Mercurial > hg > truffle
comparison src/share/vm/classfile/classFileParser.cpp @ 5967:f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
Summary: Fold instanceKlass::_enclosing_method_class_index and instanceKlass::_enclosing_method_method_index into the instanceKlass::_inner_classes array.
Reviewed-by: never, coleenp
Contributed-by: Jiangli Zhou <jiangli.zhou@oracle.com>
author | jiangli |
---|---|
date | Tue, 13 Mar 2012 13:50:48 -0400 |
parents | 2b3acb34791f |
children | 749b1464aa81 49036505ab5f |
comparison
equal
deleted
inserted
replaced
5933:fde683df4c27 | 5967:f7c4174b33ba |
---|---|
2313 | 2313 |
2314 // Inner classes can be static, private or protected (classic VM does this) | 2314 // Inner classes can be static, private or protected (classic VM does this) |
2315 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC) | 2315 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC) |
2316 | 2316 |
2317 // Return number of classes in the inner classes attribute table | 2317 // Return number of classes in the inner classes attribute table |
2318 u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) { | 2318 u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start, |
2319 bool parsed_enclosingmethod_attribute, | |
2320 u2 enclosing_method_class_index, | |
2321 u2 enclosing_method_method_index, | |
2322 constantPoolHandle cp, | |
2323 instanceKlassHandle k, TRAPS) { | |
2319 ClassFileStream* cfs = stream(); | 2324 ClassFileStream* cfs = stream(); |
2320 cfs->guarantee_more(2, CHECK_0); // length | 2325 u1* current_mark = cfs->current(); |
2321 u2 length = cfs->get_u2_fast(); | 2326 u2 length = 0; |
2322 | 2327 if (inner_classes_attribute_start != NULL) { |
2323 // 4-tuples of shorts [inner_class_info_index, outer_class_info_index, inner_name_index, inner_class_access_flags] | 2328 cfs->set_current(inner_classes_attribute_start); |
2324 typeArrayOop ic = oopFactory::new_permanent_shortArray(length*4, CHECK_0); | 2329 cfs->guarantee_more(2, CHECK_0); // length |
2330 length = cfs->get_u2_fast(); | |
2331 } | |
2332 | |
2333 // 4-tuples of shorts of inner classes data and 2 shorts of enclosing | |
2334 // method data: | |
2335 // [inner_class_info_index, | |
2336 // outer_class_info_index, | |
2337 // inner_name_index, | |
2338 // inner_class_access_flags, | |
2339 // ... | |
2340 // enclosing_method_class_index, | |
2341 // enclosing_method_method_index] | |
2342 int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0); | |
2343 typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0); | |
2325 typeArrayHandle inner_classes(THREAD, ic); | 2344 typeArrayHandle inner_classes(THREAD, ic); |
2326 int index = 0; | 2345 int index = 0; |
2327 int cp_size = cp->length(); | 2346 int cp_size = cp->length(); |
2328 cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2 | 2347 cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2 |
2329 for (int n = 0; n < length; n++) { | 2348 for (int n = 0; n < length; n++) { |
2370 inner_classes->short_at_put(index++, inner_access_flags.as_short()); | 2389 inner_classes->short_at_put(index++, inner_access_flags.as_short()); |
2371 } | 2390 } |
2372 | 2391 |
2373 // 4347400: make sure there's no duplicate entry in the classes array | 2392 // 4347400: make sure there's no duplicate entry in the classes array |
2374 if (_need_verify && _major_version >= JAVA_1_5_VERSION) { | 2393 if (_need_verify && _major_version >= JAVA_1_5_VERSION) { |
2375 for(int i = 0; i < inner_classes->length(); i += 4) { | 2394 for(int i = 0; i < length * 4; i += 4) { |
2376 for(int j = i + 4; j < inner_classes->length(); j += 4) { | 2395 for(int j = i + 4; j < length * 4; j += 4) { |
2377 guarantee_property((inner_classes->ushort_at(i) != inner_classes->ushort_at(j) || | 2396 guarantee_property((inner_classes->ushort_at(i) != inner_classes->ushort_at(j) || |
2378 inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) || | 2397 inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) || |
2379 inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) || | 2398 inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) || |
2380 inner_classes->ushort_at(i+3) != inner_classes->ushort_at(j+3)), | 2399 inner_classes->ushort_at(i+3) != inner_classes->ushort_at(j+3)), |
2381 "Duplicate entry in InnerClasses in class file %s", | 2400 "Duplicate entry in InnerClasses in class file %s", |
2382 CHECK_0); | 2401 CHECK_0); |
2383 } | 2402 } |
2384 } | 2403 } |
2385 } | 2404 } |
2386 | 2405 |
2406 // Set EnclosingMethod class and method indexes. | |
2407 if (parsed_enclosingmethod_attribute) { | |
2408 inner_classes->short_at_put(index++, enclosing_method_class_index); | |
2409 inner_classes->short_at_put(index++, enclosing_method_method_index); | |
2410 } | |
2411 assert(index == size, "wrong size"); | |
2412 | |
2387 // Update instanceKlass with inner class info. | 2413 // Update instanceKlass with inner class info. |
2388 k->set_inner_classes(inner_classes()); | 2414 k->set_inner_classes(inner_classes()); |
2415 | |
2416 // Restore buffer's current position. | |
2417 cfs->set_current(current_mark); | |
2418 | |
2389 return length; | 2419 return length; |
2390 } | 2420 } |
2391 | 2421 |
2392 void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) { | 2422 void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) { |
2393 k->set_is_synthetic(); | 2423 k->set_is_synthetic(); |
2488 bool parsed_bootstrap_methods_attribute = false; | 2518 bool parsed_bootstrap_methods_attribute = false; |
2489 u1* runtime_visible_annotations = NULL; | 2519 u1* runtime_visible_annotations = NULL; |
2490 int runtime_visible_annotations_length = 0; | 2520 int runtime_visible_annotations_length = 0; |
2491 u1* runtime_invisible_annotations = NULL; | 2521 u1* runtime_invisible_annotations = NULL; |
2492 int runtime_invisible_annotations_length = 0; | 2522 int runtime_invisible_annotations_length = 0; |
2523 u1* inner_classes_attribute_start = NULL; | |
2524 u4 inner_classes_attribute_length = 0; | |
2525 u2 enclosing_method_class_index = 0; | |
2526 u2 enclosing_method_method_index = 0; | |
2493 // Iterate over attributes | 2527 // Iterate over attributes |
2494 while (attributes_count--) { | 2528 while (attributes_count--) { |
2495 cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length | 2529 cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length |
2496 u2 attribute_name_index = cfs->get_u2_fast(); | 2530 u2 attribute_name_index = cfs->get_u2_fast(); |
2497 u4 attribute_length = cfs->get_u4_fast(); | 2531 u4 attribute_length = cfs->get_u4_fast(); |
2520 if (parsed_innerclasses_attribute) { | 2554 if (parsed_innerclasses_attribute) { |
2521 classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK); | 2555 classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK); |
2522 } else { | 2556 } else { |
2523 parsed_innerclasses_attribute = true; | 2557 parsed_innerclasses_attribute = true; |
2524 } | 2558 } |
2525 u2 num_of_classes = parse_classfile_inner_classes_attribute(cp, k, CHECK); | 2559 inner_classes_attribute_start = cfs->get_u1_buffer(); |
2526 if (_need_verify && _major_version >= JAVA_1_5_VERSION) { | 2560 inner_classes_attribute_length = attribute_length; |
2527 guarantee_property(attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes, | 2561 cfs->skip_u1(inner_classes_attribute_length, CHECK); |
2528 "Wrong InnerClasses attribute length in class file %s", CHECK); | |
2529 } | |
2530 } else if (tag == vmSymbols::tag_synthetic()) { | 2562 } else if (tag == vmSymbols::tag_synthetic()) { |
2531 // Check for Synthetic tag | 2563 // Check for Synthetic tag |
2532 // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec | 2564 // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec |
2533 if (attribute_length != 0) { | 2565 if (attribute_length != 0) { |
2534 classfile_parse_error( | 2566 classfile_parse_error( |
2566 classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); | 2598 classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); |
2567 } else { | 2599 } else { |
2568 parsed_enclosingmethod_attribute = true; | 2600 parsed_enclosingmethod_attribute = true; |
2569 } | 2601 } |
2570 cfs->guarantee_more(4, CHECK); // class_index, method_index | 2602 cfs->guarantee_more(4, CHECK); // class_index, method_index |
2571 u2 class_index = cfs->get_u2_fast(); | 2603 enclosing_method_class_index = cfs->get_u2_fast(); |
2572 u2 method_index = cfs->get_u2_fast(); | 2604 enclosing_method_method_index = cfs->get_u2_fast(); |
2573 if (class_index == 0) { | 2605 if (enclosing_method_class_index == 0) { |
2574 classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK); | 2606 classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK); |
2575 } | 2607 } |
2576 // Validate the constant pool indices and types | 2608 // Validate the constant pool indices and types |
2577 if (!cp->is_within_bounds(class_index) || | 2609 if (!cp->is_within_bounds(enclosing_method_class_index) || |
2578 !is_klass_reference(cp, class_index)) { | 2610 !is_klass_reference(cp, enclosing_method_class_index)) { |
2579 classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK); | 2611 classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK); |
2580 } | 2612 } |
2581 if (method_index != 0 && | 2613 if (enclosing_method_method_index != 0 && |
2582 (!cp->is_within_bounds(method_index) || | 2614 (!cp->is_within_bounds(enclosing_method_method_index) || |
2583 !cp->tag_at(method_index).is_name_and_type())) { | 2615 !cp->tag_at(enclosing_method_method_index).is_name_and_type())) { |
2584 classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK); | 2616 classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK); |
2585 } | 2617 } |
2586 k->set_enclosing_method_indices(class_index, method_index); | |
2587 } else if (tag == vmSymbols::tag_bootstrap_methods() && | 2618 } else if (tag == vmSymbols::tag_bootstrap_methods() && |
2588 _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { | 2619 _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { |
2589 if (parsed_bootstrap_methods_attribute) | 2620 if (parsed_bootstrap_methods_attribute) |
2590 classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); | 2621 classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); |
2591 parsed_bootstrap_methods_attribute = true; | 2622 parsed_bootstrap_methods_attribute = true; |
2603 runtime_visible_annotations_length, | 2634 runtime_visible_annotations_length, |
2604 runtime_invisible_annotations, | 2635 runtime_invisible_annotations, |
2605 runtime_invisible_annotations_length, | 2636 runtime_invisible_annotations_length, |
2606 CHECK); | 2637 CHECK); |
2607 k->set_class_annotations(annotations()); | 2638 k->set_class_annotations(annotations()); |
2639 | |
2640 if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) { | |
2641 u2 num_of_classes = parse_classfile_inner_classes_attribute( | |
2642 inner_classes_attribute_start, | |
2643 parsed_innerclasses_attribute, | |
2644 enclosing_method_class_index, | |
2645 enclosing_method_method_index, | |
2646 cp, k, CHECK); | |
2647 if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) { | |
2648 guarantee_property( | |
2649 inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes, | |
2650 "Wrong InnerClasses attribute length in class file %s", CHECK); | |
2651 } | |
2652 } | |
2608 | 2653 |
2609 if (_max_bootstrap_specifier_index >= 0) { | 2654 if (_max_bootstrap_specifier_index >= 0) { |
2610 guarantee_property(parsed_bootstrap_methods_attribute, | 2655 guarantee_property(parsed_bootstrap_methods_attribute, |
2611 "Missing BootstrapMethods attribute in class file %s", CHECK); | 2656 "Missing BootstrapMethods attribute in class file %s", CHECK); |
2612 } | 2657 } |