Mon, 06 Feb 2017 23:36:58 +0300
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
1.1 --- a/src/share/vm/classfile/classLoader.cpp Thu Feb 02 00:29:28 2017 +0000 1.2 +++ b/src/share/vm/classfile/classLoader.cpp Mon Feb 06 23:36:58 2017 +0300 1.3 @@ -1627,7 +1627,6 @@ 1.4 if (nm != NULL && !m->is_method_handle_intrinsic()) { 1.5 // Throw out the code so that the code cache doesn't fill up 1.6 nm->make_not_entrant(); 1.7 - m->clear_code(); 1.8 } 1.9 CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization, 1.10 methodHandle(), 0, "CTW", THREAD); 1.11 @@ -1646,7 +1645,6 @@ 1.12 if (nm != NULL && !m->is_method_handle_intrinsic()) { 1.13 // Throw out the code so that the code cache doesn't fill up 1.14 nm->make_not_entrant(); 1.15 - m->clear_code(); 1.16 } 1.17 } 1.18 }
2.1 --- a/src/share/vm/code/nmethod.cpp Thu Feb 02 00:29:28 2017 +0000 2.2 +++ b/src/share/vm/code/nmethod.cpp Mon Feb 06 23:36:58 2017 +0300 2.3 @@ -1506,7 +1506,7 @@ 2.4 if (method() != NULL && (method()->code() == this || 2.5 method()->from_compiled_entry() == verified_entry_point())) { 2.6 HandleMark hm; 2.7 - method()->clear_code(); 2.8 + method()->clear_code(false /* already owns Patching_lock */); 2.9 } 2.10 } // leave critical region under Patching_lock 2.11
3.1 --- a/src/share/vm/oops/method.cpp Thu Feb 02 00:29:28 2017 +0000 3.2 +++ b/src/share/vm/oops/method.cpp Mon Feb 06 23:36:58 2017 +0300 3.3 @@ -98,7 +98,7 @@ 3.4 // Fix and bury in Method* 3.5 set_interpreter_entry(NULL); // sets i2i entry and from_int 3.6 set_adapter_entry(NULL); 3.7 - clear_code(); // from_c/from_i get set to c2i/i2i 3.8 + clear_code(false /* don't need a lock */); // from_c/from_i get set to c2i/i2i 3.9 3.10 if (access_flags.is_native()) { 3.11 clear_native_function(); 3.12 @@ -846,8 +846,8 @@ 3.13 } 3.14 3.15 // Revert to using the interpreter and clear out the nmethod 3.16 -void Method::clear_code() { 3.17 - 3.18 +void Method::clear_code(bool acquire_lock /* = true */) { 3.19 + MutexLockerEx pl(acquire_lock ? Patching_lock : NULL, Mutex::_no_safepoint_check_flag); 3.20 // this may be NULL if c2i adapters have not been made yet 3.21 // Only should happen at allocate time. 3.22 if (_adapter == NULL) { 3.23 @@ -975,6 +975,7 @@ 3.24 3.25 // Install compiled code. Instantly it can execute. 3.26 void Method::set_code(methodHandle mh, nmethod *code) { 3.27 + MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); 3.28 assert( code, "use clear_code to remove code" ); 3.29 assert( mh->check_code(), "" ); 3.30
4.1 --- a/src/share/vm/oops/method.hpp Thu Feb 02 00:29:28 2017 +0000 4.2 +++ b/src/share/vm/oops/method.hpp Mon Feb 06 23:36:58 2017 +0300 4.3 @@ -445,7 +445,7 @@ 4.4 address verified_code_entry(); 4.5 bool check_code() const; // Not inline to avoid circular ref 4.6 nmethod* volatile code() const { assert( check_code(), "" ); return (nmethod *)OrderAccess::load_ptr_acquire(&_code); } 4.7 - void clear_code(); // Clear out any compiled code 4.8 + void clear_code(bool acquire_lock = true); // Clear out any compiled code 4.9 static void set_code(methodHandle mh, nmethod* code); 4.10 void set_adapter_entry(AdapterHandlerEntry* adapter) { _adapter = adapter; } 4.11 address get_i2c_entry();