comparison src/share/vm/prims/jvmtiRedefineClasses.cpp @ 22886:fdde6a70ea85

8046246: the constantPoolCacheOopDesc::adjust_method_entries() used in RedefineClasses does not scale Summary: optimize the adjust_method_entries functions by using the orig_method_idnum() function Reviewed-by: coleenp, dcubed
author sspitsyn
date Tue, 17 Mar 2015 17:11:14 -0700
parents 367427923e39
children 5b2cd065dfc6
comparison
equal deleted inserted replaced
22885:367427923e39 22886:fdde6a70ea85
775 u2 old_num = k_old_method->method_idnum(); 775 u2 old_num = k_old_method->method_idnum();
776 if (new_num != old_num) { 776 if (new_num != old_num) {
777 Method* idnum_owner = scratch_class->method_with_idnum(old_num); 777 Method* idnum_owner = scratch_class->method_with_idnum(old_num);
778 if (idnum_owner != NULL) { 778 if (idnum_owner != NULL) {
779 // There is already a method assigned this idnum -- switch them 779 // There is already a method assigned this idnum -- switch them
780 // Take current and original idnum from the new_method
780 idnum_owner->set_method_idnum(new_num); 781 idnum_owner->set_method_idnum(new_num);
782 idnum_owner->set_orig_method_idnum(k_new_method->orig_method_idnum());
781 } 783 }
784 // Take current and original idnum from the old_method
782 k_new_method->set_method_idnum(old_num); 785 k_new_method->set_method_idnum(old_num);
786 k_new_method->set_orig_method_idnum(k_old_method->orig_method_idnum());
783 if (thread->has_pending_exception()) { 787 if (thread->has_pending_exception()) {
784 return JVMTI_ERROR_OUT_OF_MEMORY; 788 return JVMTI_ERROR_OUT_OF_MEMORY;
785 } 789 }
786 } 790 }
787 } 791 }
810 } 814 }
811 u2 new_num = k_new_method->method_idnum(); 815 u2 new_num = k_new_method->method_idnum();
812 Method* idnum_owner = scratch_class->method_with_idnum(num); 816 Method* idnum_owner = scratch_class->method_with_idnum(num);
813 if (idnum_owner != NULL) { 817 if (idnum_owner != NULL) {
814 // There is already a method assigned this idnum -- switch them 818 // There is already a method assigned this idnum -- switch them
819 // Take current and original idnum from the new_method
815 idnum_owner->set_method_idnum(new_num); 820 idnum_owner->set_method_idnum(new_num);
821 idnum_owner->set_orig_method_idnum(k_new_method->orig_method_idnum());
816 } 822 }
817 k_new_method->set_method_idnum(num); 823 k_new_method->set_method_idnum(num);
824 k_new_method->set_orig_method_idnum(num);
818 if (thread->has_pending_exception()) { 825 if (thread->has_pending_exception()) {
819 return JVMTI_ERROR_OUT_OF_MEMORY; 826 return JVMTI_ERROR_OUT_OF_MEMORY;
820 } 827 }
821 } 828 }
822 RC_TRACE(0x00008000, ("Method added: new: %s [%d]", 829 RC_TRACE(0x00008000, ("Method added: new: %s [%d]",
3320 void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { 3327 void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
3321 3328
3322 // This is a very busy routine. We don't want too much tracing 3329 // This is a very busy routine. We don't want too much tracing
3323 // printed out. 3330 // printed out.
3324 bool trace_name_printed = false; 3331 bool trace_name_printed = false;
3332 InstanceKlass *the_class = InstanceKlass::cast(_the_class_oop);
3325 3333
3326 // Very noisy: only enable this call if you are trying to determine 3334 // Very noisy: only enable this call if you are trying to determine
3327 // that a specific class gets found by this routine. 3335 // that a specific class gets found by this routine.
3328 // RC_TRACE macro has an embedded ResourceMark 3336 // RC_TRACE macro has an embedded ResourceMark
3329 // RC_TRACE_WITH_THREAD(0x00100000, THREAD, 3337 // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
3331 // trace_name_printed = true; 3339 // trace_name_printed = true;
3332 3340
3333 // If the class being redefined is java.lang.Object, we need to fix all 3341 // If the class being redefined is java.lang.Object, we need to fix all
3334 // array class vtables also 3342 // array class vtables also
3335 if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) { 3343 if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) {
3336 k->vtable()->adjust_method_entries(_matching_old_methods, 3344 k->vtable()->adjust_method_entries(the_class, &trace_name_printed);
3337 _matching_new_methods, 3345
3338 _matching_methods_length,
3339 &trace_name_printed);
3340 } else if (k->oop_is_instance()) { 3346 } else if (k->oop_is_instance()) {
3341 HandleMark hm(_thread); 3347 HandleMark hm(_thread);
3342 InstanceKlass *ik = InstanceKlass::cast(k); 3348 InstanceKlass *ik = InstanceKlass::cast(k);
3343 3349
3344 // HotSpot specific optimization! HotSpot does not currently 3350 // HotSpot specific optimization! HotSpot does not currently
3374 // default_vtable_indices for methods already in the vtable. 3380 // default_vtable_indices for methods already in the vtable.
3375 if (ik->vtable_length() > 0 && (_the_class_oop->is_interface() 3381 if (ik->vtable_length() > 0 && (_the_class_oop->is_interface()
3376 || ik->is_subtype_of(_the_class_oop))) { 3382 || ik->is_subtype_of(_the_class_oop))) {
3377 // ik->vtable() creates a wrapper object; rm cleans it up 3383 // ik->vtable() creates a wrapper object; rm cleans it up
3378 ResourceMark rm(_thread); 3384 ResourceMark rm(_thread);
3379 ik->vtable()->adjust_method_entries(_matching_old_methods, 3385
3380 _matching_new_methods, 3386 ik->vtable()->adjust_method_entries(the_class, &trace_name_printed);
3381 _matching_methods_length, 3387 ik->adjust_default_methods(the_class, &trace_name_printed);
3382 &trace_name_printed);
3383 ik->adjust_default_methods(_matching_old_methods,
3384 _matching_new_methods,
3385 _matching_methods_length,
3386 &trace_name_printed);
3387 } 3388 }
3388 3389
3389 // If the current class has an itable and we are either redefining an 3390 // If the current class has an itable and we are either redefining an
3390 // interface or if the current class is a subclass of the_class, then 3391 // interface or if the current class is a subclass of the_class, then
3391 // we potentially have to fix the itable. If we are redefining an 3392 // we potentially have to fix the itable. If we are redefining an
3394 // subclass relationship between an interface and an InstanceKlass. 3395 // subclass relationship between an interface and an InstanceKlass.
3395 if (ik->itable_length() > 0 && (_the_class_oop->is_interface() 3396 if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
3396 || ik->is_subclass_of(_the_class_oop))) { 3397 || ik->is_subclass_of(_the_class_oop))) {
3397 // ik->itable() creates a wrapper object; rm cleans it up 3398 // ik->itable() creates a wrapper object; rm cleans it up
3398 ResourceMark rm(_thread); 3399 ResourceMark rm(_thread);
3399 ik->itable()->adjust_method_entries(_matching_old_methods, 3400
3400 _matching_new_methods, 3401 ik->itable()->adjust_method_entries(the_class, &trace_name_printed);
3401 _matching_methods_length,
3402 &trace_name_printed);
3403 } 3402 }
3404 3403
3405 // The constant pools in other classes (other_cp) can refer to 3404 // The constant pools in other classes (other_cp) can refer to
3406 // methods in the_class. We have to update method information in 3405 // methods in the_class. We have to update method information in
3407 // other_cp's cache. If other_cp has a previous version, then we 3406 // other_cp's cache. If other_cp has a previous version, then we
3421 if (ik != _the_class_oop) { 3420 if (ik != _the_class_oop) {
3422 // this klass' constant pool cache may need adjustment 3421 // this klass' constant pool cache may need adjustment
3423 other_cp = constantPoolHandle(ik->constants()); 3422 other_cp = constantPoolHandle(ik->constants());
3424 cp_cache = other_cp->cache(); 3423 cp_cache = other_cp->cache();
3425 if (cp_cache != NULL) { 3424 if (cp_cache != NULL) {
3426 cp_cache->adjust_method_entries(_matching_old_methods, 3425 cp_cache->adjust_method_entries(the_class, &trace_name_printed);
3427 _matching_new_methods,
3428 _matching_methods_length,
3429 &trace_name_printed);
3430 } 3426 }
3431 } 3427 }
3432 3428
3433 // the previous versions' constant pool caches may need adjustment 3429 // the previous versions' constant pool caches may need adjustment
3434 PreviousVersionWalker pvw(_thread, ik); 3430 PreviousVersionWalker pvw(_thread, ik);
3553 old_method->set_is_obsolete(); 3549 old_method->set_is_obsolete();
3554 obsolete_count++; 3550 obsolete_count++;
3555 3551
3556 // obsolete methods need a unique idnum so they become new entries in 3552 // obsolete methods need a unique idnum so they become new entries in
3557 // the jmethodID cache in InstanceKlass 3553 // the jmethodID cache in InstanceKlass
3554 assert(old_method->method_idnum() == new_method->method_idnum(), "must match");
3558 u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum(); 3555 u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum();
3559 if (num != ConstMethod::UNSET_IDNUM) { 3556 if (num != ConstMethod::UNSET_IDNUM) {
3560 old_method->set_method_idnum(num); 3557 old_method->set_method_idnum(num);
3561 } 3558 }
3562 3559