Mercurial > hg > icedtea8-forest > hotspot
changeset 9636:77d9c9da7188 jdk8u152-b01
8153134: Infinite loop in handle_wrong_method in jmod
Summary: Use Patching_lock to synchronize access between set_code() and clear_code().
Reviewed-by: kvn, dlong
author | vkempik |
---|---|
date | Mon, 06 Feb 2017 23:36:58 +0300 |
parents | 619700f41f8e |
children | e765322578aa f89cf87d867d |
files | src/share/vm/classfile/classLoader.cpp src/share/vm/code/nmethod.cpp src/share/vm/oops/method.cpp src/share/vm/oops/method.hpp |
diffstat | 4 files changed, 6 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/classfile/classLoader.cpp Thu Feb 02 00:29:28 2017 +0000 +++ b/src/share/vm/classfile/classLoader.cpp Mon Feb 06 23:36:58 2017 +0300 @@ -1627,7 +1627,6 @@ if (nm != NULL && !m->is_method_handle_intrinsic()) { // Throw out the code so that the code cache doesn't fill up nm->make_not_entrant(); - m->clear_code(); } CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization, methodHandle(), 0, "CTW", THREAD); @@ -1646,7 +1645,6 @@ if (nm != NULL && !m->is_method_handle_intrinsic()) { // Throw out the code so that the code cache doesn't fill up nm->make_not_entrant(); - m->clear_code(); } } }
--- a/src/share/vm/code/nmethod.cpp Thu Feb 02 00:29:28 2017 +0000 +++ b/src/share/vm/code/nmethod.cpp Mon Feb 06 23:36:58 2017 +0300 @@ -1506,7 +1506,7 @@ if (method() != NULL && (method()->code() == this || method()->from_compiled_entry() == verified_entry_point())) { HandleMark hm; - method()->clear_code(); + method()->clear_code(false /* already owns Patching_lock */); } } // leave critical region under Patching_lock
--- a/src/share/vm/oops/method.cpp Thu Feb 02 00:29:28 2017 +0000 +++ b/src/share/vm/oops/method.cpp Mon Feb 06 23:36:58 2017 +0300 @@ -98,7 +98,7 @@ // Fix and bury in Method* set_interpreter_entry(NULL); // sets i2i entry and from_int set_adapter_entry(NULL); - clear_code(); // from_c/from_i get set to c2i/i2i + clear_code(false /* don't need a lock */); // from_c/from_i get set to c2i/i2i if (access_flags.is_native()) { clear_native_function(); @@ -846,8 +846,8 @@ } // Revert to using the interpreter and clear out the nmethod -void Method::clear_code() { - +void Method::clear_code(bool acquire_lock /* = true */) { + MutexLockerEx pl(acquire_lock ? Patching_lock : NULL, Mutex::_no_safepoint_check_flag); // this may be NULL if c2i adapters have not been made yet // Only should happen at allocate time. if (_adapter == NULL) { @@ -975,6 +975,7 @@ // Install compiled code. Instantly it can execute. void Method::set_code(methodHandle mh, nmethod *code) { + MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); assert( code, "use clear_code to remove code" ); assert( mh->check_code(), "" );
--- a/src/share/vm/oops/method.hpp Thu Feb 02 00:29:28 2017 +0000 +++ b/src/share/vm/oops/method.hpp Mon Feb 06 23:36:58 2017 +0300 @@ -445,7 +445,7 @@ address verified_code_entry(); bool check_code() const; // Not inline to avoid circular ref nmethod* volatile code() const { assert( check_code(), "" ); return (nmethod *)OrderAccess::load_ptr_acquire(&_code); } - void clear_code(); // Clear out any compiled code + void clear_code(bool acquire_lock = true); // Clear out any compiled code static void set_code(methodHandle mh, nmethod* code); void set_adapter_entry(AdapterHandlerEntry* adapter) { _adapter = adapter; } address get_i2c_entry();