src/share/vm/code/nmethod.cpp

Print this page

        

*** 1294,1307 **** print_on(tty, _state == zombie ? "made zombie" : "made not entrant"); } } // Common functionality for both make_not_entrant and make_zombie ! bool nmethod::make_not_entrant_or_zombie(unsigned int state) { ! assert(state == zombie || state == not_entrant, "must be zombie or not_entrant"); assert(!is_zombie(), "should not already be a zombie"); // Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below. nmethodLocker nml(this); methodHandle the_method(method()); No_Safepoint_Verifier nsv; --- 1294,1314 ---- print_on(tty, _state == zombie ? "made zombie" : "made not entrant"); } } // Common functionality for both make_not_entrant and make_zombie ! bool nmethod::make_not_entrant_or_zombie(unsigned int new_state) { ! assert(new_state == zombie || new_state == not_entrant, "must become zombie or not_entrant"); assert(!is_zombie(), "should not already be a zombie"); + // The state of nmethods that are currently locked by the VM must not change. + // Some operations such as setting ICs (e.g., SharedRuntime::resolve_sub_helper()) + // rely on this fact. + if (is_locked_by_vm()) { + return false; + } + // Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below. nmethodLocker nml(this); methodHandle the_method(method()); No_Safepoint_Verifier nsv;
*** 1323,1336 **** } // Enter critical section. Does not block for safepoint. MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); ! if (_state == state) { // another thread already performed this transition so nothing ! // to do, but return false to indicate this. ! return false; } // The caller can be calling the method statically or through an inline // cache call. if (!is_osr_method() && !is_not_entrant()) { --- 1330,1343 ---- } // Enter critical section. Does not block for safepoint. MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); ! if (_state == new_state) { // another thread already performed this transition so nothing ! // to do, but return true to indicate this. ! return true; } // The caller can be calling the method statically or through an inline // cache call. if (!is_osr_method() && !is_not_entrant()) {
*** 1345,1360 **** } // If the state is becoming a zombie, signal to unregister the nmethod with // the heap. // This nmethod may have already been unloaded during a full GC. ! if ((state == zombie) && !is_unloaded()) { nmethod_needs_unregister = true; } // Change state ! _state = state; // Log the transition once log_state_change(); // Remove nmethod from method. --- 1352,1367 ---- } // If the state is becoming a zombie, signal to unregister the nmethod with // the heap. // This nmethod may have already been unloaded during a full GC. ! if ((new_state == zombie) && !is_unloaded()) { nmethod_needs_unregister = true; } // Change state ! _state = new_state; // Log the transition once log_state_change(); // Remove nmethod from method.
*** 1368,1388 **** method()->from_compiled_entry() == verified_entry_point())) { HandleMark hm; method()->clear_code(); } ! if (state == not_entrant) { mark_as_seen_on_stack(); } } // leave critical region under Patching_lock // When the nmethod becomes zombie it is no longer alive so the // dependencies must be flushed. nmethods in the not_entrant // state will be flushed later when the transition to zombie // happens or they get unloaded. ! if (state == zombie) { { // Flushing dependecies must be done before any possible // safepoint can sneak in, otherwise the oops used by the // dependency logic could have become stale. MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); --- 1375,1395 ---- method()->from_compiled_entry() == verified_entry_point())) { HandleMark hm; method()->clear_code(); } ! if (new_state == not_entrant) { mark_as_seen_on_stack(); } } // leave critical region under Patching_lock // When the nmethod becomes zombie it is no longer alive so the // dependencies must be flushed. nmethods in the not_entrant // state will be flushed later when the transition to zombie // happens or they get unloaded. ! if (new_state == zombie) { { // Flushing dependecies must be done before any possible // safepoint can sneak in, otherwise the oops used by the // dependency logic could have become stale. MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
*** 1406,1425 **** #endif // the Method may be reclaimed by class unloading now that the // nmethod is in zombie state set_method(NULL); } else { ! assert(state == not_entrant, "other cases may need to be handled differently"); } if (TraceCreateZombies) { ! tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie"); } // Make sweeper aware that there is a zombie method that needs to be removed NMethodSweeper::notify(this); - return true; } void nmethod::flush() { // Note that there are no valid oops in the nmethod anymore. --- 1413,1431 ---- #endif // the Method may be reclaimed by class unloading now that the // nmethod is in zombie state set_method(NULL); } else { ! assert(new_state == not_entrant, "other cases may need to be handled differently"); } if (TraceCreateZombies) { ! tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (new_state == not_entrant) ? "not entrant" : "zombie"); } // Make sweeper aware that there is a zombie method that needs to be removed NMethodSweeper::notify(this); return true; } void nmethod::flush() { // Note that there are no valid oops in the nmethod anymore.