--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Dec 19 10:35:08 2012 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Dec 20 10:22:19 2012 +0100
@@ -906,6 +906,7 @@
bool* is_synthetic_addr,
u2* generic_signature_index_addr,
AnnotationArray** field_annotations,
+ AnnotationArray** field_type_annotations,
ClassFileParser::FieldAnnotationCollector* parsed_annotations,
TRAPS) {
ClassFileStream* cfs = stream();
@@ -917,6 +918,10 @@
int runtime_visible_annotations_length = 0;
u1* runtime_invisible_annotations = NULL;
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--) {
cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
u2 attribute_name_index = cfs->get_u2_fast();
@@ -971,6 +976,16 @@
runtime_invisible_annotations = cfs->get_u1_buffer();
assert(runtime_invisible_annotations != NULL, "null invisible annotations");
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 {
cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes
}
@@ -988,6 +1003,12 @@
runtime_invisible_annotations,
runtime_invisible_annotations_length,
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;
}
@@ -1084,6 +1105,7 @@
bool is_interface,
FieldAllocationCount *fac,
Array<AnnotationArray*>** fields_annotations,
+ Array<AnnotationArray*>** fields_type_annotations,
u2* java_fields_count_ptr, TRAPS) {
ClassFileStream* cfs = stream();
cfs->guarantee_more(2, CHECK_NULL); // length
@@ -1119,6 +1141,7 @@
THREAD, u2, total_fields * (FieldInfo::field_slots + 1));
AnnotationArray* field_annotations = NULL;
+ AnnotationArray* field_type_annotations = NULL;
// The generic signature slots start after all other fields' data.
int generic_signature_slot = total_fields * FieldInfo::field_slots;
int num_generic_signature = 0;
@@ -1160,7 +1183,7 @@
cp, attributes_count, is_static, signature_index,
&constantvalue_index, &is_synthetic,
&generic_signature_index, &field_annotations,
- &parsed_annotations,
+ &field_type_annotations, &parsed_annotations,
CHECK_NULL);
if (field_annotations != NULL) {
if (*fields_annotations == NULL) {
@@ -1170,6 +1193,14 @@
}
(*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) {
access_flags.set_is_synthetic();
}
@@ -1831,6 +1862,7 @@
AnnotationArray** method_annotations,
AnnotationArray** method_parameter_annotations,
AnnotationArray** method_default_annotations,
+ AnnotationArray** method_type_annotations,
TRAPS) {
ClassFileStream* cfs = stream();
methodHandle nullHandle;
@@ -1918,6 +1950,10 @@
int runtime_visible_parameter_annotations_length = 0;
u1* runtime_invisible_parameter_annotations = NULL;
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;
int annotation_default_length = 0;
@@ -2159,6 +2195,17 @@
annotation_default = cfs->get_u1_buffer();
assert(annotation_default != NULL, "null annotation default");
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 {
// Skip unknown attributes
cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
@@ -2333,6 +2380,12 @@
NULL,
0,
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() &&
signature == vmSymbols::void_method_signature()) {
@@ -2364,12 +2417,14 @@
Array<AnnotationArray*>** methods_annotations,
Array<AnnotationArray*>** methods_parameter_annotations,
Array<AnnotationArray*>** methods_default_annotations,
+ Array<AnnotationArray*>** methods_type_annotations,
bool* has_default_methods,
TRAPS) {
ClassFileStream* cfs = stream();
AnnotationArray* method_annotations = NULL;
AnnotationArray* method_parameter_annotations = NULL;
AnnotationArray* method_default_annotations = NULL;
+ AnnotationArray* method_type_annotations = NULL;
cfs->guarantee_more(2, CHECK_NULL); // length
u2 length = cfs->get_u2_fast();
if (length == 0) {
@@ -2386,6 +2441,7 @@
&method_annotations,
&method_parameter_annotations,
&method_default_annotations,
+ &method_type_annotations,
CHECK_NULL);
if (method->is_final()) {
@@ -2411,7 +2467,13 @@
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
}
(*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) {
// Check duplicated methods
ResourceMark rm(THREAD);
@@ -2445,6 +2507,7 @@
Array<AnnotationArray*>* methods_annotations,
Array<AnnotationArray*>* methods_parameter_annotations,
Array<AnnotationArray*>* methods_default_annotations,
+ Array<AnnotationArray*>* methods_type_annotations,
TRAPS) {
int length = methods->length();
// If JVMTI original method ordering or sharing is enabled we have to
@@ -2463,7 +2526,8 @@
// Note that the ordering is not alphabetical, see Symbol::fast_compare
Method::sort_methods(methods, methods_annotations,
methods_parameter_annotations,
- methods_default_annotations);
+ methods_default_annotations,
+ methods_type_annotations);
// If JVMTI original method ordering or sharing is enabled construct int
// array remembering the original ordering
@@ -2728,6 +2792,10 @@
int runtime_visible_annotations_length = 0;
u1* runtime_invisible_annotations = NULL;
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;
u4 inner_classes_attribute_length = 0;
u2 enclosing_method_class_index = 0;
@@ -2834,6 +2902,17 @@
classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
parsed_bootstrap_methods_attribute = true;
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 {
// Unknown attribute
cfs->skip_u1(attribute_length, CHECK);
@@ -2850,6 +2929,13 @@
runtime_invisible_annotations_length,
CHECK);
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) {
u2 num_of_classes = parse_classfile_inner_classes_attribute(
@@ -3190,7 +3276,9 @@
// Fields (offsets are filled in later)
FieldAllocationCount fac;
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,
+ &fields_type_annotations,
&java_fields_count,
CHECK_(nullHandle));
// Methods
@@ -3202,6 +3290,7 @@
Array<AnnotationArray*>* methods_annotations = NULL;
Array<AnnotationArray*>* methods_parameter_annotations = NULL;
Array<AnnotationArray*>* methods_default_annotations = NULL;
+ Array<AnnotationArray*>* methods_type_annotations = NULL;
Array<Method*>* methods = parse_methods(loader_data,
cp, access_flags.is_interface(),
&promoted_flags,
@@ -3209,6 +3298,7 @@
&methods_annotations,
&methods_parameter_annotations,
&methods_default_annotations,
+ &methods_type_annotations,
&has_default_methods,
CHECK_(nullHandle));
@@ -3270,6 +3360,7 @@
methods_annotations,
methods_parameter_annotations,
methods_default_annotations,
+ methods_type_annotations,
CHECK_(nullHandle));
// promote flags from parse_methods() to the klass' flags
@@ -3687,11 +3778,13 @@
if (is_anonymous()) // I am well known to myself
cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
+ // Allocate an annotation type if needed.
if (fields_annotations != NULL ||
methods_annotations != NULL ||
methods_parameter_annotations != NULL ||
- methods_default_annotations != NULL) {
- // Allocate an annotation type if needed.
+ methods_default_annotations != NULL ||
+ fields_type_annotations != NULL ||
+ methods_type_annotations != NULL) {
Annotations* anno = Annotations::allocate(loader_data,
fields_annotations, methods_annotations,
methods_parameter_annotations,
@@ -3701,6 +3794,16 @@
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_major_version(major_version);
@@ -3725,6 +3828,7 @@
// Fill in field values obtained by parse_classfile_attributes
if (parsed_annotations.has_any_annotations())
parsed_annotations.apply_to(this_klass);
+
// Create annotations
if (_annotations != NULL && this_klass->annotations() == NULL) {
Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
@@ -3732,6 +3836,19 @@
}
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
if ((num_miranda_methods > 0) ||
// if this class introduced new miranda methods or