# HG changeset patch # User never # Date 1277155577 25200 # Node ID c60924a89622c79ce23818b31ec70d299e33d1a3 # Parent 7127e98012e345a2f679d8123304ffb12c74c5ed 6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs") Reviewed-by: dcubed, kvn, twisti diff -r 7127e98012e3 -r c60924a89622 hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Fri Jun 18 16:51:54 2010 -0700 +++ b/hotspot/src/share/vm/code/nmethod.cpp Mon Jun 21 14:26:17 2010 -0700 @@ -584,6 +584,7 @@ _oops_do_mark_link = NULL; _method = method; _entry_bci = InvocationEntryBci; + _jmethod_id = NULL; _osr_link = NULL; _scavenge_root_link = NULL; _scavenge_root_state = 0; @@ -677,6 +678,7 @@ _oops_do_mark_link = NULL; _method = method; _entry_bci = InvocationEntryBci; + _jmethod_id = NULL; _osr_link = NULL; _scavenge_root_link = NULL; _scavenge_root_state = 0; @@ -784,6 +786,7 @@ NOT_PRODUCT(_has_debug_info = false); _oops_do_mark_link = NULL; _method = method; + _jmethod_id = NULL; _compile_id = compile_id; _comp_level = comp_level; _entry_bci = entry_bci; @@ -1488,11 +1491,25 @@ moop->signature()->utf8_length(), code_begin(), code_size()); + if (JvmtiExport::should_post_compiled_method_load() || + JvmtiExport::should_post_compiled_method_unload()) { + get_and_cache_jmethod_id(); + } + if (JvmtiExport::should_post_compiled_method_load()) { JvmtiExport::post_compiled_method_load(this); } } +jmethodID nmethod::get_and_cache_jmethod_id() { + if (_jmethod_id == NULL) { + // Cache the jmethod_id since it can no longer be looked up once the + // method itself has been marked for unloading. + _jmethod_id = method()->jmethod_id(); + } + return _jmethod_id; +} + void nmethod::post_compiled_method_unload() { if (unload_reported()) { // During unloading we transition to unloaded and then to zombie @@ -1504,12 +1521,17 @@ DTRACE_METHOD_UNLOAD_PROBE(method()); // If a JVMTI agent has enabled the CompiledMethodUnload event then - // post the event. Sometime later this nmethod will be made a zombie by - // the sweeper but the methodOop will not be valid at that point. - if (JvmtiExport::should_post_compiled_method_unload()) { + // post the event. Sometime later this nmethod will be made a zombie + // by the sweeper but the methodOop will not be valid at that point. + // If the _jmethod_id is null then no load event was ever requested + // so don't bother posting the unload. The main reason for this is + // that the jmethodID is a weak reference to the methodOop so if + // it's being unloaded there's no way to look it up since the weak + // ref will have been cleared. + if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) { assert(!unload_reported(), "already unloaded"); HandleMark hm; - JvmtiExport::post_compiled_method_unload(method()->jmethod_id(), code_begin()); + JvmtiExport::post_compiled_method_unload(_jmethod_id, code_begin()); } // The JVMTI CompiledMethodUnload event can be enabled or disabled at diff -r 7127e98012e3 -r c60924a89622 hotspot/src/share/vm/code/nmethod.hpp --- a/hotspot/src/share/vm/code/nmethod.hpp Fri Jun 18 16:51:54 2010 -0700 +++ b/hotspot/src/share/vm/code/nmethod.hpp Mon Jun 21 14:26:17 2010 -0700 @@ -135,6 +135,7 @@ methodOop _method; int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method + jmethodID _jmethod_id; // Cache of method()->jmethod_id() // To support simple linked-list chaining of nmethods: nmethod* _osr_link; // from instanceKlass::osr_nmethods_head @@ -599,6 +600,7 @@ // jvmti support: void post_compiled_method_load_event(); + jmethodID get_and_cache_jmethod_id(); // verify operations void verify(); diff -r 7127e98012e3 -r c60924a89622 hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp --- a/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Fri Jun 18 16:51:54 2010 -0700 +++ b/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Mon Jun 21 14:26:17 2010 -0700 @@ -217,21 +217,21 @@ class nmethodDesc: public CHeapObj { private: - methodHandle _method; + jmethodID _jmethod_id; address _code_begin; address _code_end; jvmtiAddrLocationMap* _map; jint _map_length; public: - nmethodDesc(methodHandle method, address code_begin, address code_end, + nmethodDesc(jmethodID jmethod_id, address code_begin, address code_end, jvmtiAddrLocationMap* map, jint map_length) { - _method = method; + _jmethod_id = jmethod_id; _code_begin = code_begin; _code_end = code_end; _map = map; _map_length = map_length; } - methodHandle method() const { return _method; } + jmethodID jmethod_id() const { return _jmethod_id; } address code_begin() const { return _code_begin; } address code_end() const { return _code_end; } jvmtiAddrLocationMap* map() const { return _map; } @@ -323,8 +323,7 @@ JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &map, &map_length); // record the nmethod details - methodHandle mh(nm->method()); - nmethodDesc* snm = new nmethodDesc(mh, + nmethodDesc* snm = new nmethodDesc(nm->get_and_cache_jmethod_id(), nm->code_begin(), nm->code_end(), map, @@ -367,8 +366,7 @@ // iterate over the list and post an event for each nmethod nmethodDesc* nm_desc = collector.first(); while (nm_desc != NULL) { - methodOop method = nm_desc->method()(); - jmethodID mid = method->jmethod_id(); + jmethodID mid = nm_desc->jmethod_id(); assert(mid != NULL, "checking"); JvmtiExport::post_compiled_method_load(env, mid, (jint)(nm_desc->code_end() - nm_desc->code_begin()), diff -r 7127e98012e3 -r c60924a89622 hotspot/src/share/vm/runtime/jniHandles.cpp --- a/hotspot/src/share/vm/runtime/jniHandles.cpp Fri Jun 18 16:51:54 2010 -0700 +++ b/hotspot/src/share/vm/runtime/jniHandles.cpp Mon Jun 21 14:26:17 2010 -0700 @@ -66,6 +66,7 @@ jobject JNIHandles::make_global(Handle obj) { + assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); jobject res = NULL; if (!obj.is_null()) { // ignore null handles @@ -81,6 +82,7 @@ jobject JNIHandles::make_weak_global(Handle obj) { + assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); jobject res = NULL; if (!obj.is_null()) { // ignore null handles