mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field
Fold instanceKlass::_enclosing_method_class_index and instanceKlass::_enclosing_method_method_index into the instanceKlass::_inner_classes array. Reviewed-by: never, coleenp
This commit is contained in:
parent
db0efee3d4
commit
b9e6895d3a
11 changed files with 297 additions and 142 deletions
|
@ -2315,13 +2315,32 @@ void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantP
|
|||
#define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
|
||||
|
||||
// Return number of classes in the inner classes attribute table
|
||||
u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
|
||||
u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
|
||||
bool parsed_enclosingmethod_attribute,
|
||||
u2 enclosing_method_class_index,
|
||||
u2 enclosing_method_method_index,
|
||||
constantPoolHandle cp,
|
||||
instanceKlassHandle k, TRAPS) {
|
||||
ClassFileStream* cfs = stream();
|
||||
cfs->guarantee_more(2, CHECK_0); // length
|
||||
u2 length = cfs->get_u2_fast();
|
||||
u1* current_mark = cfs->current();
|
||||
u2 length = 0;
|
||||
if (inner_classes_attribute_start != NULL) {
|
||||
cfs->set_current(inner_classes_attribute_start);
|
||||
cfs->guarantee_more(2, CHECK_0); // length
|
||||
length = cfs->get_u2_fast();
|
||||
}
|
||||
|
||||
// 4-tuples of shorts [inner_class_info_index, outer_class_info_index, inner_name_index, inner_class_access_flags]
|
||||
typeArrayOop ic = oopFactory::new_permanent_shortArray(length*4, CHECK_0);
|
||||
// 4-tuples of shorts of inner classes data and 2 shorts of enclosing
|
||||
// method data:
|
||||
// [inner_class_info_index,
|
||||
// outer_class_info_index,
|
||||
// inner_name_index,
|
||||
// inner_class_access_flags,
|
||||
// ...
|
||||
// enclosing_method_class_index,
|
||||
// enclosing_method_method_index]
|
||||
int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
|
||||
typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0);
|
||||
typeArrayHandle inner_classes(THREAD, ic);
|
||||
int index = 0;
|
||||
int cp_size = cp->length();
|
||||
|
@ -2372,8 +2391,8 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle c
|
|||
|
||||
// 4347400: make sure there's no duplicate entry in the classes array
|
||||
if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
|
||||
for(int i = 0; i < inner_classes->length(); i += 4) {
|
||||
for(int j = i + 4; j < inner_classes->length(); j += 4) {
|
||||
for(int i = 0; i < length * 4; i += 4) {
|
||||
for(int j = i + 4; j < length * 4; j += 4) {
|
||||
guarantee_property((inner_classes->ushort_at(i) != inner_classes->ushort_at(j) ||
|
||||
inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
|
||||
inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
|
||||
|
@ -2384,8 +2403,19 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle c
|
|||
}
|
||||
}
|
||||
|
||||
// Set EnclosingMethod class and method indexes.
|
||||
if (parsed_enclosingmethod_attribute) {
|
||||
inner_classes->short_at_put(index++, enclosing_method_class_index);
|
||||
inner_classes->short_at_put(index++, enclosing_method_method_index);
|
||||
}
|
||||
assert(index == size, "wrong size");
|
||||
|
||||
// Update instanceKlass with inner class info.
|
||||
k->set_inner_classes(inner_classes());
|
||||
|
||||
// Restore buffer's current position.
|
||||
cfs->set_current(current_mark);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
@ -2490,6 +2520,10 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
|||
int runtime_visible_annotations_length = 0;
|
||||
u1* runtime_invisible_annotations = NULL;
|
||||
int runtime_invisible_annotations_length = 0;
|
||||
u1* inner_classes_attribute_start = NULL;
|
||||
u4 inner_classes_attribute_length = 0;
|
||||
u2 enclosing_method_class_index = 0;
|
||||
u2 enclosing_method_method_index = 0;
|
||||
// Iterate over attributes
|
||||
while (attributes_count--) {
|
||||
cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
|
||||
|
@ -2522,11 +2556,9 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
|||
} else {
|
||||
parsed_innerclasses_attribute = true;
|
||||
}
|
||||
u2 num_of_classes = parse_classfile_inner_classes_attribute(cp, k, CHECK);
|
||||
if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
|
||||
guarantee_property(attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
|
||||
"Wrong InnerClasses attribute length in class file %s", CHECK);
|
||||
}
|
||||
inner_classes_attribute_start = cfs->get_u1_buffer();
|
||||
inner_classes_attribute_length = attribute_length;
|
||||
cfs->skip_u1(inner_classes_attribute_length, CHECK);
|
||||
} else if (tag == vmSymbols::tag_synthetic()) {
|
||||
// Check for Synthetic tag
|
||||
// Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
|
||||
|
@ -2568,22 +2600,21 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
|||
parsed_enclosingmethod_attribute = true;
|
||||
}
|
||||
cfs->guarantee_more(4, CHECK); // class_index, method_index
|
||||
u2 class_index = cfs->get_u2_fast();
|
||||
u2 method_index = cfs->get_u2_fast();
|
||||
if (class_index == 0) {
|
||||
enclosing_method_class_index = cfs->get_u2_fast();
|
||||
enclosing_method_method_index = cfs->get_u2_fast();
|
||||
if (enclosing_method_class_index == 0) {
|
||||
classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK);
|
||||
}
|
||||
// Validate the constant pool indices and types
|
||||
if (!cp->is_within_bounds(class_index) ||
|
||||
!is_klass_reference(cp, class_index)) {
|
||||
if (!cp->is_within_bounds(enclosing_method_class_index) ||
|
||||
!is_klass_reference(cp, enclosing_method_class_index)) {
|
||||
classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
|
||||
}
|
||||
if (method_index != 0 &&
|
||||
(!cp->is_within_bounds(method_index) ||
|
||||
!cp->tag_at(method_index).is_name_and_type())) {
|
||||
if (enclosing_method_method_index != 0 &&
|
||||
(!cp->is_within_bounds(enclosing_method_method_index) ||
|
||||
!cp->tag_at(enclosing_method_method_index).is_name_and_type())) {
|
||||
classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
|
||||
}
|
||||
k->set_enclosing_method_indices(class_index, method_index);
|
||||
} else if (tag == vmSymbols::tag_bootstrap_methods() &&
|
||||
_major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
|
||||
if (parsed_bootstrap_methods_attribute)
|
||||
|
@ -2606,6 +2637,20 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
|||
CHECK);
|
||||
k->set_class_annotations(annotations());
|
||||
|
||||
if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
|
||||
u2 num_of_classes = parse_classfile_inner_classes_attribute(
|
||||
inner_classes_attribute_start,
|
||||
parsed_innerclasses_attribute,
|
||||
enclosing_method_class_index,
|
||||
enclosing_method_method_index,
|
||||
cp, k, CHECK);
|
||||
if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
|
||||
guarantee_property(
|
||||
inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
|
||||
"Wrong InnerClasses attribute length in class file %s", CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
if (_max_bootstrap_specifier_index >= 0) {
|
||||
guarantee_property(parsed_bootstrap_methods_attribute,
|
||||
"Missing BootstrapMethods attribute in class file %s", CHECK);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue