--- a/hotspot/src/share/vm/code/nmethod.cpp Wed Oct 16 10:52:41 2013 +0200
+++ b/hotspot/src/share/vm/code/nmethod.cpp Tue Nov 05 17:38:04 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -93,18 +93,21 @@
#endif
bool nmethod::is_compiled_by_c1() const {
- if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing
- if (is_native_method()) return false;
+ if (compiler() == NULL) {
+ return false;
+ }
return compiler()->is_c1();
}
bool nmethod::is_compiled_by_c2() const {
- if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing
- if (is_native_method()) return false;
+ if (compiler() == NULL) {
+ return false;
+ }
return compiler()->is_c2();
}
bool nmethod::is_compiled_by_shark() const {
- if (is_native_method()) return false;
- assert(compiler() != NULL, "must be");
+ if (compiler() == NULL) {
+ return false;
+ }
return compiler()->is_shark();
}
@@ -459,7 +462,6 @@
_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;
@@ -478,7 +480,6 @@
_osr_link = NULL;
_scavenge_root_link = NULL;
_scavenge_root_state = 0;
- _saved_nmethod_link = NULL;
_compiler = NULL;
#ifdef HAVE_DTRACE_H
@@ -683,6 +684,7 @@
_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()) {
@@ -767,6 +769,7 @@
_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());
@@ -800,7 +803,7 @@
}
#endif // def HAVE_DTRACE_H
-void* nmethod::operator new(size_t size, int nmethod_size) {
+void* nmethod::operator new(size_t size, int nmethod_size) throw() {
// Not critical, may return null if there is too little continuous memory
return CodeCache::allocate(nmethod_size);
}
@@ -839,6 +842,7 @@
_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());
@@ -1173,7 +1177,7 @@
// This is a private interface with the sweeper.
void nmethod::mark_as_seen_on_stack() {
- assert(is_not_entrant(), "must be a non-entrant method");
+ assert(is_alive(), "Must be an alive method");
// Set the traversal mark to ensure that the sweeper does 2
// cleaning passes before moving to zombie.
set_stack_traversal_mark(NMethodSweeper::traversal_count());
@@ -1258,7 +1262,7 @@
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() {
@@ -1348,6 +1352,15 @@
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();
+ OrderAccess::storestore();
+ }
+
// Change state
_state = state;
@@ -1366,11 +1379,6 @@
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
@@ -1401,6 +1409,9 @@
// nmethods aren't scanned for GC.
_oops_are_stale = true;
#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");
}
@@ -1410,7 +1421,7 @@
}
// Make sweeper aware that there is a zombie method that needs to be removed
- NMethodSweeper::notify(this);
+ NMethodSweeper::notify();
return true;
}
@@ -1445,10 +1456,6 @@
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
@@ -1959,7 +1966,7 @@
if (!_detected_scavenge_root) _print_nm->print_on(tty, "new scavenge root");
tty->print_cr(""PTR_FORMAT"[offset=%d] detected scavengable oop "PTR_FORMAT" (found at "PTR_FORMAT")",
_print_nm, (int)((intptr_t)p - (intptr_t)_print_nm),
- (intptr_t)(*p), (intptr_t)p);
+ (void *)(*p), (intptr_t)p);
(*p)->print();
}
#endif //PRODUCT
@@ -2339,7 +2346,7 @@
_ok = false;
}
tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
- (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
+ (void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
}
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
};
@@ -2460,7 +2467,7 @@
_ok = false;
}
tty->print_cr("*** scavengable oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
- (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
+ (void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
(*p)->print();
}
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }