diff --git a/src/share/vm/classfile/javaClasses.cpp b/src/share/vm/classfile/javaClasses.cpp index 81b3e65d4ee6a34ce2d241484c9624b5f17feac6..fa422673d48b6218bd16e96343b1423e49ef0aa6 100644 --- a/src/share/vm/classfile/javaClasses.cpp +++ b/src/share/vm/classfile/javaClasses.cpp @@ -1357,7 +1357,7 @@ class BacktraceBuilder: public StackObj { }; -void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { +void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) { if (!StackTraceInThrowable) return; ResourceMark rm(THREAD); @@ -1374,6 +1374,16 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { JavaThread* thread = (JavaThread*)THREAD; BacktraceBuilder bt(CHECK); + // If there is no Java frame just return the method that was being called + // with bci 0 + if (!thread->has_last_Java_frame()) { + if (max_depth >= 1 && method() != NULL) { + bt.push(method(), 0, CHECK); + set_backtrace(throwable(), bt.backtrace()); + } + return; + } + // Instead of using vframe directly, this version of fill_in_stack_trace // basically handles everything by hand. This significantly improved the // speed of this method call up to 28.5% on Solaris sparc. 27.1% on Windows. @@ -1477,7 +1487,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { set_backtrace(throwable(), bt.backtrace()); } -void java_lang_Throwable::fill_in_stack_trace(Handle throwable) { +void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method) { // No-op if stack trace is disabled if (!StackTraceInThrowable) { return; @@ -1491,7 +1501,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable) { PRESERVE_EXCEPTION_MARK; JavaThread* thread = JavaThread::active(); - fill_in_stack_trace(throwable, thread); + fill_in_stack_trace(throwable, method, thread); // ignore exceptions thrown during stack trace filling CLEAR_PENDING_EXCEPTION; } diff --git a/src/share/vm/classfile/javaClasses.hpp b/src/share/vm/classfile/javaClasses.hpp index bed2ad46ac2bc69ac4a2a14132158cd2c6ea5a7e..5701bc3893c48c8248ba7a8f310a00271b41240b 100644 --- a/src/share/vm/classfile/javaClasses.hpp +++ b/src/share/vm/classfile/javaClasses.hpp @@ -440,8 +440,8 @@ class java_lang_Throwable: AllStatic { static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable); // Fill in current stack trace, can cause GC - static void fill_in_stack_trace(Handle throwable, TRAPS); - static void fill_in_stack_trace(Handle throwable); + static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS); + static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle()); // Programmatic access to stack trace static oop get_stack_trace_element(oop throwable, int index, TRAPS); static int get_stack_trace_depth(oop throwable, TRAPS); diff --git a/src/share/vm/runtime/javaCalls.cpp b/src/share/vm/runtime/javaCalls.cpp index aaa2805e7e7af46a266a520a07791415faf74bf3..eca02a49629fa12fa2b080309c452c6a50011fde 100644 --- a/src/share/vm/runtime/javaCalls.cpp +++ b/src/share/vm/runtime/javaCalls.cpp @@ -389,7 +389,7 @@ void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArgument // to Java if (!os::stack_shadow_pages_available(THREAD, method)) { // Throw stack overflow exception with preinitialized exception. - Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__); + Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method); return; } else { // Touch pages checked if the OS needs them to be touched to be mapped. diff --git a/src/share/vm/utilities/exceptions.cpp b/src/share/vm/utilities/exceptions.cpp index 5d8a33b4d2efff55f2be171d53c498f35c3fb08a..3d2f3cfea6442bfdcc69c187c513489cea455eb9 100644 --- a/src/share/vm/utilities/exceptions.cpp +++ b/src/share/vm/utilities/exceptions.cpp @@ -207,7 +207,7 @@ void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* } -void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line) { +void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) { Handle exception; if (!THREAD->has_pending_exception()) { klassOop k = SystemDictionary::StackOverflowError_klass(); @@ -215,13 +215,13 @@ void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file exception = Handle(THREAD, e); // fill_in_stack trace does gc assert(instanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation"); if (StackTraceInThrowable) { - java_lang_Throwable::fill_in_stack_trace(exception); + java_lang_Throwable::fill_in_stack_trace(exception, method()); } } else { // if prior exception, throw that one instead exception = Handle(THREAD, THREAD->pending_exception()); } - _throw_oop(THREAD, file, line, exception()); + _throw(THREAD, file, line, exception); } void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) { diff --git a/src/share/vm/utilities/exceptions.hpp b/src/share/vm/utilities/exceptions.hpp index 5649f4e600d714b122392c83ce69b6d60103f6ff..52540f31f65733fff46016a084f873a12025482c 100644 --- a/src/share/vm/utilities/exceptions.hpp +++ b/src/share/vm/utilities/exceptions.hpp @@ -144,7 +144,7 @@ class Exceptions { const char* message, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); - static void throw_stack_overflow_exception(Thread* thread, const char* file, int line); + static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method); // for AbortVMOnException flag NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);)