changeset 1819:38e8278318ca

6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs") Reviewed-by: dcubed, kvn, twisti
author never
date Mon, 21 Jun 2010 14:26:17 -0700
parents ff38d05ea86f
children 9887b5e57f9e
files src/share/vm/code/nmethod.cpp src/share/vm/code/nmethod.hpp src/share/vm/prims/jvmtiCodeBlobEvents.cpp src/share/vm/runtime/jniHandles.cpp
diffstat 4 files changed, 36 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/code/nmethod.cpp	Fri Jun 18 16:51:54 2010 -0700
+++ b/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
--- a/src/share/vm/code/nmethod.hpp	Fri Jun 18 16:51:54 2010 -0700
+++ b/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();
--- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Fri Jun 18 16:51:54 2010 -0700
+++ b/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()),
--- a/src/share/vm/runtime/jniHandles.cpp	Fri Jun 18 16:51:54 2010 -0700
+++ b/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