comparison src/share/vm/prims/jvmtiRedefineClasses.cpp @ 10268:43083e670adf

8005056: NPG: Crash after redefining java.lang.Object Summary: Need to walk array class vtables replacing old methods too if j.l.o redefined Reviewed-by: sspitsyn, dcubed, ctornqvi
author coleenp
date Mon, 13 May 2013 15:37:08 -0400
parents 712a1e9c91f3
children e7d29a019a3c
comparison
equal deleted inserted replaced
10267:8b40495b9381 10268:43083e670adf
158 // always called for non-product bits. 158 // always called for non-product bits.
159 #ifdef PRODUCT 159 #ifdef PRODUCT
160 if (RC_TRACE_ENABLED(0x00004000)) { 160 if (RC_TRACE_ENABLED(0x00004000)) {
161 #endif 161 #endif
162 RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class")); 162 RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
163 SystemDictionary::classes_do(check_class, thread); 163 CheckClass check_class(thread);
164 ClassLoaderDataGraph::classes_do(&check_class);
164 #ifdef PRODUCT 165 #ifdef PRODUCT
165 } 166 }
166 #endif 167 #endif
167 } 168 }
168 169
2651 rewrite_cp_refs_in_stack_map_table(method, THREAD); 2652 rewrite_cp_refs_in_stack_map_table(method, THREAD);
2652 } // end for each method 2653 } // end for each method
2653 } // end set_new_constant_pool() 2654 } // end set_new_constant_pool()
2654 2655
2655 2656
2656 void VM_RedefineClasses::adjust_array_vtable(Klass* k_oop) {
2657 ArrayKlass* ak = ArrayKlass::cast(k_oop);
2658 bool trace_name_printed = false;
2659 ak->vtable()->adjust_method_entries(_matching_old_methods,
2660 _matching_new_methods,
2661 _matching_methods_length,
2662 &trace_name_printed);
2663 }
2664
2665 // Unevolving classes may point to methods of the_class directly 2657 // Unevolving classes may point to methods of the_class directly
2666 // from their constant pool caches, itables, and/or vtables. We 2658 // from their constant pool caches, itables, and/or vtables. We
2667 // use the SystemDictionary::classes_do() facility and this helper 2659 // use the ClassLoaderDataGraph::classes_do() facility and this helper
2668 // to fix up these pointers. 2660 // to fix up these pointers.
2669 // 2661
2670 // Note: We currently don't support updating the vtable in 2662 // Adjust cpools and vtables closure
2671 // arrayKlassOops. See Open Issues in jvmtiRedefineClasses.hpp. 2663 void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
2672 void VM_RedefineClasses::adjust_cpool_cache_and_vtable(Klass* k_oop, 2664
2673 ClassLoaderData* initiating_loader, 2665 // This is a very busy routine. We don't want too much tracing
2674 TRAPS) { 2666 // printed out.
2675 Klass *k = k_oop; 2667 bool trace_name_printed = false;
2676 if (k->oop_is_instance()) { 2668
2677 HandleMark hm(THREAD); 2669 // Very noisy: only enable this call if you are trying to determine
2678 InstanceKlass *ik = (InstanceKlass *) k; 2670 // that a specific class gets found by this routine.
2671 // RC_TRACE macro has an embedded ResourceMark
2672 // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
2673 // ("adjust check: name=%s", k->external_name()));
2674 // trace_name_printed = true;
2675
2676 // If the class being redefined is java.lang.Object, we need to fix all
2677 // array class vtables also
2678 if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) {
2679 k->vtable()->adjust_method_entries(_matching_old_methods,
2680 _matching_new_methods,
2681 _matching_methods_length,
2682 &trace_name_printed);
2683 } else if (k->oop_is_instance()) {
2684 HandleMark hm(_thread);
2685 InstanceKlass *ik = InstanceKlass::cast(k);
2679 2686
2680 // HotSpot specific optimization! HotSpot does not currently 2687 // HotSpot specific optimization! HotSpot does not currently
2681 // support delegation from the bootstrap class loader to a 2688 // support delegation from the bootstrap class loader to a
2682 // user-defined class loader. This means that if the bootstrap 2689 // user-defined class loader. This means that if the bootstrap
2683 // class loader is the initiating class loader, then it will also 2690 // class loader is the initiating class loader, then it will also
2693 InstanceKlass::cast(_the_class_oop)->class_loader() != NULL; 2700 InstanceKlass::cast(_the_class_oop)->class_loader() != NULL;
2694 if (is_user_defined && ik->class_loader() == NULL) { 2701 if (is_user_defined && ik->class_loader() == NULL) {
2695 return; 2702 return;
2696 } 2703 }
2697 2704
2698 // If the class being redefined is java.lang.Object, we need to fix all
2699 // array class vtables also
2700 if (_the_class_oop == SystemDictionary::Object_klass()) {
2701 ik->array_klasses_do(adjust_array_vtable);
2702 }
2703
2704 // This is a very busy routine. We don't want too much tracing
2705 // printed out.
2706 bool trace_name_printed = false;
2707
2708 // Very noisy: only enable this call if you are trying to determine
2709 // that a specific class gets found by this routine.
2710 // RC_TRACE macro has an embedded ResourceMark
2711 // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
2712 // ("adjust check: name=%s", ik->external_name()));
2713 // trace_name_printed = true;
2714
2715 // Fix the vtable embedded in the_class and subclasses of the_class, 2705 // Fix the vtable embedded in the_class and subclasses of the_class,
2716 // if one exists. We discard scratch_class and we don't keep an 2706 // if one exists. We discard scratch_class and we don't keep an
2717 // InstanceKlass around to hold obsolete methods so we don't have 2707 // InstanceKlass around to hold obsolete methods so we don't have
2718 // any other InstanceKlass embedded vtables to update. The vtable 2708 // any other InstanceKlass embedded vtables to update. The vtable
2719 // holds the Method*s for virtual (but not final) methods. 2709 // holds the Method*s for virtual (but not final) methods.
2720 if (ik->vtable_length() > 0 && ik->is_subtype_of(_the_class_oop)) { 2710 if (ik->vtable_length() > 0 && ik->is_subtype_of(_the_class_oop)) {
2721 // ik->vtable() creates a wrapper object; rm cleans it up 2711 // ik->vtable() creates a wrapper object; rm cleans it up
2722 ResourceMark rm(THREAD); 2712 ResourceMark rm(_thread);
2723 ik->vtable()->adjust_method_entries(_matching_old_methods, 2713 ik->vtable()->adjust_method_entries(_matching_old_methods,
2724 _matching_new_methods, 2714 _matching_new_methods,
2725 _matching_methods_length, 2715 _matching_methods_length,
2726 &trace_name_printed); 2716 &trace_name_printed);
2727 } 2717 }
2733 // every InstanceKlass that has an itable since there isn't a 2723 // every InstanceKlass that has an itable since there isn't a
2734 // subclass relationship between an interface and an InstanceKlass. 2724 // subclass relationship between an interface and an InstanceKlass.
2735 if (ik->itable_length() > 0 && (_the_class_oop->is_interface() 2725 if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
2736 || ik->is_subclass_of(_the_class_oop))) { 2726 || ik->is_subclass_of(_the_class_oop))) {
2737 // ik->itable() creates a wrapper object; rm cleans it up 2727 // ik->itable() creates a wrapper object; rm cleans it up
2738 ResourceMark rm(THREAD); 2728 ResourceMark rm(_thread);
2739 ik->itable()->adjust_method_entries(_matching_old_methods, 2729 ik->itable()->adjust_method_entries(_matching_old_methods,
2740 _matching_new_methods, 2730 _matching_new_methods,
2741 _matching_methods_length, 2731 _matching_methods_length,
2742 &trace_name_printed); 2732 &trace_name_printed);
2743 } 2733 }
2756 // updated. We can simply start with the previous version(s) in 2746 // updated. We can simply start with the previous version(s) in
2757 // that case. 2747 // that case.
2758 constantPoolHandle other_cp; 2748 constantPoolHandle other_cp;
2759 ConstantPoolCache* cp_cache; 2749 ConstantPoolCache* cp_cache;
2760 2750
2761 if (k_oop != _the_class_oop) { 2751 if (ik != _the_class_oop) {
2762 // this klass' constant pool cache may need adjustment 2752 // this klass' constant pool cache may need adjustment
2763 other_cp = constantPoolHandle(ik->constants()); 2753 other_cp = constantPoolHandle(ik->constants());
2764 cp_cache = other_cp->cache(); 2754 cp_cache = other_cp->cache();
2765 if (cp_cache != NULL) { 2755 if (cp_cache != NULL) {
2766 cp_cache->adjust_method_entries(_matching_old_methods, 2756 cp_cache->adjust_method_entries(_matching_old_methods,
2768 _matching_methods_length, 2758 _matching_methods_length,
2769 &trace_name_printed); 2759 &trace_name_printed);
2770 } 2760 }
2771 } 2761 }
2772 { 2762 {
2773 ResourceMark rm(THREAD); 2763 ResourceMark rm(_thread);
2774 // PreviousVersionInfo objects returned via PreviousVersionWalker 2764 // PreviousVersionInfo objects returned via PreviousVersionWalker
2775 // contain a GrowableArray of handles. We have to clean up the 2765 // contain a GrowableArray of handles. We have to clean up the
2776 // GrowableArray _after_ the PreviousVersionWalker destructor 2766 // GrowableArray _after_ the PreviousVersionWalker destructor
2777 // has destroyed the handles. 2767 // has destroyed the handles.
2778 { 2768 {
3206 // - replacing parts in the_class with parts from scratch_class 3196 // - replacing parts in the_class with parts from scratch_class
3207 // - adding a weak reference to track the obsolete but interesting 3197 // - adding a weak reference to track the obsolete but interesting
3208 // parts of the_class 3198 // parts of the_class
3209 // - adjusting constant pool caches and vtables in other classes 3199 // - adjusting constant pool caches and vtables in other classes
3210 // that refer to methods in the_class. These adjustments use the 3200 // that refer to methods in the_class. These adjustments use the
3211 // SystemDictionary::classes_do() facility which only allows 3201 // ClassLoaderDataGraph::classes_do() facility which only allows
3212 // a helper method to be specified. The interesting parameters 3202 // a helper method to be specified. The interesting parameters
3213 // that we would like to pass to the helper method are saved in 3203 // that we would like to pass to the helper method are saved in
3214 // static global fields in the VM operation. 3204 // static global fields in the VM operation.
3215 void VM_RedefineClasses::redefine_single_class(jclass the_jclass, 3205 void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
3216 Klass* scratch_class_oop, TRAPS) { 3206 Klass* scratch_class_oop, TRAPS) {
3440 RC_TIMER_STOP(_timer_rsc_phase1); 3430 RC_TIMER_STOP(_timer_rsc_phase1);
3441 RC_TIMER_START(_timer_rsc_phase2); 3431 RC_TIMER_START(_timer_rsc_phase2);
3442 3432
3443 // Adjust constantpool caches and vtables for all classes 3433 // Adjust constantpool caches and vtables for all classes
3444 // that reference methods of the evolved class. 3434 // that reference methods of the evolved class.
3445 SystemDictionary::classes_do(adjust_cpool_cache_and_vtable, THREAD); 3435 AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD);
3436 ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable);
3446 3437
3447 // JSR-292 support 3438 // JSR-292 support
3448 MemberNameTable* mnt = the_class->member_names(); 3439 MemberNameTable* mnt = the_class->member_names();
3449 if (mnt != NULL) { 3440 if (mnt != NULL) {
3450 bool trace_name_printed = false; 3441 bool trace_name_printed = false;
3501 increment_class_counter(subik, THREAD); 3492 increment_class_counter(subik, THREAD);
3502 } 3493 }
3503 } 3494 }
3504 } 3495 }
3505 3496
3506 void VM_RedefineClasses::check_class(Klass* k_oop, 3497 void VM_RedefineClasses::CheckClass::do_klass(Klass* k) {
3507 ClassLoaderData* initiating_loader, 3498 bool no_old_methods = true; // be optimistic
3508 TRAPS) { 3499
3509 Klass *k = k_oop; 3500 // Both array and instance classes have vtables.
3501 // a vtable should never contain old or obsolete methods
3502 ResourceMark rm(_thread);
3503 if (k->vtable_length() > 0 &&
3504 !k->vtable()->check_no_old_or_obsolete_entries()) {
3505 if (RC_TRACE_ENABLED(0x00004000)) {
3506 RC_TRACE_WITH_THREAD(0x00004000, _thread,
3507 ("klassVtable::check_no_old_or_obsolete_entries failure"
3508 " -- OLD or OBSOLETE method found -- class: %s",
3509 k->signature_name()));
3510 k->vtable()->dump_vtable();
3511 }
3512 no_old_methods = false;
3513 }
3514
3510 if (k->oop_is_instance()) { 3515 if (k->oop_is_instance()) {
3511 HandleMark hm(THREAD); 3516 HandleMark hm(_thread);
3512 InstanceKlass *ik = (InstanceKlass *) k; 3517 InstanceKlass *ik = InstanceKlass::cast(k);
3513 bool no_old_methods = true; // be optimistic
3514 ResourceMark rm(THREAD);
3515
3516 // a vtable should never contain old or obsolete methods
3517 if (ik->vtable_length() > 0 &&
3518 !ik->vtable()->check_no_old_or_obsolete_entries()) {
3519 if (RC_TRACE_ENABLED(0x00004000)) {
3520 RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3521 ("klassVtable::check_no_old_or_obsolete_entries failure"
3522 " -- OLD or OBSOLETE method found -- class: %s",
3523 ik->signature_name()));
3524 ik->vtable()->dump_vtable();
3525 }
3526 no_old_methods = false;
3527 }
3528 3518
3529 // an itable should never contain old or obsolete methods 3519 // an itable should never contain old or obsolete methods
3530 if (ik->itable_length() > 0 && 3520 if (ik->itable_length() > 0 &&
3531 !ik->itable()->check_no_old_or_obsolete_entries()) { 3521 !ik->itable()->check_no_old_or_obsolete_entries()) {
3532 if (RC_TRACE_ENABLED(0x00004000)) { 3522 if (RC_TRACE_ENABLED(0x00004000)) {
3533 RC_TRACE_WITH_THREAD(0x00004000, THREAD, 3523 RC_TRACE_WITH_THREAD(0x00004000, _thread,
3534 ("klassItable::check_no_old_or_obsolete_entries failure" 3524 ("klassItable::check_no_old_or_obsolete_entries failure"
3535 " -- OLD or OBSOLETE method found -- class: %s", 3525 " -- OLD or OBSOLETE method found -- class: %s",
3536 ik->signature_name())); 3526 ik->signature_name()));
3537 ik->itable()->dump_itable(); 3527 ik->itable()->dump_itable();
3538 } 3528 }
3542 // the constant pool cache should never contain old or obsolete methods 3532 // the constant pool cache should never contain old or obsolete methods
3543 if (ik->constants() != NULL && 3533 if (ik->constants() != NULL &&
3544 ik->constants()->cache() != NULL && 3534 ik->constants()->cache() != NULL &&
3545 !ik->constants()->cache()->check_no_old_or_obsolete_entries()) { 3535 !ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
3546 if (RC_TRACE_ENABLED(0x00004000)) { 3536 if (RC_TRACE_ENABLED(0x00004000)) {
3547 RC_TRACE_WITH_THREAD(0x00004000, THREAD, 3537 RC_TRACE_WITH_THREAD(0x00004000, _thread,
3548 ("cp-cache::check_no_old_or_obsolete_entries failure" 3538 ("cp-cache::check_no_old_or_obsolete_entries failure"
3549 " -- OLD or OBSOLETE method found -- class: %s", 3539 " -- OLD or OBSOLETE method found -- class: %s",
3550 ik->signature_name())); 3540 ik->signature_name()));
3551 ik->constants()->cache()->dump_cache(); 3541 ik->constants()->cache()->dump_cache();
3552 } 3542 }
3553 no_old_methods = false; 3543 no_old_methods = false;
3554 } 3544 }
3555 3545 }
3556 if (!no_old_methods) { 3546
3557 if (RC_TRACE_ENABLED(0x00004000)) { 3547 // print and fail guarantee if old methods are found.
3558 dump_methods(); 3548 if (!no_old_methods) {
3559 } else { 3549 if (RC_TRACE_ENABLED(0x00004000)) {
3560 tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option " 3550 dump_methods();
3561 "to see more info about the following guarantee() failure."); 3551 } else {
3562 } 3552 tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
3563 guarantee(false, "OLD and/or OBSOLETE method(s) found"); 3553 "to see more info about the following guarantee() failure.");
3564 } 3554 }
3555 guarantee(false, "OLD and/or OBSOLETE method(s) found");
3565 } 3556 }
3566 } 3557 }
3558
3567 3559
3568 void VM_RedefineClasses::dump_methods() { 3560 void VM_RedefineClasses::dump_methods() {
3569 int j; 3561 int j;
3570 RC_TRACE(0x00004000, ("_old_methods --")); 3562 RC_TRACE(0x00004000, ("_old_methods --"));
3571 for (j = 0; j < _old_methods->length(); ++j) { 3563 for (j = 0; j < _old_methods->length(); ++j) {