Blocks :
|
|
CSR :
|
|
Relates :
|
|
Relates :
|
Summary ------- Reduce static initialization footprint of `java.lang.classfile.Attributes`. Problem ------- `java.lang.classfile.Attributes` is a central point for `AttributeMapper`s of all supported attributes. For each `Attribute` there is a relevant static final `AttributeMapper` field. Plus there is a field `PREDEFINED_ATTRIBUTES` initialized with a set of all mappers. Plus there is a static method `standardAttribute(Utf8Entry name)` providing mapping from `Utf8Entry` to a known `AttributeMapper`. These statically initialized fields and mapping represents enormous initialization footprint on the JDK critical bootstrap path. `java.lang.classfile.Attributes` is not declared final, even it is non-instantiable utility class. Solution -------- Change all static final fields into static methods with lazy individual initialization of each `AttributeMapper`. Remove `PREDEFINED_ATTRIBUTES` field from the API. Remove `standardAttribute(Utf8Entry name)` static mapping method from the API. Declare `java.lang.classfile.Attributes` as final class. Specification ------------- src/java.base/share/classes/java/lang/classfile/Attributes.java ``` - public class Attributes { - /** Attribute mapper for the {@code AnnotationDefault} attribute */ - public static final AttributeMapper<AnnotationDefaultAttribute> - ANNOTATION_DEFAULT = new AbstractAttributeMapper<>(NAME_ANNOTATION_DEFAULT) { - /** Attribute mapper for the {@code BootstrapMethods} attribute */ - public static final AttributeMapper<BootstrapMethodsAttribute> - BOOTSTRAP_METHODS = new AbstractAttributeMapper<>(NAME_BOOTSTRAP_METHODS) { - /** Attribute mapper for the {@code CharacterRangeTable} attribute */ - public static final AttributeMapper<CharacterRangeTableAttribute> - CHARACTER_RANGE_TABLE = new AbstractAttributeMapper<>(NAME_CHARACTER_RANGE_TABLE, true) { - /** Attribute mapper for the {@code Code} attribute */ - public static final AttributeMapper<CodeAttribute> - CODE = new AbstractAttributeMapper<>(NAME_CODE) { - /** Attribute mapper for the {@code CompilationID} attribute */ - public static final AttributeMapper<CompilationIDAttribute> - COMPILATION_ID = new AbstractAttributeMapper<>(NAME_COMPILATION_ID, true) { - /** Attribute mapper for the {@code ConstantValue} attribute */ - public static final AttributeMapper<ConstantValueAttribute> - CONSTANT_VALUE = new AbstractAttributeMapper<>(NAME_CONSTANT_VALUE) { - /** Attribute mapper for the {@code Deprecated} attribute */ - public static final AttributeMapper<DeprecatedAttribute> - DEPRECATED = new AbstractAttributeMapper<>(NAME_DEPRECATED, true) { - /** Attribute mapper for the {@code EnclosingMethod} attribute */ - public static final AttributeMapper<EnclosingMethodAttribute> - ENCLOSING_METHOD = new AbstractAttributeMapper<>(NAME_ENCLOSING_METHOD) { - /** Attribute mapper for the {@code Exceptions} attribute */ - public static final AttributeMapper<ExceptionsAttribute> - EXCEPTIONS = new AbstractAttributeMapper<>(NAME_EXCEPTIONS) { - /** Attribute mapper for the {@code InnerClasses} attribute */ - public static final AttributeMapper<InnerClassesAttribute> - INNER_CLASSES = new AbstractAttributeMapper<>(NAME_INNER_CLASSES) { - /** Attribute mapper for the {@code LineNumberTable} attribute */ - public static final AttributeMapper<LineNumberTableAttribute> - LINE_NUMBER_TABLE = new AbstractAttributeMapper<>(NAME_LINE_NUMBER_TABLE, true) { - /** Attribute mapper for the {@code LocalVariableTable} attribute */ - public static final AttributeMapper<LocalVariableTableAttribute> - LOCAL_VARIABLE_TABLE = new AbstractAttributeMapper<>(NAME_LOCAL_VARIABLE_TABLE, true) { - /** Attribute mapper for the {@code LocalVariableTypeTable} attribute */ - public static final AttributeMapper<LocalVariableTypeTableAttribute> - LOCAL_VARIABLE_TYPE_TABLE = new AbstractAttributeMapper<>(NAME_LOCAL_VARIABLE_TYPE_TABLE, true) { - /** Attribute mapper for the {@code MethodParameters} attribute */ - public static final AttributeMapper<MethodParametersAttribute> - METHOD_PARAMETERS = new AbstractAttributeMapper<>(NAME_METHOD_PARAMETERS) { - /** Attribute mapper for the {@code Module} attribute */ - public static final AttributeMapper<ModuleAttribute> - MODULE = new AbstractAttributeMapper<>(NAME_MODULE) { - /** Attribute mapper for the {@code ModuleHashes} attribute */ - public static final AttributeMapper<ModuleHashesAttribute> - MODULE_HASHES = new AbstractAttributeMapper<>(NAME_MODULE_HASHES) { - /** Attribute mapper for the {@code ModuleMainClass} attribute */ - public static final AttributeMapper<ModuleMainClassAttribute> - MODULE_MAIN_CLASS = new AbstractAttributeMapper<>(NAME_MODULE_MAIN_CLASS) { - /** Attribute mapper for the {@code ModulePackages} attribute */ - public static final AttributeMapper<ModulePackagesAttribute> - MODULE_PACKAGES = new AbstractAttributeMapper<>(NAME_MODULE_PACKAGES) { - /** Attribute mapper for the {@code ModuleResolution} attribute */ - public static final AttributeMapper<ModuleResolutionAttribute> - MODULE_RESOLUTION = new AbstractAttributeMapper<>(NAME_MODULE_RESOLUTION) { - /** Attribute mapper for the {@code ModuleTarget} attribute */ - public static final AttributeMapper<ModuleTargetAttribute> - MODULE_TARGET = new AbstractAttributeMapper<>(NAME_MODULE_TARGET) { - /** Attribute mapper for the {@code NestHost} attribute */ - public static final AttributeMapper<NestHostAttribute> - NEST_HOST = new AbstractAttributeMapper<>(NAME_NEST_HOST) { - /** Attribute mapper for the {@code NestMembers} attribute */ - public static final AttributeMapper<NestMembersAttribute> - NEST_MEMBERS = new AbstractAttributeMapper<>(NAME_NEST_MEMBERS) { - /** Attribute mapper for the {@code PermittedSubclasses} attribute */ - public static final AttributeMapper<PermittedSubclassesAttribute> - PERMITTED_SUBCLASSES = new AbstractAttributeMapper<>(NAME_PERMITTED_SUBCLASSES) { - /** Attribute mapper for the {@code Record} attribute */ - public static final AttributeMapper<RecordAttribute> - RECORD = new AbstractAttributeMapper<>(NAME_RECORD) { - /** Attribute mapper for the {@code RuntimeInvisibleAnnotations} attribute */ - public static final AttributeMapper<RuntimeInvisibleAnnotationsAttribute> - RUNTIME_INVISIBLE_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_INVISIBLE_ANNOTATIONS) { - /** Attribute mapper for the {@code RuntimeInvisibleParameterAnnotations} attribute */ - public static final AttributeMapper<RuntimeInvisibleParameterAnnotationsAttribute> - RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS) { - /** Attribute mapper for the {@code RuntimeInvisibleTypeAnnotations} attribute */ - public static final AttributeMapper<RuntimeInvisibleTypeAnnotationsAttribute> - RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS) { - /** Attribute mapper for the {@code RuntimeVisibleAnnotations} attribute */ - public static final AttributeMapper<RuntimeVisibleAnnotationsAttribute> - RUNTIME_VISIBLE_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_VISIBLE_ANNOTATIONS) { - /** Attribute mapper for the {@code RuntimeVisibleParameterAnnotations} attribute */ - public static final AttributeMapper<RuntimeVisibleParameterAnnotationsAttribute> - RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS) { - /** Attribute mapper for the {@code RuntimeVisibleTypeAnnotations} attribute */ - public static final AttributeMapper<RuntimeVisibleTypeAnnotationsAttribute> - RUNTIME_VISIBLE_TYPE_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS) { - /** Attribute mapper for the {@code Signature} attribute */ - public static final AttributeMapper<SignatureAttribute> - SIGNATURE = new AbstractAttributeMapper<>(NAME_SIGNATURE) { - /** Attribute mapper for the {@code SourceDebugExtension} attribute */ - public static final AttributeMapper<SourceDebugExtensionAttribute> - SOURCE_DEBUG_EXTENSION = new AbstractAttributeMapper<>(NAME_SOURCE_DEBUG_EXTENSION) { - /** Attribute mapper for the {@code SourceFile} attribute */ - public static final AttributeMapper<SourceFileAttribute> - SOURCE_FILE = new AbstractAttributeMapper<>(NAME_SOURCE_FILE) { - /** Attribute mapper for the {@code SourceID} attribute */ - public static final AttributeMapper<SourceIDAttribute> - SOURCE_ID = new AbstractAttributeMapper<>(NAME_SOURCE_ID) { - /** Attribute mapper for the {@code StackMapTable} attribute */ - public static final AttributeMapper<StackMapTableAttribute> - STACK_MAP_TABLE = new AbstractAttributeMapper<>(NAME_STACK_MAP_TABLE) { - /** Attribute mapper for the {@code Synthetic} attribute */ - public static final AttributeMapper<SyntheticAttribute> - SYNTHETIC = new AbstractAttributeMapper<>(NAME_SYNTHETIC, true) { - /** - * All standard attribute mappers. - */ - public static final Set<AttributeMapper<?>> PREDEFINED_ATTRIBUTES = Set.of( - ANNOTATION_DEFAULT, - BOOTSTRAP_METHODS, - CHARACTER_RANGE_TABLE, - CODE, - COMPILATION_ID, - CONSTANT_VALUE, - DEPRECATED, - ENCLOSING_METHOD, - EXCEPTIONS, - INNER_CLASSES, - LINE_NUMBER_TABLE, - LOCAL_VARIABLE_TABLE, - LOCAL_VARIABLE_TYPE_TABLE, - METHOD_PARAMETERS, - MODULE, - MODULE_HASHES, - MODULE_MAIN_CLASS, - MODULE_PACKAGES, - MODULE_RESOLUTION, - MODULE_TARGET, - NEST_HOST, - NEST_MEMBERS, - PERMITTED_SUBCLASSES, - RECORD, - RUNTIME_INVISIBLE_ANNOTATIONS, - RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, - RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, - RUNTIME_VISIBLE_ANNOTATIONS, - RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, - RUNTIME_VISIBLE_TYPE_ANNOTATIONS, - SIGNATURE, - SOURCE_DEBUG_EXTENSION, - SOURCE_FILE, - SOURCE_ID, - STACK_MAP_TABLE, - SYNTHETIC); /** * Attribute mappers for standard classfile attributes. + * <p> + * Unless otherwise specified, mappers returned by each method + * do not permit multiple attribute instances in a given location. + * <p> + * The most stable {@link AttributeStability#STATELESS STATELESS} mappers are: + * <ul> + * <li>{@link #deprecated()} + * <li>{@link #moduleResolution()} + * <li>{@link #sourceDebugExtension()} + * <li>{@link #synthetic()} + * </ul> + * + * The mappers with {@link AttributeStability#CP_REFS CP_REFS} stability are: + * <ul> + * <li>{@link #annotationDefault()} + * <li>{@link #bootstrapMethods()} + * <li>{@link #code()} + * <li>{@link #compilationId()} + * <li>{@link #constantValue()} + * <li>{@link #enclosingMethod()} + * <li>{@link #exceptions()} + * <li>{@link #innerClasses()} + * <li>{@link #methodParameters()} + * <li>{@link #module()} + * <li>{@link #moduleHashes()} + * <li>{@link #moduleMainClass()} + * <li>{@link #modulePackages()} + * <li>{@link #moduleTarget()} + * <li>{@link #nestHost()} + * <li>{@link #nestMembers()} + * <li>{@link #permittedSubclasses()} + * <li>{@link #record()} + * <li>{@link #runtimeInvisibleAnnotations()} + * <li>{@link #runtimeInvisibleParameterAnnotations()} + * <li>{@link #runtimeVisibleAnnotations()} + * <li>{@link #runtimeVisibleParameterAnnotations()} + * <li>{@link #signature()} + * <li>{@link #sourceFile()} + * <li>{@link #sourceId()} + * </ul> + * + * The mappers with {@link AttributeStability#LABELS LABELS} stability are: + * <ul> + * <li>{@link #characterRangeTable()} + * <li>{@link #lineNumberTable()} + * <li>{@link #localVariableTable()} + * <li>{@link #localVariableTypeTable()} + * </ul> + * + * The {@link AttributeStability#UNSTABLE UNSTABLE} mappers are: + * <ul> + * <li>{@link #runtimeInvisibleTypeAnnotations()} + * <li>{@link #runtimeVisibleTypeAnnotations()} + * </ul> * * @see AttributeMapper * * @since 22 */ @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) + public final class Attributes { + + /** + * {@return Attribute mapper for the {@code AnnotationDefault} attribute} + * @since 23 + */ + public static AttributeMapper<AnnotationDefaultAttribute> annotationDefault() { + return AnnotationDefaultMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code BootstrapMethods} attribute} + * @since 23 + */ + public static AttributeMapper<BootstrapMethodsAttribute> bootstrapMethods() { + return BootstrapMethodsMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code CharacterRangeTable} attribute} + * The mapper permits multiple instances in a given location. + * @since 23 + */ + public static AttributeMapper<CharacterRangeTableAttribute> characterRangeTable() { + return CharacterRangeTableMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code Code} attribute} + * @since 23 + */ + public static AttributeMapper<CodeAttribute> code() { + return CodeMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code CompilationID} attribute} + * @since 23 + */ + public static AttributeMapper<CompilationIDAttribute> compilationId() { + return CompilationIDMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code ConstantValue} attribute} + * @since 23 + */ + public static AttributeMapper<ConstantValueAttribute> constantValue() { + return ConstantValueMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code Deprecated} attribute} + * The mapper permits multiple instances in a given location. + * @since 23 + */ + public static AttributeMapper<DeprecatedAttribute> deprecated() { + return DeprecatedMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code EnclosingMethod} attribute} + * @since 23 + */ + public static AttributeMapper<EnclosingMethodAttribute> enclosingMethod() { + return EnclosingMethodMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code Exceptions} attribute} + * @since 23 + */ + public static AttributeMapper<ExceptionsAttribute> exceptions() { + return ExceptionsMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code InnerClasses} attribute} + * @since 23 + */ + public static AttributeMapper<InnerClassesAttribute> innerClasses() { + return InnerClassesMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code LineNumberTable} attribute} + * The mapper permits multiple instances in a given location. + * @since 23 + */ + public static AttributeMapper<LineNumberTableAttribute> lineNumberTable() { + return LineNumberTableMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code LocalVariableTable} attribute} + * The mapper permits multiple instances in a given location. + * @since 23 + */ + public static AttributeMapper<LocalVariableTableAttribute> localVariableTable() { + return LocalVariableTableMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code LocalVariableTypeTable} attribute} + * The mapper permits multiple instances in a given location. + * @since 23 + */ + public static AttributeMapper<LocalVariableTypeTableAttribute> localVariableTypeTable() { + return LocalVariableTypeTableMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code MethodParameters} attribute} + * @since 23 + */ + public static AttributeMapper<MethodParametersAttribute> methodParameters() { + return MethodParametersMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code Module} attribute} + * @since 23 + */ + public static AttributeMapper<ModuleAttribute> module() { + return ModuleMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code ModuleHashes} attribute} + * @since 23 + */ + public static AttributeMapper<ModuleHashesAttribute> moduleHashes() { + return ModuleHashesMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code ModuleMainClass} attribute} + * @since 23 + */ + public static AttributeMapper<ModuleMainClassAttribute> moduleMainClass() { + return ModuleMainClassMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code ModulePackages} attribute} + * @since 23 + */ + public static AttributeMapper<ModulePackagesAttribute> modulePackages() { + return ModulePackagesMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code ModuleResolution} attribute} + * @since 23 + */ + public static AttributeMapper<ModuleResolutionAttribute> moduleResolution() { + return ModuleResolutionMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code ModuleTarget} attribute} + * @since 23 + */ + public static AttributeMapper<ModuleTargetAttribute> moduleTarget() { + return ModuleTargetMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code NestHost} attribute} + * @since 23 + */ + public static AttributeMapper<NestHostAttribute> nestHost() { + return NestHostMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code NestMembers} attribute} + * @since 23 + */ + public static AttributeMapper<NestMembersAttribute> nestMembers() { + return NestMembersMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code PermittedSubclasses} attribute} + * @since 23 + */ + public static AttributeMapper<PermittedSubclassesAttribute> permittedSubclasses() { + return PermittedSubclassesMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code Record} attribute} + * @since 23 + */ + public static AttributeMapper<RecordAttribute> record() { + return RecordMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code RuntimeInvisibleAnnotations} attribute} + * @since 23 + */ + public static AttributeMapper<RuntimeInvisibleAnnotationsAttribute> runtimeInvisibleAnnotations() { + return RuntimeInvisibleAnnotationsMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code RuntimeInvisibleParameterAnnotations} attribute} + * @since 23 + */ + public static AttributeMapper<RuntimeInvisibleParameterAnnotationsAttribute> runtimeInvisibleParameterAnnotations() { + return RuntimeInvisibleParameterAnnotationsMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code RuntimeInvisibleTypeAnnotations} attribute} + * @since 23 + */ + public static AttributeMapper<RuntimeInvisibleTypeAnnotationsAttribute> runtimeInvisibleTypeAnnotations() { + return RuntimeInvisibleTypeAnnotationsMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code RuntimeVisibleAnnotations} attribute} + * @since 23 + */ + public static AttributeMapper<RuntimeVisibleAnnotationsAttribute> runtimeVisibleAnnotations() { + return RuntimeVisibleAnnotationsMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code RuntimeVisibleParameterAnnotations} attribute} + * @since 23 + */ + public static AttributeMapper<RuntimeVisibleParameterAnnotationsAttribute> runtimeVisibleParameterAnnotations() { + return RuntimeVisibleParameterAnnotationsMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code RuntimeVisibleTypeAnnotations} attribute} + * @since 23 + */ + public static AttributeMapper<RuntimeVisibleTypeAnnotationsAttribute> runtimeVisibleTypeAnnotations() { + return RuntimeVisibleTypeAnnotationsMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code Signature} attribute} + * @since 23 + */ + public static AttributeMapper<SignatureAttribute> signature() { + return SignatureMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code SourceDebugExtension} attribute} + * @since 23 + */ + public static AttributeMapper<SourceDebugExtensionAttribute> sourceDebugExtension() { + return SourceDebugExtensionMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code SourceFile} attribute} + * @since 23 + */ + public static AttributeMapper<SourceFileAttribute> sourceFile() { + return SourceFileMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code SourceID} attribute} + * @since 23 + */ + public static AttributeMapper<SourceIDAttribute> sourceId() { + return SourceIDMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code StackMapTable} attribute} + * @since 23 + */ + public static AttributeMapper<StackMapTableAttribute> stackMapTable() { + return StackMapTableMapper.INSTANCE; + } + + /** + * {@return Attribute mapper for the {@code Synthetic} attribute} + * The mapper permits multiple instances in a given location. + * @since 23 + */ + public static AttributeMapper<SyntheticAttribute> synthetic() { + return SyntheticMapper.INSTANCE; + } ```
|