8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
Summary: Use methodHandle.
Reviewed-by: coleenp, acorn, twisti, sspitsyn
--- 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.