Mercurial > hg > graal-jvmci-8
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 |