提交 c898e069 编写于 作者: S sspitsyn

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
上级 a4f3a135
...@@ -114,6 +114,7 @@ oop Universe::_the_min_jint_string = NULL; ...@@ -114,6 +114,7 @@ oop Universe::_the_min_jint_string = NULL;
LatestMethodCache* Universe::_finalizer_register_cache = NULL; LatestMethodCache* Universe::_finalizer_register_cache = NULL;
LatestMethodCache* Universe::_loader_addClass_cache = NULL; LatestMethodCache* Universe::_loader_addClass_cache = NULL;
LatestMethodCache* Universe::_pd_implies_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_java_heap = NULL;
oop Universe::_out_of_memory_error_metaspace = NULL; oop Universe::_out_of_memory_error_metaspace = NULL;
oop Universe::_out_of_memory_error_class_metaspace = NULL; oop Universe::_out_of_memory_error_class_metaspace = NULL;
...@@ -129,7 +130,6 @@ oop Universe::_virtual_machine_error_instance = NULL; ...@@ -129,7 +130,6 @@ oop Universe::_virtual_machine_error_instance = NULL;
oop Universe::_vm_exception = NULL; oop Universe::_vm_exception = NULL;
oop Universe::_allocation_context_notification_obj = NULL; oop Universe::_allocation_context_notification_obj = NULL;
Method* Universe::_throw_illegal_access_error = NULL;
Array<int>* Universe::_the_empty_int_array = NULL; Array<int>* Universe::_the_empty_int_array = NULL;
Array<u2>* Universe::_the_empty_short_array = NULL; Array<u2>* Universe::_the_empty_short_array = NULL;
Array<Klass*>* Universe::_the_empty_klass_array = NULL; Array<Klass*>* Universe::_the_empty_klass_array = NULL;
...@@ -235,6 +235,7 @@ void Universe::serialize(SerializeClosure* f, bool do_all) { ...@@ -235,6 +235,7 @@ void Universe::serialize(SerializeClosure* f, bool do_all) {
_finalizer_register_cache->serialize(f); _finalizer_register_cache->serialize(f);
_loader_addClass_cache->serialize(f); _loader_addClass_cache->serialize(f);
_pd_implies_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) { void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
...@@ -663,6 +664,7 @@ jint universe_init() { ...@@ -663,6 +664,7 @@ jint universe_init() {
Universe::_finalizer_register_cache = new LatestMethodCache(); Universe::_finalizer_register_cache = new LatestMethodCache();
Universe::_loader_addClass_cache = new LatestMethodCache(); Universe::_loader_addClass_cache = new LatestMethodCache();
Universe::_pd_implies_cache = new LatestMethodCache(); Universe::_pd_implies_cache = new LatestMethodCache();
Universe::_throw_illegal_access_error_cache = new LatestMethodCache();
if (UseSharedSpaces) { if (UseSharedSpaces) {
// Read the data structures supporting the shared spaces (shared // Read the data structures supporting the shared spaces (shared
...@@ -1135,7 +1137,8 @@ bool universe_post_init() { ...@@ -1135,7 +1137,8 @@ bool universe_post_init() {
tty->print_cr("Unable to link/verify Unsafe.throwIllegalAccessError method"); tty->print_cr("Unable to link/verify Unsafe.throwIllegalAccessError method");
return false; // initialization failed (cannot throw exception yet) 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 // Setup method for registering loaded classes in class loader vector
InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false);
...@@ -1161,7 +1164,7 @@ bool universe_post_init() { ...@@ -1161,7 +1164,7 @@ bool universe_post_init() {
return false; // initialization failed return false; // initialization failed
} }
Universe::_pd_implies_cache->init( Universe::_pd_implies_cache->init(
SystemDictionary::ProtectionDomain_klass(), m);; SystemDictionary::ProtectionDomain_klass(), m);
} }
// The folowing is initializing converter functions for serialization in // The folowing is initializing converter functions for serialization in
......
...@@ -148,8 +148,7 @@ class Universe: AllStatic { ...@@ -148,8 +148,7 @@ class Universe: AllStatic {
static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects 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* _loader_addClass_cache; // method for registering loaded classes in class loader vector
static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes
static LatestMethodCache* _throw_illegal_access_error_cache; // Unsafe.throwIllegalAccessError() method
static Method* _throw_illegal_access_error;
// preallocated error objects (no backtrace) // preallocated error objects (no backtrace)
static oop _out_of_memory_error_java_heap; static oop _out_of_memory_error_java_heap;
...@@ -305,6 +304,7 @@ class Universe: AllStatic { ...@@ -305,6 +304,7 @@ class Universe: AllStatic {
static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); } 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* 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 null_ptr_exception_instance() { return _null_ptr_exception_instance; }
static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
...@@ -314,8 +314,6 @@ class Universe: AllStatic { ...@@ -314,8 +314,6 @@ class Universe: AllStatic {
static inline oop allocation_context_notification_obj(); static inline oop allocation_context_notification_obj();
static inline void set_allocation_context_notification_obj(oop obj); static inline void set_allocation_context_notification_obj(oop obj);
static Method* throw_illegal_access_error() { return _throw_illegal_access_error; }
static Array<int>* the_empty_int_array() { return _the_empty_int_array; } static Array<int>* the_empty_int_array() { return _the_empty_int_array; }
static Array<u2>* the_empty_short_array() { return _the_empty_short_array; } static Array<u2>* the_empty_short_array() { return _the_empty_short_array; }
static Array<Method*>* the_empty_method_array() { return _the_empty_method_array; } static Array<Method*>* the_empty_method_array() { return _the_empty_method_array; }
......
...@@ -3378,7 +3378,9 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { ...@@ -3378,7 +3378,9 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
// not yet in the vtable, because the vtable setup is in progress. // not yet in the vtable, because the vtable setup is in progress.
// This must be done after we adjust the default_methods and // This must be done after we adjust the default_methods and
// default_vtable_indices for methods already in the vtable. // 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() 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->is_subtype_of(_the_class_oop))) {
// ik->vtable() creates a wrapper object; rm cleans it up // ik->vtable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread); ResourceMark rm(_thread);
...@@ -3393,7 +3395,9 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { ...@@ -3393,7 +3395,9 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
// interface, then we have to call adjust_method_entries() for // interface, then we have to call adjust_method_entries() for
// every InstanceKlass that has an itable since there isn't a // every InstanceKlass that has an itable since there isn't a
// subclass relationship between an interface and an InstanceKlass. // 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() 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->is_subclass_of(_the_class_oop))) {
// ik->itable() creates a wrapper object; rm cleans it up // ik->itable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread); ResourceMark rm(_thread);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册