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 }