src/share/vm/prims/jvmtiRedefineClasses.cpp
Print this page
*** 779,791 ****
--- 779,795 ----
u2 old_num = k_old_method->method_idnum();
if (new_num != old_num) {
Method* idnum_owner = scratch_class->method_with_idnum(old_num);
if (idnum_owner != NULL) {
// There is already a method assigned this idnum -- switch them
+ // Take current and original idnum from the new_method
idnum_owner->set_method_idnum(new_num);
+ idnum_owner->set_orig_method_idnum(k_new_method->orig_method_idnum());
}
+ // Take current and original idnum from the old_method
k_new_method->set_method_idnum(old_num);
+ k_new_method->set_orig_method_idnum(k_old_method->orig_method_idnum());
if (thread->has_pending_exception()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
}
}
}
*** 814,826 ****
--- 818,833 ----
}
u2 new_num = k_new_method->method_idnum();
Method* idnum_owner = scratch_class->method_with_idnum(num);
if (idnum_owner != NULL) {
// There is already a method assigned this idnum -- switch them
+ // Take current and original idnum from the new_method
idnum_owner->set_method_idnum(new_num);
+ idnum_owner->set_orig_method_idnum(k_new_method->orig_method_idnum());
}
k_new_method->set_method_idnum(num);
+ k_new_method->set_orig_method_idnum(num);
if (thread->has_pending_exception()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
}
}
RC_TRACE(0x00008000, ("Method added: new: %s [%d]",
*** 3324,3333 ****
--- 3331,3341 ----
void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
// This is a very busy routine. We don't want too much tracing
// printed out.
bool trace_name_printed = false;
+ InstanceKlass *the_class = InstanceKlass::cast(_the_class_oop);
// Very noisy: only enable this call if you are trying to determine
// that a specific class gets found by this routine.
// RC_TRACE macro has an embedded ResourceMark
// RC_TRACE_WITH_THREAD(0x00100000, THREAD,
*** 3335,3348 ****
// trace_name_printed = true;
// If the class being redefined is java.lang.Object, we need to fix all
// array class vtables also
if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) {
! k->vtable()->adjust_method_entries(_matching_old_methods,
! _matching_new_methods,
! _matching_methods_length,
! &trace_name_printed);
} else if (k->oop_is_instance()) {
HandleMark hm(_thread);
InstanceKlass *ik = InstanceKlass::cast(k);
// HotSpot specific optimization! HotSpot does not currently
--- 3343,3354 ----
// trace_name_printed = true;
// If the class being redefined is java.lang.Object, we need to fix all
// array class vtables also
if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) {
! k->vtable()->adjust_method_entries(the_class, &trace_name_printed);
!
} else if (k->oop_is_instance()) {
HandleMark hm(_thread);
InstanceKlass *ik = InstanceKlass::cast(k);
// HotSpot specific optimization! HotSpot does not currently
*** 3380,3397 ****
if (ik->vtable_length() > 0 && (_the_class_oop->is_interface()
|| _the_class_oop == SystemDictionary::misc_Unsafe_klass()
|| ik->is_subtype_of(_the_class_oop))) {
// ik->vtable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread);
! ik->vtable()->adjust_method_entries(_matching_old_methods,
! _matching_new_methods,
! _matching_methods_length,
! &trace_name_printed);
! ik->adjust_default_methods(_matching_old_methods,
! _matching_new_methods,
! _matching_methods_length,
! &trace_name_printed);
}
// If the current class has an itable and we are either redefining an
// interface or if the current class is a subclass of the_class, then
// we potentially have to fix the itable. If we are redefining an
--- 3386,3398 ----
if (ik->vtable_length() > 0 && (_the_class_oop->is_interface()
|| _the_class_oop == SystemDictionary::misc_Unsafe_klass()
|| ik->is_subtype_of(_the_class_oop))) {
// ik->vtable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread);
!
! ik->vtable()->adjust_method_entries(the_class, &trace_name_printed);
! ik->adjust_default_methods(the_class, &trace_name_printed);
}
// If the current class has an itable and we are either redefining an
// interface or if the current class is a subclass of the_class, then
// we potentially have to fix the itable. If we are redefining an
*** 3402,3415 ****
if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
|| _the_class_oop == SystemDictionary::misc_Unsafe_klass()
|| ik->is_subclass_of(_the_class_oop))) {
// ik->itable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread);
! ik->itable()->adjust_method_entries(_matching_old_methods,
! _matching_new_methods,
! _matching_methods_length,
! &trace_name_printed);
}
// The constant pools in other classes (other_cp) can refer to
// methods in the_class. We have to update method information in
// other_cp's cache. If other_cp has a previous version, then we
--- 3403,3414 ----
if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
|| _the_class_oop == SystemDictionary::misc_Unsafe_klass()
|| ik->is_subclass_of(_the_class_oop))) {
// ik->itable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread);
!
! ik->itable()->adjust_method_entries(the_class, &trace_name_printed);
}
// The constant pools in other classes (other_cp) can refer to
// methods in the_class. We have to update method information in
// other_cp's cache. If other_cp has a previous version, then we
*** 3429,3442 ****
if (ik != _the_class_oop) {
// this klass' constant pool cache may need adjustment
other_cp = constantPoolHandle(ik->constants());
cp_cache = other_cp->cache();
if (cp_cache != NULL) {
! cp_cache->adjust_method_entries(_matching_old_methods,
! _matching_new_methods,
! _matching_methods_length,
! &trace_name_printed);
}
}
// the previous versions' constant pool caches may need adjustment
for (InstanceKlass* pv_node = ik->previous_versions();
--- 3428,3438 ----
if (ik != _the_class_oop) {
// this klass' constant pool cache may need adjustment
other_cp = constantPoolHandle(ik->constants());
cp_cache = other_cp->cache();
if (cp_cache != NULL) {
! cp_cache->adjust_method_entries(the_class, &trace_name_printed);
}
}
// the previous versions' constant pool caches may need adjustment
for (InstanceKlass* pv_node = ik->previous_versions();
*** 3575,3584 ****
--- 3571,3581 ----
old_method->set_is_obsolete();
obsolete_count++;
// obsolete methods need a unique idnum so they become new entries in
// the jmethodID cache in InstanceKlass
+ assert(old_method->method_idnum() == new_method->method_idnum(), "must match");
u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum();
if (num != ConstMethod::UNSET_IDNUM) {
old_method->set_method_idnum(num);
}