# HG changeset patch # User sspitsyn # Date 1422316288 28800 # Node ID a7ef74a8eca24bee42c85da926a309536c66093f # Parent 0fc2c46098403f42024e64e243bbb09f75f59a89 8068162: jvmtiRedefineClasses.cpp: guarantee(false) failed: OLD and/or OBSOLETE method(s) found Summary: adjust Unsafe methods in the itable/vtable if Unsafe is redefined Reviewed-by: coleenp, dcubed Contributed-by: serguei.spitsyn@oracle.com diff -r 0fc2c4609840 -r a7ef74a8eca2 hotspot/src/share/vm/memory/universe.cpp --- a/hotspot/src/share/vm/memory/universe.cpp Mon Jan 12 09:16:06 2015 +0100 +++ b/hotspot/src/share/vm/memory/universe.cpp Mon Jan 26 15:51:28 2015 -0800 @@ -115,6 +115,7 @@ LatestMethodCache* Universe::_finalizer_register_cache = NULL; LatestMethodCache* Universe::_loader_addClass_cache = NULL; LatestMethodCache* Universe::_pd_implies_cache = NULL; +LatestMethodCache* Universe::_throw_illegal_access_error_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; oop Universe::_out_of_memory_error_metaspace = NULL; oop Universe::_out_of_memory_error_class_metaspace = NULL; @@ -130,7 +131,6 @@ oop Universe::_vm_exception = NULL; oop Universe::_allocation_context_notification_obj = NULL; -Method* Universe::_throw_illegal_access_error = NULL; Array* Universe::_the_empty_int_array = NULL; Array* Universe::_the_empty_short_array = NULL; Array* Universe::_the_empty_klass_array = NULL; @@ -236,6 +236,7 @@ _finalizer_register_cache->serialize(f); _loader_addClass_cache->serialize(f); _pd_implies_cache->serialize(f); + _throw_illegal_access_error_cache->serialize(f); } void Universe::check_alignment(uintx size, uintx alignment, const char* name) { @@ -664,6 +665,7 @@ Universe::_finalizer_register_cache = new LatestMethodCache(); Universe::_loader_addClass_cache = new LatestMethodCache(); Universe::_pd_implies_cache = new LatestMethodCache(); + Universe::_throw_illegal_access_error_cache = new LatestMethodCache(); if (UseSharedSpaces) { // Read the data structures supporting the shared spaces (shared @@ -1016,7 +1018,8 @@ tty->print_cr("Unable to link/verify Unsafe.throwIllegalAccessError method"); return false; // initialization failed (cannot throw exception yet) } - Universe::_throw_illegal_access_error = m; + Universe::_throw_illegal_access_error_cache->init( + SystemDictionary::misc_Unsafe_klass(), m); // Setup method for registering loaded classes in class loader vector InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); @@ -1042,7 +1045,7 @@ return false; // initialization failed } Universe::_pd_implies_cache->init( - SystemDictionary::ProtectionDomain_klass(), m);; + SystemDictionary::ProtectionDomain_klass(), m); } // This needs to be done before the first scavenge/gc, since diff -r 0fc2c4609840 -r a7ef74a8eca2 hotspot/src/share/vm/memory/universe.hpp --- a/hotspot/src/share/vm/memory/universe.hpp Mon Jan 12 09:16:06 2015 +0100 +++ b/hotspot/src/share/vm/memory/universe.hpp Mon Jan 26 15:51:28 2015 -0800 @@ -148,8 +148,7 @@ static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes - - static Method* _throw_illegal_access_error; + static LatestMethodCache* _throw_illegal_access_error_cache; // Unsafe.throwIllegalAccessError() method // preallocated error objects (no backtrace) static oop _out_of_memory_error_java_heap; @@ -305,6 +304,7 @@ static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); } static Method* protection_domain_implies_method() { return _pd_implies_cache->get_method(); } + static Method* throw_illegal_access_error() { return _throw_illegal_access_error_cache->get_method(); } static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; } static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } @@ -314,8 +314,6 @@ static inline oop allocation_context_notification_obj(); static inline void set_allocation_context_notification_obj(oop obj); - static Method* throw_illegal_access_error() { return _throw_illegal_access_error; } - static Array* the_empty_int_array() { return _the_empty_int_array; } static Array* the_empty_short_array() { return _the_empty_short_array; } static Array* the_empty_method_array() { return _the_empty_method_array; } diff -r 0fc2c4609840 -r a7ef74a8eca2 hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Jan 12 09:16:06 2015 +0100 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Jan 26 15:51:28 2015 -0800 @@ -3376,7 +3376,9 @@ // not yet in the vtable, because the vtable setup is in progress. // This must be done after we adjust the default_methods and // default_vtable_indices for methods already in the vtable. + // If redefining Unsafe, walk all the vtables looking for entries. 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); @@ -3396,7 +3398,9 @@ // interface, then we have to call adjust_method_entries() for // every InstanceKlass that has an itable since there isn't a // subclass relationship between an interface and an InstanceKlass. + // If redefining Unsafe, walk all the itables looking for entries. 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);