--- a/hotspot/src/share/vm/code/nmethod.cpp Mon Aug 31 05:27:29 2009 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Sep 02 00:04:29 2009 -0700
@@ -1079,6 +1079,10 @@
this, (address)_method, (address)cause);
cause->klass()->print();
}
+ // Unlink the osr method, so we do not look this up again
+ if (is_osr_method()) {
+ invalidate_osr_method();
+ }
// If _method is already NULL the methodOop is about to be unloaded,
// so we don't have to break the cycle. Note that it is possible to
// have the methodOop live here, in case we unload the nmethod because
@@ -1148,7 +1152,7 @@
// will never be used anymore. That the nmethods only gets removed when class unloading
// happens, make life much simpler, since the nmethods are not just going to disappear
// out of the blue.
- if (is_osr_only_method()) {
+ if (is_osr_method()) {
if (osr_entry_bci() != InvalidOSREntryBci) {
// only log this once
log_state_change(state);
@@ -1520,6 +1524,17 @@
#endif // !PRODUCT
}
+// This method is called twice during GC -- once while
+// tracing the "active" nmethods on thread stacks during
+// the (strong) marking phase, and then again when walking
+// the code cache contents during the weak roots processing
+// phase. The two uses are distinguished by means of the
+// do_nmethods() method in the closure "f" below -- which
+// answers "yes" in the first case, and "no" in the second
+// case. We want to walk the weak roots in the nmethod
+// only in the second case. The weak roots in the nmethod
+// are the oops in the ExceptionCache and the InlineCache
+// oops.
void nmethod::oops_do(OopClosure* f) {
// make sure the oops ready to receive visitors
assert(!is_zombie() && !is_unloaded(),
@@ -1538,19 +1553,25 @@
// Compiled code
f->do_oop((oop*) &_method);
- ExceptionCache* ec = exception_cache();
- while(ec != NULL) {
- f->do_oop((oop*)ec->exception_type_addr());
- ec = ec->next();
- }
+ if (!f->do_nmethods()) {
+ // weak roots processing phase -- update ExceptionCache oops
+ ExceptionCache* ec = exception_cache();
+ while(ec != NULL) {
+ f->do_oop((oop*)ec->exception_type_addr());
+ ec = ec->next();
+ }
+ } // Else strong roots phase -- skip oops in ExceptionCache
RelocIterator iter(this, low_boundary);
+
while (iter.next()) {
if (iter.type() == relocInfo::oop_type ) {
oop_Relocation* r = iter.oop_reloc();
// In this loop, we must only follow those oops directly embedded in
// the code. Other oops (oop_index>0) are seen as part of scopes_oops.
- assert(1 == (r->oop_is_immediate()) + (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()), "oop must be found in exactly one place");
+ assert(1 == (r->oop_is_immediate()) +
+ (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()),
+ "oop must be found in exactly one place");
if (r->oop_is_immediate() && r->oop_value() != NULL) {
f->do_oop(r->oop_addr());
}