src/share/vm/code/nmethod.cpp
Print this page
@@ -460,11 +460,10 @@
// Fill in default values for various flag fields
void nmethod::init_defaults() {
_state = alive;
_marked_for_reclamation = 0;
_has_flushed_dependencies = 0;
- _speculatively_disconnected = 0;
_has_unsafe_access = 0;
_has_method_handle_invokes = 0;
_lazy_critical_native = 0;
_has_wide_vectors = 0;
_marked_for_deoptimization = 0;
@@ -479,11 +478,10 @@
_oops_do_mark_link = NULL;
_jmethod_id = NULL;
_osr_link = NULL;
_scavenge_root_link = NULL;
_scavenge_root_state = 0;
- _saved_nmethod_link = NULL;
_compiler = NULL;
#ifdef HAVE_DTRACE_H
_trap_offset = 0;
#endif // def HAVE_DTRACE_H
@@ -684,10 +682,11 @@
_entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
_verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry);
_osr_entry_point = NULL;
_exception_cache = NULL;
_pc_desc_cache.reset_to(NULL);
+ _hotness_counter = NMethodSweeper::hotness_counter_reset_val();
code_buffer->copy_values_to(this);
if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
CodeCache::add_scavenge_root_nmethod(this);
Universe::heap()->register_nmethod(this);
@@ -768,10 +767,11 @@
_entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
_verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry);
_osr_entry_point = NULL;
_exception_cache = NULL;
_pc_desc_cache.reset_to(NULL);
+ _hotness_counter = NMethodSweeper::hotness_counter_reset_val();
code_buffer->copy_values_to(this);
debug_only(verify_scavenge_root_oops());
CodeCache::commit(this);
}
@@ -840,10 +840,11 @@
_entry_bci = entry_bci;
_compile_id = compile_id;
_comp_level = comp_level;
_compiler = compiler;
_orig_pc_offset = orig_pc_offset;
+ _hotness_counter = NMethodSweeper::hotness_counter_reset_val();
// Section offsets
_consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts());
_stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs());
@@ -1259,11 +1260,11 @@
// The Method* is gone at this point
assert(_method == NULL, "Tautology");
set_osr_link(NULL);
//set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
- NMethodSweeper::notify(this);
+ NMethodSweeper::notify();
}
void nmethod::invalidate_osr_method() {
assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
// Remove from list of active nmethods
@@ -1349,10 +1350,18 @@
// This nmethod may have already been unloaded during a full GC.
if ((state == zombie) && !is_unloaded()) {
nmethod_needs_unregister = true;
}
+ // Must happen before state change. Otherwise we have a race condition in
+ // nmethod::can_not_entrant_be_converted(). I.e., a method can immediately
+ // transition its state from 'not_entrant' to 'zombie' without having to wait
+ // for stack scanning.
+ if (state == not_entrant) {
+ mark_as_seen_on_stack();
+ }
+
// Change state
_state = state;
// Log the transition once
log_state_change();
@@ -1367,15 +1376,10 @@
if (method() != NULL && (method()->code() == this ||
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
@@ -1414,11 +1418,11 @@
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);
+ NMethodSweeper::notify();
return true;
}
void nmethod::flush() {
@@ -1449,14 +1453,10 @@
if (on_scavenge_root_list()) {
CodeCache::drop_scavenge_root_nmethod(this);
}
- if (is_speculatively_disconnected()) {
- CodeCache::remove_saved_code(this);
- }
-
#ifdef SHARK
((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
#endif // SHARK
((CodeBlob*)(this))->flush();