8004823: Add VM support for type annotation reflection
Reviewed-by: dholmes, coleenp
This commit is contained in:
parent
9c761152db
commit
6ed6cb5375
@ -126,8 +126,9 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetClassModifiers;
|
JVM_GetClassModifiers;
|
||||||
JVM_GetClassName;
|
JVM_GetClassName;
|
||||||
JVM_GetClassNameUTF;
|
JVM_GetClassNameUTF;
|
||||||
JVM_GetClassSignature;
|
JVM_GetClassSignature;
|
||||||
JVM_GetClassSigners;
|
JVM_GetClassSigners;
|
||||||
|
JVM_GetClassTypeAnnotations;
|
||||||
JVM_GetComponentType;
|
JVM_GetComponentType;
|
||||||
JVM_GetDeclaredClasses;
|
JVM_GetDeclaredClasses;
|
||||||
JVM_GetDeclaringClass;
|
JVM_GetDeclaringClass;
|
||||||
|
@ -128,6 +128,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetClassNameUTF;
|
JVM_GetClassNameUTF;
|
||||||
JVM_GetClassSignature;
|
JVM_GetClassSignature;
|
||||||
JVM_GetClassSigners;
|
JVM_GetClassSigners;
|
||||||
|
JVM_GetClassTypeAnnotations;
|
||||||
JVM_GetComponentType;
|
JVM_GetComponentType;
|
||||||
JVM_GetDeclaredClasses;
|
JVM_GetDeclaredClasses;
|
||||||
JVM_GetDeclaringClass;
|
JVM_GetDeclaringClass;
|
||||||
|
@ -124,6 +124,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetClassNameUTF;
|
JVM_GetClassNameUTF;
|
||||||
JVM_GetClassSignature;
|
JVM_GetClassSignature;
|
||||||
JVM_GetClassSigners;
|
JVM_GetClassSigners;
|
||||||
|
JVM_GetClassTypeAnnotations;
|
||||||
JVM_GetComponentType;
|
JVM_GetComponentType;
|
||||||
JVM_GetDeclaredClasses;
|
JVM_GetDeclaredClasses;
|
||||||
JVM_GetDeclaringClass;
|
JVM_GetDeclaringClass;
|
||||||
|
@ -124,6 +124,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetClassNameUTF;
|
JVM_GetClassNameUTF;
|
||||||
JVM_GetClassSignature;
|
JVM_GetClassSignature;
|
||||||
JVM_GetClassSigners;
|
JVM_GetClassSigners;
|
||||||
|
JVM_GetClassTypeAnnotations;
|
||||||
JVM_GetComponentType;
|
JVM_GetComponentType;
|
||||||
JVM_GetDeclaredClasses;
|
JVM_GetDeclaredClasses;
|
||||||
JVM_GetDeclaringClass;
|
JVM_GetDeclaringClass;
|
||||||
|
@ -125,6 +125,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetClassSignature;
|
JVM_GetClassSignature;
|
||||||
JVM_GetClassSigners;
|
JVM_GetClassSigners;
|
||||||
JVM_GetComponentType;
|
JVM_GetComponentType;
|
||||||
|
JVM_GetClassTypeAnnotations;
|
||||||
JVM_GetDeclaredClasses;
|
JVM_GetDeclaredClasses;
|
||||||
JVM_GetDeclaringClass;
|
JVM_GetDeclaringClass;
|
||||||
JVM_GetEnclosingMethodInfo;
|
JVM_GetEnclosingMethodInfo;
|
||||||
|
@ -906,6 +906,7 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data,
|
|||||||
bool* is_synthetic_addr,
|
bool* is_synthetic_addr,
|
||||||
u2* generic_signature_index_addr,
|
u2* generic_signature_index_addr,
|
||||||
AnnotationArray** field_annotations,
|
AnnotationArray** field_annotations,
|
||||||
|
AnnotationArray** field_type_annotations,
|
||||||
ClassFileParser::FieldAnnotationCollector* parsed_annotations,
|
ClassFileParser::FieldAnnotationCollector* parsed_annotations,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
ClassFileStream* cfs = stream();
|
ClassFileStream* cfs = stream();
|
||||||
@ -917,6 +918,10 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data,
|
|||||||
int runtime_visible_annotations_length = 0;
|
int runtime_visible_annotations_length = 0;
|
||||||
u1* runtime_invisible_annotations = NULL;
|
u1* runtime_invisible_annotations = NULL;
|
||||||
int runtime_invisible_annotations_length = 0;
|
int runtime_invisible_annotations_length = 0;
|
||||||
|
u1* runtime_visible_type_annotations = NULL;
|
||||||
|
int runtime_visible_type_annotations_length = 0;
|
||||||
|
u1* runtime_invisible_type_annotations = NULL;
|
||||||
|
int runtime_invisible_type_annotations_length = 0;
|
||||||
while (attributes_count--) {
|
while (attributes_count--) {
|
||||||
cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
|
cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
|
||||||
u2 attribute_name_index = cfs->get_u2_fast();
|
u2 attribute_name_index = cfs->get_u2_fast();
|
||||||
@ -971,6 +976,16 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data,
|
|||||||
runtime_invisible_annotations = cfs->get_u1_buffer();
|
runtime_invisible_annotations = cfs->get_u1_buffer();
|
||||||
assert(runtime_invisible_annotations != NULL, "null invisible annotations");
|
assert(runtime_invisible_annotations != NULL, "null invisible annotations");
|
||||||
cfs->skip_u1(runtime_invisible_annotations_length, CHECK);
|
cfs->skip_u1(runtime_invisible_annotations_length, CHECK);
|
||||||
|
} else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
|
||||||
|
runtime_visible_type_annotations_length = attribute_length;
|
||||||
|
runtime_visible_type_annotations = cfs->get_u1_buffer();
|
||||||
|
assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
|
||||||
|
cfs->skip_u1(runtime_visible_type_annotations_length, CHECK);
|
||||||
|
} else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
|
||||||
|
runtime_invisible_type_annotations_length = attribute_length;
|
||||||
|
runtime_invisible_type_annotations = cfs->get_u1_buffer();
|
||||||
|
assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
|
||||||
|
cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK);
|
||||||
} else {
|
} else {
|
||||||
cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes
|
cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes
|
||||||
}
|
}
|
||||||
@ -988,6 +1003,12 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data,
|
|||||||
runtime_invisible_annotations,
|
runtime_invisible_annotations,
|
||||||
runtime_invisible_annotations_length,
|
runtime_invisible_annotations_length,
|
||||||
CHECK);
|
CHECK);
|
||||||
|
*field_type_annotations = assemble_annotations(loader_data,
|
||||||
|
runtime_visible_type_annotations,
|
||||||
|
runtime_visible_type_annotations_length,
|
||||||
|
runtime_invisible_type_annotations,
|
||||||
|
runtime_invisible_type_annotations_length,
|
||||||
|
CHECK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,6 +1105,7 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
|
|||||||
bool is_interface,
|
bool is_interface,
|
||||||
FieldAllocationCount *fac,
|
FieldAllocationCount *fac,
|
||||||
Array<AnnotationArray*>** fields_annotations,
|
Array<AnnotationArray*>** fields_annotations,
|
||||||
|
Array<AnnotationArray*>** fields_type_annotations,
|
||||||
u2* java_fields_count_ptr, TRAPS) {
|
u2* java_fields_count_ptr, TRAPS) {
|
||||||
ClassFileStream* cfs = stream();
|
ClassFileStream* cfs = stream();
|
||||||
cfs->guarantee_more(2, CHECK_NULL); // length
|
cfs->guarantee_more(2, CHECK_NULL); // length
|
||||||
@ -1119,6 +1141,7 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
|
|||||||
THREAD, u2, total_fields * (FieldInfo::field_slots + 1));
|
THREAD, u2, total_fields * (FieldInfo::field_slots + 1));
|
||||||
|
|
||||||
AnnotationArray* field_annotations = NULL;
|
AnnotationArray* field_annotations = NULL;
|
||||||
|
AnnotationArray* field_type_annotations = NULL;
|
||||||
// The generic signature slots start after all other fields' data.
|
// The generic signature slots start after all other fields' data.
|
||||||
int generic_signature_slot = total_fields * FieldInfo::field_slots;
|
int generic_signature_slot = total_fields * FieldInfo::field_slots;
|
||||||
int num_generic_signature = 0;
|
int num_generic_signature = 0;
|
||||||
@ -1160,7 +1183,7 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
|
|||||||
cp, attributes_count, is_static, signature_index,
|
cp, attributes_count, is_static, signature_index,
|
||||||
&constantvalue_index, &is_synthetic,
|
&constantvalue_index, &is_synthetic,
|
||||||
&generic_signature_index, &field_annotations,
|
&generic_signature_index, &field_annotations,
|
||||||
&parsed_annotations,
|
&field_type_annotations, &parsed_annotations,
|
||||||
CHECK_NULL);
|
CHECK_NULL);
|
||||||
if (field_annotations != NULL) {
|
if (field_annotations != NULL) {
|
||||||
if (*fields_annotations == NULL) {
|
if (*fields_annotations == NULL) {
|
||||||
@ -1170,6 +1193,14 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
|
|||||||
}
|
}
|
||||||
(*fields_annotations)->at_put(n, field_annotations);
|
(*fields_annotations)->at_put(n, field_annotations);
|
||||||
}
|
}
|
||||||
|
if (field_type_annotations != NULL) {
|
||||||
|
if (*fields_type_annotations == NULL) {
|
||||||
|
*fields_type_annotations = MetadataFactory::new_array<AnnotationArray*>(
|
||||||
|
loader_data, length, NULL,
|
||||||
|
CHECK_NULL);
|
||||||
|
}
|
||||||
|
(*fields_type_annotations)->at_put(n, field_type_annotations);
|
||||||
|
}
|
||||||
if (is_synthetic) {
|
if (is_synthetic) {
|
||||||
access_flags.set_is_synthetic();
|
access_flags.set_is_synthetic();
|
||||||
}
|
}
|
||||||
@ -1831,6 +1862,7 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
|
|||||||
AnnotationArray** method_annotations,
|
AnnotationArray** method_annotations,
|
||||||
AnnotationArray** method_parameter_annotations,
|
AnnotationArray** method_parameter_annotations,
|
||||||
AnnotationArray** method_default_annotations,
|
AnnotationArray** method_default_annotations,
|
||||||
|
AnnotationArray** method_type_annotations,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
ClassFileStream* cfs = stream();
|
ClassFileStream* cfs = stream();
|
||||||
methodHandle nullHandle;
|
methodHandle nullHandle;
|
||||||
@ -1918,6 +1950,10 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
|
|||||||
int runtime_visible_parameter_annotations_length = 0;
|
int runtime_visible_parameter_annotations_length = 0;
|
||||||
u1* runtime_invisible_parameter_annotations = NULL;
|
u1* runtime_invisible_parameter_annotations = NULL;
|
||||||
int runtime_invisible_parameter_annotations_length = 0;
|
int runtime_invisible_parameter_annotations_length = 0;
|
||||||
|
u1* runtime_visible_type_annotations = NULL;
|
||||||
|
int runtime_visible_type_annotations_length = 0;
|
||||||
|
u1* runtime_invisible_type_annotations = NULL;
|
||||||
|
int runtime_invisible_type_annotations_length = 0;
|
||||||
u1* annotation_default = NULL;
|
u1* annotation_default = NULL;
|
||||||
int annotation_default_length = 0;
|
int annotation_default_length = 0;
|
||||||
|
|
||||||
@ -2159,6 +2195,17 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
|
|||||||
annotation_default = cfs->get_u1_buffer();
|
annotation_default = cfs->get_u1_buffer();
|
||||||
assert(annotation_default != NULL, "null annotation default");
|
assert(annotation_default != NULL, "null annotation default");
|
||||||
cfs->skip_u1(annotation_default_length, CHECK_(nullHandle));
|
cfs->skip_u1(annotation_default_length, CHECK_(nullHandle));
|
||||||
|
} else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
|
||||||
|
runtime_visible_type_annotations_length = method_attribute_length;
|
||||||
|
runtime_visible_type_annotations = cfs->get_u1_buffer();
|
||||||
|
assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
|
||||||
|
// No need for the VM to parse Type annotations
|
||||||
|
cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle));
|
||||||
|
} else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
|
||||||
|
runtime_invisible_type_annotations_length = method_attribute_length;
|
||||||
|
runtime_invisible_type_annotations = cfs->get_u1_buffer();
|
||||||
|
assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
|
||||||
|
cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle));
|
||||||
} else {
|
} else {
|
||||||
// Skip unknown attributes
|
// Skip unknown attributes
|
||||||
cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
|
cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
|
||||||
@ -2333,6 +2380,12 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
|
|||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
|
*method_type_annotations = assemble_annotations(loader_data,
|
||||||
|
runtime_visible_type_annotations,
|
||||||
|
runtime_visible_type_annotations_length,
|
||||||
|
runtime_invisible_type_annotations,
|
||||||
|
runtime_invisible_type_annotations_length,
|
||||||
|
CHECK_(nullHandle));
|
||||||
|
|
||||||
if (name == vmSymbols::finalize_method_name() &&
|
if (name == vmSymbols::finalize_method_name() &&
|
||||||
signature == vmSymbols::void_method_signature()) {
|
signature == vmSymbols::void_method_signature()) {
|
||||||
@ -2364,12 +2417,14 @@ Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
|
|||||||
Array<AnnotationArray*>** methods_annotations,
|
Array<AnnotationArray*>** methods_annotations,
|
||||||
Array<AnnotationArray*>** methods_parameter_annotations,
|
Array<AnnotationArray*>** methods_parameter_annotations,
|
||||||
Array<AnnotationArray*>** methods_default_annotations,
|
Array<AnnotationArray*>** methods_default_annotations,
|
||||||
|
Array<AnnotationArray*>** methods_type_annotations,
|
||||||
bool* has_default_methods,
|
bool* has_default_methods,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
ClassFileStream* cfs = stream();
|
ClassFileStream* cfs = stream();
|
||||||
AnnotationArray* method_annotations = NULL;
|
AnnotationArray* method_annotations = NULL;
|
||||||
AnnotationArray* method_parameter_annotations = NULL;
|
AnnotationArray* method_parameter_annotations = NULL;
|
||||||
AnnotationArray* method_default_annotations = NULL;
|
AnnotationArray* method_default_annotations = NULL;
|
||||||
|
AnnotationArray* method_type_annotations = NULL;
|
||||||
cfs->guarantee_more(2, CHECK_NULL); // length
|
cfs->guarantee_more(2, CHECK_NULL); // length
|
||||||
u2 length = cfs->get_u2_fast();
|
u2 length = cfs->get_u2_fast();
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
@ -2386,6 +2441,7 @@ Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
|
|||||||
&method_annotations,
|
&method_annotations,
|
||||||
&method_parameter_annotations,
|
&method_parameter_annotations,
|
||||||
&method_default_annotations,
|
&method_default_annotations,
|
||||||
|
&method_type_annotations,
|
||||||
CHECK_NULL);
|
CHECK_NULL);
|
||||||
|
|
||||||
if (method->is_final()) {
|
if (method->is_final()) {
|
||||||
@ -2411,7 +2467,13 @@ Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
|
|||||||
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
|
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
|
||||||
}
|
}
|
||||||
(*methods_default_annotations)->at_put(index, method_default_annotations);
|
(*methods_default_annotations)->at_put(index, method_default_annotations);
|
||||||
|
if (*methods_type_annotations == NULL) {
|
||||||
|
*methods_type_annotations =
|
||||||
|
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
|
||||||
|
}
|
||||||
|
(*methods_type_annotations)->at_put(index, method_type_annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_need_verify && length > 1) {
|
if (_need_verify && length > 1) {
|
||||||
// Check duplicated methods
|
// Check duplicated methods
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
@ -2445,6 +2507,7 @@ Array<int>* ClassFileParser::sort_methods(ClassLoaderData* loader_data,
|
|||||||
Array<AnnotationArray*>* methods_annotations,
|
Array<AnnotationArray*>* methods_annotations,
|
||||||
Array<AnnotationArray*>* methods_parameter_annotations,
|
Array<AnnotationArray*>* methods_parameter_annotations,
|
||||||
Array<AnnotationArray*>* methods_default_annotations,
|
Array<AnnotationArray*>* methods_default_annotations,
|
||||||
|
Array<AnnotationArray*>* methods_type_annotations,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
int length = methods->length();
|
int length = methods->length();
|
||||||
// If JVMTI original method ordering or sharing is enabled we have to
|
// If JVMTI original method ordering or sharing is enabled we have to
|
||||||
@ -2463,7 +2526,8 @@ Array<int>* ClassFileParser::sort_methods(ClassLoaderData* loader_data,
|
|||||||
// Note that the ordering is not alphabetical, see Symbol::fast_compare
|
// Note that the ordering is not alphabetical, see Symbol::fast_compare
|
||||||
Method::sort_methods(methods, methods_annotations,
|
Method::sort_methods(methods, methods_annotations,
|
||||||
methods_parameter_annotations,
|
methods_parameter_annotations,
|
||||||
methods_default_annotations);
|
methods_default_annotations,
|
||||||
|
methods_type_annotations);
|
||||||
|
|
||||||
// If JVMTI original method ordering or sharing is enabled construct int
|
// If JVMTI original method ordering or sharing is enabled construct int
|
||||||
// array remembering the original ordering
|
// array remembering the original ordering
|
||||||
@ -2728,6 +2792,10 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data,
|
|||||||
int runtime_visible_annotations_length = 0;
|
int runtime_visible_annotations_length = 0;
|
||||||
u1* runtime_invisible_annotations = NULL;
|
u1* runtime_invisible_annotations = NULL;
|
||||||
int runtime_invisible_annotations_length = 0;
|
int runtime_invisible_annotations_length = 0;
|
||||||
|
u1* runtime_visible_type_annotations = NULL;
|
||||||
|
int runtime_visible_type_annotations_length = 0;
|
||||||
|
u1* runtime_invisible_type_annotations = NULL;
|
||||||
|
int runtime_invisible_type_annotations_length = 0;
|
||||||
u1* inner_classes_attribute_start = NULL;
|
u1* inner_classes_attribute_start = NULL;
|
||||||
u4 inner_classes_attribute_length = 0;
|
u4 inner_classes_attribute_length = 0;
|
||||||
u2 enclosing_method_class_index = 0;
|
u2 enclosing_method_class_index = 0;
|
||||||
@ -2834,6 +2902,17 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data,
|
|||||||
classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
|
classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
|
||||||
parsed_bootstrap_methods_attribute = true;
|
parsed_bootstrap_methods_attribute = true;
|
||||||
parse_classfile_bootstrap_methods_attribute(loader_data, cp, attribute_length, CHECK);
|
parse_classfile_bootstrap_methods_attribute(loader_data, cp, attribute_length, CHECK);
|
||||||
|
} else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) {
|
||||||
|
runtime_visible_type_annotations_length = attribute_length;
|
||||||
|
runtime_visible_type_annotations = cfs->get_u1_buffer();
|
||||||
|
assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
|
||||||
|
// No need for the VM to parse Type annotations
|
||||||
|
cfs->skip_u1(runtime_visible_type_annotations_length, CHECK);
|
||||||
|
} else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) {
|
||||||
|
runtime_invisible_type_annotations_length = attribute_length;
|
||||||
|
runtime_invisible_type_annotations = cfs->get_u1_buffer();
|
||||||
|
assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
|
||||||
|
cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK);
|
||||||
} else {
|
} else {
|
||||||
// Unknown attribute
|
// Unknown attribute
|
||||||
cfs->skip_u1(attribute_length, CHECK);
|
cfs->skip_u1(attribute_length, CHECK);
|
||||||
@ -2850,6 +2929,13 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data,
|
|||||||
runtime_invisible_annotations_length,
|
runtime_invisible_annotations_length,
|
||||||
CHECK);
|
CHECK);
|
||||||
set_class_annotations(annotations);
|
set_class_annotations(annotations);
|
||||||
|
AnnotationArray* type_annotations = assemble_annotations(loader_data,
|
||||||
|
runtime_visible_type_annotations,
|
||||||
|
runtime_visible_type_annotations_length,
|
||||||
|
runtime_invisible_type_annotations,
|
||||||
|
runtime_invisible_type_annotations_length,
|
||||||
|
CHECK);
|
||||||
|
set_class_type_annotations(type_annotations);
|
||||||
|
|
||||||
if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
|
if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
|
||||||
u2 num_of_classes = parse_classfile_inner_classes_attribute(
|
u2 num_of_classes = parse_classfile_inner_classes_attribute(
|
||||||
@ -3190,7 +3276,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
// Fields (offsets are filled in later)
|
// Fields (offsets are filled in later)
|
||||||
FieldAllocationCount fac;
|
FieldAllocationCount fac;
|
||||||
Array<AnnotationArray*>* fields_annotations = NULL;
|
Array<AnnotationArray*>* fields_annotations = NULL;
|
||||||
|
Array<AnnotationArray*>* fields_type_annotations = NULL;
|
||||||
Array<u2>* fields = parse_fields(loader_data, class_name, cp, access_flags.is_interface(), &fac, &fields_annotations,
|
Array<u2>* fields = parse_fields(loader_data, class_name, cp, access_flags.is_interface(), &fac, &fields_annotations,
|
||||||
|
&fields_type_annotations,
|
||||||
&java_fields_count,
|
&java_fields_count,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
// Methods
|
// Methods
|
||||||
@ -3202,6 +3290,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
Array<AnnotationArray*>* methods_annotations = NULL;
|
Array<AnnotationArray*>* methods_annotations = NULL;
|
||||||
Array<AnnotationArray*>* methods_parameter_annotations = NULL;
|
Array<AnnotationArray*>* methods_parameter_annotations = NULL;
|
||||||
Array<AnnotationArray*>* methods_default_annotations = NULL;
|
Array<AnnotationArray*>* methods_default_annotations = NULL;
|
||||||
|
Array<AnnotationArray*>* methods_type_annotations = NULL;
|
||||||
Array<Method*>* methods = parse_methods(loader_data,
|
Array<Method*>* methods = parse_methods(loader_data,
|
||||||
cp, access_flags.is_interface(),
|
cp, access_flags.is_interface(),
|
||||||
&promoted_flags,
|
&promoted_flags,
|
||||||
@ -3209,6 +3298,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
&methods_annotations,
|
&methods_annotations,
|
||||||
&methods_parameter_annotations,
|
&methods_parameter_annotations,
|
||||||
&methods_default_annotations,
|
&methods_default_annotations,
|
||||||
|
&methods_type_annotations,
|
||||||
&has_default_methods,
|
&has_default_methods,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
|
|
||||||
@ -3270,6 +3360,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
methods_annotations,
|
methods_annotations,
|
||||||
methods_parameter_annotations,
|
methods_parameter_annotations,
|
||||||
methods_default_annotations,
|
methods_default_annotations,
|
||||||
|
methods_type_annotations,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
|
|
||||||
// promote flags from parse_methods() to the klass' flags
|
// promote flags from parse_methods() to the klass' flags
|
||||||
@ -3687,11 +3778,13 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
if (is_anonymous()) // I am well known to myself
|
if (is_anonymous()) // I am well known to myself
|
||||||
cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
|
cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
|
||||||
|
|
||||||
|
// Allocate an annotation type if needed.
|
||||||
if (fields_annotations != NULL ||
|
if (fields_annotations != NULL ||
|
||||||
methods_annotations != NULL ||
|
methods_annotations != NULL ||
|
||||||
methods_parameter_annotations != NULL ||
|
methods_parameter_annotations != NULL ||
|
||||||
methods_default_annotations != NULL) {
|
methods_default_annotations != NULL ||
|
||||||
// Allocate an annotation type if needed.
|
fields_type_annotations != NULL ||
|
||||||
|
methods_type_annotations != NULL) {
|
||||||
Annotations* anno = Annotations::allocate(loader_data,
|
Annotations* anno = Annotations::allocate(loader_data,
|
||||||
fields_annotations, methods_annotations,
|
fields_annotations, methods_annotations,
|
||||||
methods_parameter_annotations,
|
methods_parameter_annotations,
|
||||||
@ -3701,6 +3794,16 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
this_klass->set_annotations(NULL);
|
this_klass->set_annotations(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fields_type_annotations != NULL ||
|
||||||
|
methods_type_annotations != NULL) {
|
||||||
|
assert(this_klass->annotations() != NULL, "annotations should have been allocated");
|
||||||
|
Annotations* anno = Annotations::allocate(loader_data,
|
||||||
|
fields_type_annotations,
|
||||||
|
methods_type_annotations,
|
||||||
|
NULL,
|
||||||
|
NULL, CHECK_(nullHandle));
|
||||||
|
this_klass->annotations()->set_type_annotations(anno);
|
||||||
|
}
|
||||||
|
|
||||||
this_klass->set_minor_version(minor_version);
|
this_klass->set_minor_version(minor_version);
|
||||||
this_klass->set_major_version(major_version);
|
this_klass->set_major_version(major_version);
|
||||||
@ -3725,6 +3828,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
// Fill in field values obtained by parse_classfile_attributes
|
// Fill in field values obtained by parse_classfile_attributes
|
||||||
if (parsed_annotations.has_any_annotations())
|
if (parsed_annotations.has_any_annotations())
|
||||||
parsed_annotations.apply_to(this_klass);
|
parsed_annotations.apply_to(this_klass);
|
||||||
|
|
||||||
// Create annotations
|
// Create annotations
|
||||||
if (_annotations != NULL && this_klass->annotations() == NULL) {
|
if (_annotations != NULL && this_klass->annotations() == NULL) {
|
||||||
Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
|
Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
|
||||||
@ -3732,6 +3836,19 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
}
|
}
|
||||||
apply_parsed_class_attributes(this_klass);
|
apply_parsed_class_attributes(this_klass);
|
||||||
|
|
||||||
|
// Create type annotations
|
||||||
|
if (_type_annotations != NULL) {
|
||||||
|
if (this_klass->annotations() == NULL) {
|
||||||
|
Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
|
||||||
|
this_klass->set_annotations(anno);
|
||||||
|
}
|
||||||
|
if (this_klass->annotations()->type_annotations() == NULL) {
|
||||||
|
Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
|
||||||
|
this_klass->annotations()->set_type_annotations(anno);
|
||||||
|
}
|
||||||
|
this_klass->annotations()->type_annotations()->set_class_annotations(_type_annotations);
|
||||||
|
}
|
||||||
|
|
||||||
// Miranda methods
|
// Miranda methods
|
||||||
if ((num_miranda_methods > 0) ||
|
if ((num_miranda_methods > 0) ||
|
||||||
// if this class introduced new miranda methods or
|
// if this class introduced new miranda methods or
|
||||||
|
@ -64,6 +64,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
int _sde_length;
|
int _sde_length;
|
||||||
Array<u2>* _inner_classes;
|
Array<u2>* _inner_classes;
|
||||||
AnnotationArray* _annotations;
|
AnnotationArray* _annotations;
|
||||||
|
AnnotationArray* _type_annotations;
|
||||||
|
|
||||||
void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
|
void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
|
||||||
void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
|
void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
|
||||||
@ -71,12 +72,14 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
|
void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
|
||||||
void set_class_inner_classes(Array<u2>* x) { _inner_classes = x; }
|
void set_class_inner_classes(Array<u2>* x) { _inner_classes = x; }
|
||||||
void set_class_annotations(AnnotationArray* x) { _annotations = x; }
|
void set_class_annotations(AnnotationArray* x) { _annotations = x; }
|
||||||
|
void set_class_type_annotations(AnnotationArray* x) { _type_annotations = x; }
|
||||||
void init_parsed_class_attributes() {
|
void init_parsed_class_attributes() {
|
||||||
_synthetic_flag = false;
|
_synthetic_flag = false;
|
||||||
_sourcefile = NULL;
|
_sourcefile = NULL;
|
||||||
_generic_signature = NULL;
|
_generic_signature = NULL;
|
||||||
_sde_buffer = NULL;
|
_sde_buffer = NULL;
|
||||||
_sde_length = 0;
|
_sde_length = 0;
|
||||||
|
_annotations = _type_annotations = NULL;
|
||||||
// initialize the other flags too:
|
// initialize the other flags too:
|
||||||
_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
|
_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
|
||||||
_max_bootstrap_specifier_index = -1;
|
_max_bootstrap_specifier_index = -1;
|
||||||
@ -163,6 +166,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
bool* is_synthetic_addr,
|
bool* is_synthetic_addr,
|
||||||
u2* generic_signature_index_addr,
|
u2* generic_signature_index_addr,
|
||||||
AnnotationArray** field_annotations,
|
AnnotationArray** field_annotations,
|
||||||
|
AnnotationArray** field_type_annotations,
|
||||||
FieldAnnotationCollector* parsed_annotations,
|
FieldAnnotationCollector* parsed_annotations,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
Array<u2>* parse_fields(ClassLoaderData* loader_data,
|
Array<u2>* parse_fields(ClassLoaderData* loader_data,
|
||||||
@ -170,6 +174,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
constantPoolHandle cp, bool is_interface,
|
constantPoolHandle cp, bool is_interface,
|
||||||
FieldAllocationCount *fac,
|
FieldAllocationCount *fac,
|
||||||
Array<AnnotationArray*>** fields_annotations,
|
Array<AnnotationArray*>** fields_annotations,
|
||||||
|
Array<AnnotationArray*>** fields_type_annotations,
|
||||||
u2* java_fields_count_ptr, TRAPS);
|
u2* java_fields_count_ptr, TRAPS);
|
||||||
|
|
||||||
// Method parsing
|
// Method parsing
|
||||||
@ -180,6 +185,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
AnnotationArray** method_annotations,
|
AnnotationArray** method_annotations,
|
||||||
AnnotationArray** method_parameter_annotations,
|
AnnotationArray** method_parameter_annotations,
|
||||||
AnnotationArray** method_default_annotations,
|
AnnotationArray** method_default_annotations,
|
||||||
|
AnnotationArray** method_type_annotations,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
Array<Method*>* parse_methods(ClassLoaderData* loader_data,
|
Array<Method*>* parse_methods(ClassLoaderData* loader_data,
|
||||||
constantPoolHandle cp,
|
constantPoolHandle cp,
|
||||||
@ -189,6 +195,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
Array<AnnotationArray*>** methods_annotations,
|
Array<AnnotationArray*>** methods_annotations,
|
||||||
Array<AnnotationArray*>** methods_parameter_annotations,
|
Array<AnnotationArray*>** methods_parameter_annotations,
|
||||||
Array<AnnotationArray*>** methods_default_annotations,
|
Array<AnnotationArray*>** methods_default_annotations,
|
||||||
|
Array<AnnotationArray*>** methods_type_annotations,
|
||||||
bool* has_default_method,
|
bool* has_default_method,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
Array<int>* sort_methods(ClassLoaderData* loader_data,
|
Array<int>* sort_methods(ClassLoaderData* loader_data,
|
||||||
@ -196,6 +203,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
Array<AnnotationArray*>* methods_annotations,
|
Array<AnnotationArray*>* methods_annotations,
|
||||||
Array<AnnotationArray*>* methods_parameter_annotations,
|
Array<AnnotationArray*>* methods_parameter_annotations,
|
||||||
Array<AnnotationArray*>* methods_default_annotations,
|
Array<AnnotationArray*>* methods_default_annotations,
|
||||||
|
Array<AnnotationArray*>* methods_type_annotations,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
u2* parse_exception_table(ClassLoaderData* loader_data,
|
u2* parse_exception_table(ClassLoaderData* loader_data,
|
||||||
u4 code_length, u4 exception_table_length,
|
u4 code_length, u4 exception_table_length,
|
||||||
|
@ -1813,10 +1813,12 @@ void java_lang_reflect_Method::compute_offsets() {
|
|||||||
annotations_offset = -1;
|
annotations_offset = -1;
|
||||||
parameter_annotations_offset = -1;
|
parameter_annotations_offset = -1;
|
||||||
annotation_default_offset = -1;
|
annotation_default_offset = -1;
|
||||||
|
type_annotations_offset = -1;
|
||||||
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
|
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
|
||||||
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
|
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
|
||||||
compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
|
compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
|
||||||
compute_optional_offset(annotation_default_offset, k, vmSymbols::annotation_default_name(), vmSymbols::byte_array_signature());
|
compute_optional_offset(annotation_default_offset, k, vmSymbols::annotation_default_name(), vmSymbols::byte_array_signature());
|
||||||
|
compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle java_lang_reflect_Method::create(TRAPS) {
|
Handle java_lang_reflect_Method::create(TRAPS) {
|
||||||
@ -1962,6 +1964,22 @@ void java_lang_reflect_Method::set_annotation_default(oop method, oop value) {
|
|||||||
method->obj_field_put(annotation_default_offset, value);
|
method->obj_field_put(annotation_default_offset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool java_lang_reflect_Method::has_type_annotations_field() {
|
||||||
|
return (type_annotations_offset >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
oop java_lang_reflect_Method::type_annotations(oop method) {
|
||||||
|
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
|
||||||
|
assert(has_type_annotations_field(), "type_annotations field must be present");
|
||||||
|
return method->obj_field(type_annotations_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void java_lang_reflect_Method::set_type_annotations(oop method, oop value) {
|
||||||
|
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
|
||||||
|
assert(has_type_annotations_field(), "type_annotations field must be present");
|
||||||
|
method->obj_field_put(type_annotations_offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
void java_lang_reflect_Constructor::compute_offsets() {
|
void java_lang_reflect_Constructor::compute_offsets() {
|
||||||
Klass* k = SystemDictionary::reflect_Constructor_klass();
|
Klass* k = SystemDictionary::reflect_Constructor_klass();
|
||||||
compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature());
|
compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature());
|
||||||
@ -1973,9 +1991,11 @@ void java_lang_reflect_Constructor::compute_offsets() {
|
|||||||
signature_offset = -1;
|
signature_offset = -1;
|
||||||
annotations_offset = -1;
|
annotations_offset = -1;
|
||||||
parameter_annotations_offset = -1;
|
parameter_annotations_offset = -1;
|
||||||
|
type_annotations_offset = -1;
|
||||||
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
|
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
|
||||||
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
|
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
|
||||||
compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
|
compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
|
||||||
|
compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle java_lang_reflect_Constructor::create(TRAPS) {
|
Handle java_lang_reflect_Constructor::create(TRAPS) {
|
||||||
@ -2086,6 +2106,22 @@ void java_lang_reflect_Constructor::set_parameter_annotations(oop method, oop va
|
|||||||
method->obj_field_put(parameter_annotations_offset, value);
|
method->obj_field_put(parameter_annotations_offset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool java_lang_reflect_Constructor::has_type_annotations_field() {
|
||||||
|
return (type_annotations_offset >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
oop java_lang_reflect_Constructor::type_annotations(oop constructor) {
|
||||||
|
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
|
||||||
|
assert(has_type_annotations_field(), "type_annotations field must be present");
|
||||||
|
return constructor->obj_field(type_annotations_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void java_lang_reflect_Constructor::set_type_annotations(oop constructor, oop value) {
|
||||||
|
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
|
||||||
|
assert(has_type_annotations_field(), "type_annotations field must be present");
|
||||||
|
constructor->obj_field_put(type_annotations_offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
void java_lang_reflect_Field::compute_offsets() {
|
void java_lang_reflect_Field::compute_offsets() {
|
||||||
Klass* k = SystemDictionary::reflect_Field_klass();
|
Klass* k = SystemDictionary::reflect_Field_klass();
|
||||||
compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature());
|
compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature());
|
||||||
@ -2096,8 +2132,10 @@ void java_lang_reflect_Field::compute_offsets() {
|
|||||||
// The generic signature and annotations fields are only present in 1.5
|
// The generic signature and annotations fields are only present in 1.5
|
||||||
signature_offset = -1;
|
signature_offset = -1;
|
||||||
annotations_offset = -1;
|
annotations_offset = -1;
|
||||||
|
type_annotations_offset = -1;
|
||||||
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
|
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
|
||||||
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
|
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
|
||||||
|
compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle java_lang_reflect_Field::create(TRAPS) {
|
Handle java_lang_reflect_Field::create(TRAPS) {
|
||||||
@ -2192,6 +2230,21 @@ void java_lang_reflect_Field::set_annotations(oop field, oop value) {
|
|||||||
field->obj_field_put(annotations_offset, value);
|
field->obj_field_put(annotations_offset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool java_lang_reflect_Field::has_type_annotations_field() {
|
||||||
|
return (type_annotations_offset >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
oop java_lang_reflect_Field::type_annotations(oop field) {
|
||||||
|
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
|
||||||
|
assert(has_type_annotations_field(), "type_annotations field must be present");
|
||||||
|
return field->obj_field(type_annotations_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void java_lang_reflect_Field::set_type_annotations(oop field, oop value) {
|
||||||
|
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
|
||||||
|
assert(has_type_annotations_field(), "type_annotations field must be present");
|
||||||
|
field->obj_field_put(type_annotations_offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
void sun_reflect_ConstantPool::compute_offsets() {
|
void sun_reflect_ConstantPool::compute_offsets() {
|
||||||
Klass* k = SystemDictionary::reflect_ConstantPool_klass();
|
Klass* k = SystemDictionary::reflect_ConstantPool_klass();
|
||||||
@ -2857,6 +2910,7 @@ int java_lang_reflect_Method::signature_offset;
|
|||||||
int java_lang_reflect_Method::annotations_offset;
|
int java_lang_reflect_Method::annotations_offset;
|
||||||
int java_lang_reflect_Method::parameter_annotations_offset;
|
int java_lang_reflect_Method::parameter_annotations_offset;
|
||||||
int java_lang_reflect_Method::annotation_default_offset;
|
int java_lang_reflect_Method::annotation_default_offset;
|
||||||
|
int java_lang_reflect_Method::type_annotations_offset;
|
||||||
int java_lang_reflect_Constructor::clazz_offset;
|
int java_lang_reflect_Constructor::clazz_offset;
|
||||||
int java_lang_reflect_Constructor::parameterTypes_offset;
|
int java_lang_reflect_Constructor::parameterTypes_offset;
|
||||||
int java_lang_reflect_Constructor::exceptionTypes_offset;
|
int java_lang_reflect_Constructor::exceptionTypes_offset;
|
||||||
@ -2865,6 +2919,7 @@ int java_lang_reflect_Constructor::modifiers_offset;
|
|||||||
int java_lang_reflect_Constructor::signature_offset;
|
int java_lang_reflect_Constructor::signature_offset;
|
||||||
int java_lang_reflect_Constructor::annotations_offset;
|
int java_lang_reflect_Constructor::annotations_offset;
|
||||||
int java_lang_reflect_Constructor::parameter_annotations_offset;
|
int java_lang_reflect_Constructor::parameter_annotations_offset;
|
||||||
|
int java_lang_reflect_Constructor::type_annotations_offset;
|
||||||
int java_lang_reflect_Field::clazz_offset;
|
int java_lang_reflect_Field::clazz_offset;
|
||||||
int java_lang_reflect_Field::name_offset;
|
int java_lang_reflect_Field::name_offset;
|
||||||
int java_lang_reflect_Field::type_offset;
|
int java_lang_reflect_Field::type_offset;
|
||||||
@ -2872,6 +2927,7 @@ int java_lang_reflect_Field::slot_offset;
|
|||||||
int java_lang_reflect_Field::modifiers_offset;
|
int java_lang_reflect_Field::modifiers_offset;
|
||||||
int java_lang_reflect_Field::signature_offset;
|
int java_lang_reflect_Field::signature_offset;
|
||||||
int java_lang_reflect_Field::annotations_offset;
|
int java_lang_reflect_Field::annotations_offset;
|
||||||
|
int java_lang_reflect_Field::type_annotations_offset;
|
||||||
int java_lang_boxing_object::value_offset;
|
int java_lang_boxing_object::value_offset;
|
||||||
int java_lang_boxing_object::long_value_offset;
|
int java_lang_boxing_object::long_value_offset;
|
||||||
int java_lang_ref_Reference::referent_offset;
|
int java_lang_ref_Reference::referent_offset;
|
||||||
|
@ -554,6 +554,7 @@ class java_lang_reflect_Method : public java_lang_reflect_AccessibleObject {
|
|||||||
static int annotations_offset;
|
static int annotations_offset;
|
||||||
static int parameter_annotations_offset;
|
static int parameter_annotations_offset;
|
||||||
static int annotation_default_offset;
|
static int annotation_default_offset;
|
||||||
|
static int type_annotations_offset;
|
||||||
|
|
||||||
static void compute_offsets();
|
static void compute_offsets();
|
||||||
|
|
||||||
@ -599,6 +600,10 @@ class java_lang_reflect_Method : public java_lang_reflect_AccessibleObject {
|
|||||||
static oop annotation_default(oop method);
|
static oop annotation_default(oop method);
|
||||||
static void set_annotation_default(oop method, oop value);
|
static void set_annotation_default(oop method, oop value);
|
||||||
|
|
||||||
|
static bool has_type_annotations_field();
|
||||||
|
static oop type_annotations(oop method);
|
||||||
|
static void set_type_annotations(oop method, oop value);
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
friend class JavaClasses;
|
friend class JavaClasses;
|
||||||
};
|
};
|
||||||
@ -618,6 +623,7 @@ class java_lang_reflect_Constructor : public java_lang_reflect_AccessibleObject
|
|||||||
static int signature_offset;
|
static int signature_offset;
|
||||||
static int annotations_offset;
|
static int annotations_offset;
|
||||||
static int parameter_annotations_offset;
|
static int parameter_annotations_offset;
|
||||||
|
static int type_annotations_offset;
|
||||||
|
|
||||||
static void compute_offsets();
|
static void compute_offsets();
|
||||||
|
|
||||||
@ -653,6 +659,10 @@ class java_lang_reflect_Constructor : public java_lang_reflect_AccessibleObject
|
|||||||
static oop parameter_annotations(oop method);
|
static oop parameter_annotations(oop method);
|
||||||
static void set_parameter_annotations(oop method, oop value);
|
static void set_parameter_annotations(oop method, oop value);
|
||||||
|
|
||||||
|
static bool has_type_annotations_field();
|
||||||
|
static oop type_annotations(oop constructor);
|
||||||
|
static void set_type_annotations(oop constructor, oop value);
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
friend class JavaClasses;
|
friend class JavaClasses;
|
||||||
};
|
};
|
||||||
@ -671,6 +681,7 @@ class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject {
|
|||||||
static int modifiers_offset;
|
static int modifiers_offset;
|
||||||
static int signature_offset;
|
static int signature_offset;
|
||||||
static int annotations_offset;
|
static int annotations_offset;
|
||||||
|
static int type_annotations_offset;
|
||||||
|
|
||||||
static void compute_offsets();
|
static void compute_offsets();
|
||||||
|
|
||||||
@ -710,6 +721,10 @@ class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject {
|
|||||||
static oop annotation_default(oop method);
|
static oop annotation_default(oop method);
|
||||||
static void set_annotation_default(oop method, oop value);
|
static void set_annotation_default(oop method, oop value);
|
||||||
|
|
||||||
|
static bool has_type_annotations_field();
|
||||||
|
static oop type_annotations(oop field);
|
||||||
|
static void set_type_annotations(oop field, oop value);
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
friend class JavaClasses;
|
friend class JavaClasses;
|
||||||
};
|
};
|
||||||
|
@ -136,6 +136,8 @@
|
|||||||
template(tag_runtime_visible_parameter_annotations, "RuntimeVisibleParameterAnnotations") \
|
template(tag_runtime_visible_parameter_annotations, "RuntimeVisibleParameterAnnotations") \
|
||||||
template(tag_runtime_invisible_parameter_annotations,"RuntimeInvisibleParameterAnnotations") \
|
template(tag_runtime_invisible_parameter_annotations,"RuntimeInvisibleParameterAnnotations") \
|
||||||
template(tag_annotation_default, "AnnotationDefault") \
|
template(tag_annotation_default, "AnnotationDefault") \
|
||||||
|
template(tag_runtime_visible_type_annotations, "RuntimeVisibleTypeAnnotations") \
|
||||||
|
template(tag_runtime_invisible_type_annotations, "RuntimeInvisibleTypeAnnotations") \
|
||||||
template(tag_enclosing_method, "EnclosingMethod") \
|
template(tag_enclosing_method, "EnclosingMethod") \
|
||||||
template(tag_bootstrap_methods, "BootstrapMethods") \
|
template(tag_bootstrap_methods, "BootstrapMethods") \
|
||||||
\
|
\
|
||||||
@ -239,6 +241,9 @@
|
|||||||
template(ConstantPool_name, "constantPoolOop") \
|
template(ConstantPool_name, "constantPoolOop") \
|
||||||
template(sun_reflect_UnsafeStaticFieldAccessorImpl, "sun/reflect/UnsafeStaticFieldAccessorImpl")\
|
template(sun_reflect_UnsafeStaticFieldAccessorImpl, "sun/reflect/UnsafeStaticFieldAccessorImpl")\
|
||||||
template(base_name, "base") \
|
template(base_name, "base") \
|
||||||
|
/* Type Annotations (JDK 8 and above) */ \
|
||||||
|
template(type_annotations_name, "typeAnnotations") \
|
||||||
|
\
|
||||||
\
|
\
|
||||||
/* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \
|
/* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \
|
||||||
template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \
|
template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \
|
||||||
|
@ -61,6 +61,9 @@ void Annotations::deallocate_contents(ClassLoaderData* loader_data) {
|
|||||||
free_contents(loader_data, methods_annotations());
|
free_contents(loader_data, methods_annotations());
|
||||||
free_contents(loader_data, methods_parameter_annotations());
|
free_contents(loader_data, methods_parameter_annotations());
|
||||||
free_contents(loader_data, methods_default_annotations());
|
free_contents(loader_data, methods_default_annotations());
|
||||||
|
|
||||||
|
// Recursively deallocate optional Annotations linked through this one
|
||||||
|
MetadataFactory::free_metadata(loader_data, type_annotations());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the annotation at 'idnum' to 'anno'.
|
// Set the annotation at 'idnum' to 'anno'.
|
||||||
|
@ -38,7 +38,8 @@ class outputStream;
|
|||||||
typedef Array<u1> AnnotationArray;
|
typedef Array<u1> AnnotationArray;
|
||||||
|
|
||||||
// Class to hold the various types of annotations. The only metadata that points
|
// Class to hold the various types of annotations. The only metadata that points
|
||||||
// to this is InstanceKlass.
|
// to this is InstanceKlass, or another Annotations instance if this is a
|
||||||
|
// a type_annotation instance.
|
||||||
|
|
||||||
class Annotations: public MetaspaceObj {
|
class Annotations: public MetaspaceObj {
|
||||||
|
|
||||||
@ -58,6 +59,8 @@ class Annotations: public MetaspaceObj {
|
|||||||
// such annotations.
|
// such annotations.
|
||||||
// Index is the idnum, which is initially the same as the methods array index.
|
// Index is the idnum, which is initially the same as the methods array index.
|
||||||
Array<AnnotationArray*>* _methods_default_annotations;
|
Array<AnnotationArray*>* _methods_default_annotations;
|
||||||
|
// Type annotations for this class, or null if none.
|
||||||
|
Annotations* _type_annotations;
|
||||||
|
|
||||||
// Constructor where some some values are known to not be null
|
// Constructor where some some values are known to not be null
|
||||||
Annotations(Array<AnnotationArray*>* fa, Array<AnnotationArray*>* ma,
|
Annotations(Array<AnnotationArray*>* fa, Array<AnnotationArray*>* ma,
|
||||||
@ -66,7 +69,8 @@ class Annotations: public MetaspaceObj {
|
|||||||
_fields_annotations(fa),
|
_fields_annotations(fa),
|
||||||
_methods_annotations(ma),
|
_methods_annotations(ma),
|
||||||
_methods_parameter_annotations(mpa),
|
_methods_parameter_annotations(mpa),
|
||||||
_methods_default_annotations(mda) {}
|
_methods_default_annotations(mda),
|
||||||
|
_type_annotations(NULL) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Allocate instance of this class
|
// Allocate instance of this class
|
||||||
@ -81,22 +85,26 @@ class Annotations: public MetaspaceObj {
|
|||||||
static int size() { return sizeof(Annotations) / wordSize; }
|
static int size() { return sizeof(Annotations) / wordSize; }
|
||||||
|
|
||||||
// Constructor to initialize to null
|
// Constructor to initialize to null
|
||||||
Annotations() : _class_annotations(NULL), _fields_annotations(NULL),
|
Annotations() : _class_annotations(NULL),
|
||||||
|
_fields_annotations(NULL),
|
||||||
_methods_annotations(NULL),
|
_methods_annotations(NULL),
|
||||||
_methods_parameter_annotations(NULL),
|
_methods_parameter_annotations(NULL),
|
||||||
_methods_default_annotations(NULL) {}
|
_methods_default_annotations(NULL),
|
||||||
|
_type_annotations(NULL) {}
|
||||||
|
|
||||||
AnnotationArray* class_annotations() const { return _class_annotations; }
|
AnnotationArray* class_annotations() const { return _class_annotations; }
|
||||||
Array<AnnotationArray*>* fields_annotations() const { return _fields_annotations; }
|
Array<AnnotationArray*>* fields_annotations() const { return _fields_annotations; }
|
||||||
Array<AnnotationArray*>* methods_annotations() const { return _methods_annotations; }
|
Array<AnnotationArray*>* methods_annotations() const { return _methods_annotations; }
|
||||||
Array<AnnotationArray*>* methods_parameter_annotations() const { return _methods_parameter_annotations; }
|
Array<AnnotationArray*>* methods_parameter_annotations() const { return _methods_parameter_annotations; }
|
||||||
Array<AnnotationArray*>* methods_default_annotations() const { return _methods_default_annotations; }
|
Array<AnnotationArray*>* methods_default_annotations() const { return _methods_default_annotations; }
|
||||||
|
Annotations* type_annotations() const { return _type_annotations; }
|
||||||
|
|
||||||
void set_class_annotations(AnnotationArray* md) { _class_annotations = md; }
|
void set_class_annotations(AnnotationArray* md) { _class_annotations = md; }
|
||||||
void set_fields_annotations(Array<AnnotationArray*>* md) { _fields_annotations = md; }
|
void set_fields_annotations(Array<AnnotationArray*>* md) { _fields_annotations = md; }
|
||||||
void set_methods_annotations(Array<AnnotationArray*>* md) { _methods_annotations = md; }
|
void set_methods_annotations(Array<AnnotationArray*>* md) { _methods_annotations = md; }
|
||||||
void set_methods_parameter_annotations(Array<AnnotationArray*>* md) { _methods_parameter_annotations = md; }
|
void set_methods_parameter_annotations(Array<AnnotationArray*>* md) { _methods_parameter_annotations = md; }
|
||||||
void set_methods_default_annotations(Array<AnnotationArray*>* md) { _methods_default_annotations = md; }
|
void set_methods_default_annotations(Array<AnnotationArray*>* md) { _methods_default_annotations = md; }
|
||||||
|
void set_type_annotations(Annotations* annos) { _type_annotations = annos; }
|
||||||
|
|
||||||
// Redefine classes support
|
// Redefine classes support
|
||||||
AnnotationArray* get_method_annotations_of(int idnum)
|
AnnotationArray* get_method_annotations_of(int idnum)
|
||||||
@ -129,6 +137,7 @@ class Annotations: public MetaspaceObj {
|
|||||||
inline AnnotationArray* get_method_annotations_from(int idnum, Array<AnnotationArray*>* annos);
|
inline AnnotationArray* get_method_annotations_from(int idnum, Array<AnnotationArray*>* annos);
|
||||||
void set_annotations(Array<AnnotationArray*>* md, Array<AnnotationArray*>** md_p) { *md_p = md; }
|
void set_annotations(Array<AnnotationArray*>* md, Array<AnnotationArray*>** md_p) { *md_p = md; }
|
||||||
|
|
||||||
|
bool is_klass() const { return false; }
|
||||||
private:
|
private:
|
||||||
void set_methods_annotations_of(instanceKlassHandle ik,
|
void set_methods_annotations_of(instanceKlassHandle ik,
|
||||||
int idnum, AnnotationArray* anno,
|
int idnum, AnnotationArray* anno,
|
||||||
|
@ -361,6 +361,9 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
|||||||
set_protection_domain(NULL);
|
set_protection_domain(NULL);
|
||||||
set_signers(NULL);
|
set_signers(NULL);
|
||||||
set_init_lock(NULL);
|
set_init_lock(NULL);
|
||||||
|
|
||||||
|
// We should deallocate the Annotations instance
|
||||||
|
MetadataFactory::free_metadata(loader_data, annotations());
|
||||||
set_annotations(NULL);
|
set_annotations(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,6 +657,10 @@ class InstanceKlass: public Klass {
|
|||||||
if (annotations() == NULL) return NULL;
|
if (annotations() == NULL) return NULL;
|
||||||
return annotations()->fields_annotations();
|
return annotations()->fields_annotations();
|
||||||
}
|
}
|
||||||
|
Annotations* type_annotations() const {
|
||||||
|
if (annotations() == NULL) return NULL;
|
||||||
|
return annotations()->type_annotations();
|
||||||
|
}
|
||||||
|
|
||||||
// allocation
|
// allocation
|
||||||
instanceOop allocate_instance(TRAPS);
|
instanceOop allocate_instance(TRAPS);
|
||||||
|
@ -1331,13 +1331,15 @@ void Method::sort_methods(Array<Method*>* methods,
|
|||||||
Array<AnnotationArray*>* methods_annotations,
|
Array<AnnotationArray*>* methods_annotations,
|
||||||
Array<AnnotationArray*>* methods_parameter_annotations,
|
Array<AnnotationArray*>* methods_parameter_annotations,
|
||||||
Array<AnnotationArray*>* methods_default_annotations,
|
Array<AnnotationArray*>* methods_default_annotations,
|
||||||
|
Array<AnnotationArray*>* methods_type_annotations,
|
||||||
bool idempotent) {
|
bool idempotent) {
|
||||||
int length = methods->length();
|
int length = methods->length();
|
||||||
if (length > 1) {
|
if (length > 1) {
|
||||||
bool do_annotations = false;
|
bool do_annotations = false;
|
||||||
if (methods_annotations != NULL ||
|
if (methods_annotations != NULL ||
|
||||||
methods_parameter_annotations != NULL ||
|
methods_parameter_annotations != NULL ||
|
||||||
methods_default_annotations != NULL) {
|
methods_default_annotations != NULL ||
|
||||||
|
methods_type_annotations != NULL) {
|
||||||
do_annotations = true;
|
do_annotations = true;
|
||||||
}
|
}
|
||||||
if (do_annotations) {
|
if (do_annotations) {
|
||||||
@ -1356,6 +1358,7 @@ void Method::sort_methods(Array<Method*>* methods,
|
|||||||
assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), "");
|
assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), "");
|
||||||
assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
|
assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
|
||||||
assert(methods_default_annotations == NULL || methods_default_annotations->length() == methods->length(), "");
|
assert(methods_default_annotations == NULL || methods_default_annotations->length() == methods->length(), "");
|
||||||
|
assert(methods_type_annotations == NULL || methods_type_annotations->length() == methods->length(), "");
|
||||||
if (do_annotations) {
|
if (do_annotations) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
// Allocate temporary storage
|
// Allocate temporary storage
|
||||||
@ -1363,6 +1366,7 @@ void Method::sort_methods(Array<Method*>* methods,
|
|||||||
reorder_based_on_method_index(methods, methods_annotations, temp_array);
|
reorder_based_on_method_index(methods, methods_annotations, temp_array);
|
||||||
reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
|
reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
|
||||||
reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
|
reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
|
||||||
|
reorder_based_on_method_index(methods, methods_type_annotations, temp_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset method ordering
|
// Reset method ordering
|
||||||
|
@ -228,6 +228,13 @@ class Method : public Metadata {
|
|||||||
}
|
}
|
||||||
return ik->annotations()->get_method_default_annotations_of(method_idnum());
|
return ik->annotations()->get_method_default_annotations_of(method_idnum());
|
||||||
}
|
}
|
||||||
|
AnnotationArray* type_annotations() const {
|
||||||
|
InstanceKlass* ik = method_holder();
|
||||||
|
Annotations* type_annos = ik->type_annotations();
|
||||||
|
if (type_annos == NULL)
|
||||||
|
return NULL;
|
||||||
|
return type_annos->get_method_annotations_of(method_idnum());
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CC_INTERP
|
#ifdef CC_INTERP
|
||||||
void set_result_index(BasicType type);
|
void set_result_index(BasicType type);
|
||||||
@ -794,6 +801,7 @@ class Method : public Metadata {
|
|||||||
Array<AnnotationArray*>* methods_annotations,
|
Array<AnnotationArray*>* methods_annotations,
|
||||||
Array<AnnotationArray*>* methods_parameter_annotations,
|
Array<AnnotationArray*>* methods_parameter_annotations,
|
||||||
Array<AnnotationArray*>* methods_default_annotations,
|
Array<AnnotationArray*>* methods_default_annotations,
|
||||||
|
Array<AnnotationArray*>* methods_type_annotations,
|
||||||
bool idempotent = false);
|
bool idempotent = false);
|
||||||
|
|
||||||
// size of parameters
|
// size of parameters
|
||||||
|
@ -1573,6 +1573,23 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject met
|
|||||||
Annotations::make_java_array(m->parameter_annotations(), THREAD));
|
Annotations::make_java_array(m->parameter_annotations(), THREAD));
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
/* Type use annotations support (JDK 1.8) */
|
||||||
|
|
||||||
|
JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls))
|
||||||
|
assert (cls != NULL, "illegal class");
|
||||||
|
JVMWrapper("JVM_GetClassTypeAnnotations");
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
// Return null for arrays and primitives
|
||||||
|
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
|
||||||
|
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
|
||||||
|
if (k->oop_is_instance()) {
|
||||||
|
typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->type_annotations()->class_annotations(), CHECK_NULL);
|
||||||
|
return (jbyteArray) JNIHandles::make_local(env, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
// New (JDK 1.4) reflection implementation /////////////////////////////////////
|
// New (JDK 1.4) reflection implementation /////////////////////////////////////
|
||||||
|
|
||||||
|
@ -519,6 +519,10 @@ JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method);
|
|||||||
JNIEXPORT jbyteArray JNICALL
|
JNIEXPORT jbyteArray JNICALL
|
||||||
JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method);
|
JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method);
|
||||||
|
|
||||||
|
/* Type use annotations support (JDK 1.8) */
|
||||||
|
|
||||||
|
JNIEXPORT jbyteArray JNICALL
|
||||||
|
JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* New (JDK 1.4) reflection implementation
|
* New (JDK 1.4) reflection implementation
|
||||||
|
@ -3338,7 +3338,20 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
|
|||||||
the_class->set_access_flags(flags);
|
the_class->set_access_flags(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace annotation fields value
|
// Since there is currently no rewriting of type annotations indexes
|
||||||
|
// into the CP, we null out type annotations on scratch_class before
|
||||||
|
// we swap annotations with the_class rather than facing the
|
||||||
|
// possibility of shipping annotations with broken indexes to
|
||||||
|
// Java-land.
|
||||||
|
Annotations* new_annotations = scratch_class->annotations();
|
||||||
|
if (new_annotations != NULL) {
|
||||||
|
Annotations* new_type_annotations = new_annotations->type_annotations();
|
||||||
|
if (new_type_annotations != NULL) {
|
||||||
|
MetadataFactory::free_metadata(scratch_class->class_loader_data(), new_type_annotations);
|
||||||
|
new_annotations->set_type_annotations(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Swap annotation fields values
|
||||||
Annotations* old_annotations = the_class->annotations();
|
Annotations* old_annotations = the_class->annotations();
|
||||||
the_class->set_annotations(scratch_class->annotations());
|
the_class->set_annotations(scratch_class->annotations());
|
||||||
scratch_class->set_annotations(old_annotations);
|
scratch_class->set_annotations(old_annotations);
|
||||||
|
@ -65,6 +65,17 @@ AnnotationArray* fieldDescriptor::annotations() const {
|
|||||||
return md->at(index());
|
return md->at(index());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnnotationArray* fieldDescriptor::type_annotations() const {
|
||||||
|
InstanceKlass* ik = field_holder();
|
||||||
|
Annotations* type_annos = ik->type_annotations();
|
||||||
|
if (type_annos == NULL)
|
||||||
|
return NULL;
|
||||||
|
Array<AnnotationArray*>* md = type_annos->fields_annotations();
|
||||||
|
if (md == NULL)
|
||||||
|
return NULL;
|
||||||
|
return md->at(index());
|
||||||
|
}
|
||||||
|
|
||||||
constantTag fieldDescriptor::initial_value_tag() const {
|
constantTag fieldDescriptor::initial_value_tag() const {
|
||||||
return constants()->tag_at(initial_value_index());
|
return constants()->tag_at(initial_value_index());
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC {
|
|||||||
Symbol* generic_signature() const;
|
Symbol* generic_signature() const;
|
||||||
int index() const { return _index; }
|
int index() const { return _index; }
|
||||||
AnnotationArray* annotations() const;
|
AnnotationArray* annotations() const;
|
||||||
|
AnnotationArray* type_annotations() const;
|
||||||
|
|
||||||
// Initial field value
|
// Initial field value
|
||||||
bool has_initial_value() const { return field()->initval_index() != 0; }
|
bool has_initial_value() const { return field()->initval_index() != 0; }
|
||||||
|
@ -771,6 +771,10 @@ oop Reflection::new_method(methodHandle method, bool intern_name, bool for_const
|
|||||||
typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL);
|
typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL);
|
||||||
java_lang_reflect_Method::set_annotation_default(mh(), an_oop);
|
java_lang_reflect_Method::set_annotation_default(mh(), an_oop);
|
||||||
}
|
}
|
||||||
|
if (java_lang_reflect_Method::has_type_annotations_field()) {
|
||||||
|
typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL);
|
||||||
|
java_lang_reflect_Method::set_type_annotations(mh(), an_oop);
|
||||||
|
}
|
||||||
return mh();
|
return mh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,6 +853,10 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
|
|||||||
typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
|
typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
|
||||||
java_lang_reflect_Field::set_annotations(rh(), an_oop);
|
java_lang_reflect_Field::set_annotations(rh(), an_oop);
|
||||||
}
|
}
|
||||||
|
if (java_lang_reflect_Field::has_type_annotations_field()) {
|
||||||
|
typeArrayOop an_oop = Annotations::make_java_array(fd->type_annotations(), CHECK_NULL);
|
||||||
|
java_lang_reflect_Field::set_type_annotations(rh(), an_oop);
|
||||||
|
}
|
||||||
return rh();
|
return rh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user