8153134: Infinite loop in handle_wrong_method in jmod jdk8u152-b01

Mon, 06 Feb 2017 23:36:58 +0300

author
vkempik
date
Mon, 06 Feb 2017 23:36:58 +0300
changeset 8717
77d9c9da7188
parent 8716
619700f41f8e
child 8718
e765322578aa
child 8719
f89cf87d867d

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

src/share/vm/classfile/classLoader.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/nmethod.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/method.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/method.hpp file | annotate | diff | comparison | revisions
     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();

mercurial