8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
authorjiangli
Tue, 08 Jan 2013 13:01:19 -0500
changeset 15109 088b1ea04490
parent 15108 25a01874cc47
child 15110 b09370d81054
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9. Summary: Use methodHandle. Reviewed-by: coleenp, acorn, twisti, sspitsyn
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
hotspot/src/share/vm/oops/method.cpp
hotspot/src/share/vm/oops/method.hpp
hotspot/src/share/vm/prims/jvmtiExport.cpp
hotspot/src/share/vm/runtime/sharedRuntime.cpp
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Jan 03 15:08:43 2013 -0500
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Jan 08 13:01:19 2013 -0500
@@ -417,7 +417,7 @@
 
     // exception handler lookup
     KlassHandle h_klass(THREAD, h_exception->klass());
-    handler_bci = h_method->fast_exception_handler_bci_for(h_klass, current_bci, THREAD);
+    handler_bci = Method::fast_exception_handler_bci_for(h_method, h_klass, current_bci, THREAD);
     if (HAS_PENDING_EXCEPTION) {
       // We threw an exception while trying to find the exception handler.
       // Transfer the new exception to the exception handle which will
--- a/hotspot/src/share/vm/oops/method.cpp	Thu Jan 03 15:08:43 2013 -0500
+++ b/hotspot/src/share/vm/oops/method.cpp	Tue Jan 08 13:01:19 2013 -0500
@@ -192,16 +192,16 @@
   return buf;
 }
 
-int  Method::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) {
+int Method::fast_exception_handler_bci_for(methodHandle mh, KlassHandle ex_klass, int throw_bci, TRAPS) {
   // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index)
   // access exception table
-  ExceptionTable table(this);
+  ExceptionTable table(mh());
   int length = table.length();
   // iterate through all entries sequentially
-  constantPoolHandle pool(THREAD, constants());
+  constantPoolHandle pool(THREAD, mh->constants());
   for (int i = 0; i < length; i ++) {
     //reacquire the table in case a GC happened
-    ExceptionTable table(this);
+    ExceptionTable table(mh());
     int beg_bci = table.start_pc(i);
     int end_bci = table.end_pc(i);
     assert(beg_bci <= end_bci, "inconsistent exception table");
--- a/hotspot/src/share/vm/oops/method.hpp	Thu Jan 03 15:08:43 2013 -0500
+++ b/hotspot/src/share/vm/oops/method.hpp	Tue Jan 08 13:01:19 2013 -0500
@@ -343,7 +343,7 @@
   // exception handler which caused the exception to be thrown, which
   // is needed for proper retries. See, for example,
   // InterpreterRuntime::exception_handler_for_exception.
-  int fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS);
+  static int fast_exception_handler_bci_for(methodHandle mh, KlassHandle ex_klass, int throw_bci, TRAPS);
 
   // method data access
   MethodData* method_data() const              {
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Thu Jan 03 15:08:43 2013 -0500
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Jan 08 13:01:19 2013 -0500
@@ -1305,15 +1305,21 @@
         vframeStream st(thread);
         assert(!st.at_end(), "cannot be at end");
         Method* current_method = NULL;
+        // A GC may occur during the Method::fast_exception_handler_bci_for()
+        // call below if it needs to load the constraint class. Using a
+        // methodHandle to keep the 'current_method' from being deallocated
+        // if GC happens.
+        methodHandle current_mh = methodHandle(thread, current_method);
         int current_bci = -1;
         do {
           current_method = st.method();
+          current_mh = methodHandle(thread, current_method);
           current_bci = st.bci();
           do {
             should_repeat = false;
             KlassHandle eh_klass(thread, exception_handle()->klass());
-            current_bci = current_method->fast_exception_handler_bci_for(
-              eh_klass, current_bci, THREAD);
+            current_bci = Method::fast_exception_handler_bci_for(
+              current_mh, eh_klass, current_bci, THREAD);
             if (HAS_PENDING_EXCEPTION) {
               exception_handle = Handle(thread, PENDING_EXCEPTION);
               CLEAR_PENDING_EXCEPTION;
@@ -1328,8 +1334,7 @@
           catch_jmethodID = 0;
           current_bci = 0;
         } else {
-          catch_jmethodID = jem.to_jmethodID(
-                                     methodHandle(thread, current_method));
+          catch_jmethodID = jem.to_jmethodID(current_mh);
         }
 
         JvmtiJavaThreadEventTransition jet(thread);
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Jan 03 15:08:43 2013 -0500
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Jan 08 13:01:19 2013 -0500
@@ -643,7 +643,8 @@
       bool skip_scope_increment = false;
       // exception handler lookup
       KlassHandle ek (THREAD, exception->klass());
-      handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD);
+      methodHandle mh(THREAD, sd->method());
+      handler_bci = Method::fast_exception_handler_bci_for(mh, ek, bci, THREAD);
       if (HAS_PENDING_EXCEPTION) {
         recursive_exception = true;
         // We threw an exception while trying to find the exception handler.