--- old/src/share/vm/ci/ciReplay.cpp 2015-12-17 07:42:47.000000000 -1000 +++ new/src/share/vm/ci/ciReplay.cpp 2015-12-17 07:42:47.000000000 -1000 @@ -1040,10 +1040,8 @@ } void* data = rp.process_inline(method, method->get_Method(), entry_bci, comp_level, THREAD); if (HAS_PENDING_EXCEPTION) { - oop throwable = PENDING_EXCEPTION; + Handle throwable(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; - java_lang_Throwable::print(throwable, tty); - tty->cr(); java_lang_Throwable::print_stack_trace(throwable, tty); tty->cr(); return NULL; @@ -1085,10 +1083,8 @@ } if (HAS_PENDING_EXCEPTION) { - oop throwable = PENDING_EXCEPTION; + Handle throwable(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; - java_lang_Throwable::print(throwable, tty); - tty->cr(); java_lang_Throwable::print_stack_trace(throwable, tty); tty->cr(); exit_code = 2; --- old/src/share/vm/classfile/javaClasses.cpp 2015-12-17 07:42:47.000000000 -1000 +++ new/src/share/vm/classfile/javaClasses.cpp 2015-12-17 07:42:47.000000000 -1000 @@ -1493,18 +1493,6 @@ } -void java_lang_Throwable::print(oop throwable, outputStream* st) { - ResourceMark rm; - Klass* k = throwable->klass(); - assert(k != NULL, "just checking"); - st->print("%s", k->external_name()); - oop msg = message(throwable); - if (msg != NULL) { - st->print(": %s", java_lang_String::as_utf8_string(msg)); - } -} - - void java_lang_Throwable::print(Handle throwable, outputStream* st) { ResourceMark rm; Klass* k = throwable->klass(); @@ -1733,12 +1721,15 @@ } -// Currently used only for exceptions occurring during startup -void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { - Thread *THREAD = Thread::current(); - Handle h_throwable(THREAD, throwable); - while (h_throwable.not_null()) { - objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); +void java_lang_Throwable::print_stack_trace(Handle throwable, outputStream* st) { + // First, print the message. + print(throwable, st); + st->cr(); + + // Now print the stack trace. + Thread* THREAD = Thread::current(); + while (throwable.not_null()) { + objArrayHandle result (THREAD, objArrayOop(backtrace(throwable()))); if (result.is_null()) { st->print_raw_cr(no_stack_trace_message()); return; @@ -1770,20 +1761,20 @@ EXCEPTION_MARK; JavaValue cause(T_OBJECT); JavaCalls::call_virtual(&cause, - h_throwable, - KlassHandle(THREAD, h_throwable->klass()), + throwable, + KlassHandle(THREAD, throwable->klass()), vmSymbols::getCause_name(), vmSymbols::void_throwable_signature(), THREAD); // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; - h_throwable = Handle(); + throwable = Handle(); } else { - h_throwable = Handle(THREAD, (oop) cause.get_jobject()); - if (h_throwable.not_null()) { + throwable = Handle(THREAD, (oop) cause.get_jobject()); + if (throwable.not_null()) { st->print("Caused by: "); - print(h_throwable, st); + print(throwable, st); st->cr(); } } --- old/src/share/vm/classfile/javaClasses.hpp 2015-12-17 07:42:48.000000000 -1000 +++ new/src/share/vm/classfile/javaClasses.hpp 2015-12-17 07:42:48.000000000 -1000 @@ -551,9 +551,8 @@ static oop get_stack_trace_element(oop throwable, int index, TRAPS); static int get_stack_trace_depth(oop throwable, TRAPS); // Printing - static void print(oop throwable, outputStream* st); static void print(Handle throwable, outputStream* st); - static void print_stack_trace(oop throwable, outputStream* st); + static void print_stack_trace(Handle throwable, outputStream* st); // Debugging friend class JavaClasses; }; --- old/src/share/vm/jvmci/jvmciCompiler.cpp 2015-12-17 07:42:48.000000000 -1000 +++ new/src/share/vm/jvmci/jvmciCompiler.cpp 2015-12-17 07:42:48.000000000 -1000 @@ -112,6 +112,15 @@ _bootstrapping = false; } +#define CHECK_ABORT THREAD); \ +if (HAS_PENDING_EXCEPTION) { \ + char buf[256]; \ + jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ + JVMCICompiler::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ + return; \ +} \ +(void)(0 + void JVMCICompiler::compile_method(const methodHandle& method, int entry_bci, JVMCIEnv* env) { JVMCI_EXCEPTION_CONTEXT @@ -150,12 +159,12 @@ // should be handled by the Java code in some useful way but if they leak // through to here report them instead of dying or silently ignoring them. if (HAS_PENDING_EXCEPTION) { - Handle throwable = PENDING_EXCEPTION; + Handle exception(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; - JVMCIRuntime::call_printStackTrace(throwable, THREAD); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; + { + ttyLocker ttyl; + java_lang_Throwable::print_stack_trace(exception, tty); } // Something went wrong so disable compilation at this level @@ -165,6 +174,28 @@ } } +/** + * Aborts the VM due to an unexpected exception. + */ +void JVMCICompiler::abort_on_pending_exception(Handle exception, const char* message, bool dump_core) { + Thread* THREAD = Thread::current(); + CLEAR_PENDING_EXCEPTION; + + { + ttyLocker ttyl; + tty->print_raw_cr(message); + java_lang_Throwable::print_stack_trace(exception, tty); + } + + // Give other aborting threads to also print their stack traces. + // This can be very useful when debugging class initialization + // failures. + assert(THREAD->is_Java_thread(), "compiler threads should be Java threads"); + const bool interruptible = true; + os::sleep(THREAD, 200, interruptible); + + vm_abort(dump_core); +} // Compilation entry point for methods void JVMCICompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci, DirectiveSet* directive) { --- old/src/share/vm/jvmci/jvmciCompiler.hpp 2015-12-17 07:42:49.000000000 -1000 +++ new/src/share/vm/jvmci/jvmciCompiler.hpp 2015-12-17 07:42:49.000000000 -1000 @@ -42,6 +42,8 @@ static elapsedTimer _codeInstallTimer; + static void abort_on_pending_exception(Handle exception, const char* message, bool dump_core = false); + public: JVMCICompiler(); --- old/src/share/vm/jvmci/jvmciRuntime.cpp 2015-12-17 07:42:49.000000000 -1000 +++ new/src/share/vm/jvmci/jvmciRuntime.cpp 2015-12-17 07:42:49.000000000 -1000 @@ -939,16 +939,15 @@ } } -void JVMCIRuntime::shutdown() { +void JVMCIRuntime::shutdown(TRAPS) { if (_HotSpotJVMCIRuntime_instance != NULL) { _shutdown_called = true; - JavaThread* THREAD = JavaThread::current(); HandleMark hm(THREAD); - Handle receiver = get_HotSpotJVMCIRuntime(CHECK_ABORT); + Handle receiver = get_HotSpotJVMCIRuntime(CHECK); JavaValue result(T_VOID); JavaCallArguments args; args.push_oop(receiver); - JavaCalls::call_special(&result, receiver->klass(), vmSymbols::shutdown_method_name(), vmSymbols::void_method_signature(), &args, CHECK_ABORT); + JavaCalls::call_special(&result, receiver->klass(), vmSymbols::shutdown_method_name(), vmSymbols::void_method_signature(), &args, CHECK); } } @@ -966,32 +965,6 @@ return false; } -void JVMCIRuntime::call_printStackTrace(Handle exception, Thread* thread) { - assert(exception->is_a(SystemDictionary::Throwable_klass()), "Throwable instance expected"); - JavaValue result(T_VOID); - JavaCalls::call_virtual(&result, - exception, - KlassHandle(thread, - SystemDictionary::Throwable_klass()), - vmSymbols::printStackTrace_name(), - vmSymbols::void_method_signature(), - thread); -} - -void JVMCIRuntime::abort_on_pending_exception(Handle exception, const char* message, bool dump_core) { - Thread* THREAD = Thread::current(); - CLEAR_PENDING_EXCEPTION; - tty->print_raw_cr(message); - call_printStackTrace(exception, THREAD); - - // Give other aborting threads to also print their stack traces. - // This can be very useful when debugging class initialization - // failures. - os::sleep(THREAD, 200, false); - - vm_abort(dump_core); -} - void JVMCIRuntime::parse_lines(char* path, ParseClosure* closure, bool warnStatFailure) { struct stat st; if (::stat(path, &st) == 0 && (st.st_mode & S_IFREG) == S_IFREG) { // exists & is regular file --- old/src/share/vm/jvmci/jvmciRuntime.hpp 2015-12-17 07:42:50.000000000 -1000 +++ new/src/share/vm/jvmci/jvmciRuntime.hpp 2015-12-17 07:42:50.000000000 -1000 @@ -145,7 +145,7 @@ static void metadata_do(void f(Metadata*)); - static void shutdown(); + static void shutdown(TRAPS); static bool shutdown_called() { return _shutdown_called; @@ -154,34 +154,6 @@ static bool treat_as_trivial(Method* method); static void parse_lines(char* path, ParseClosure* closure, bool warnStatFailure); - /** - * Aborts the VM due to an unexpected exception. - */ - static void abort_on_pending_exception(Handle exception, const char* message, bool dump_core = false); - - /** - * Calls Throwable.printStackTrace() on a given exception. - */ - static void call_printStackTrace(Handle exception, Thread* thread); - -#define CHECK_ABORT THREAD); \ - if (HAS_PENDING_EXCEPTION) { \ - char buf[256]; \ - jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ - JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ - return; \ - } \ - (void)(0 - -#define CHECK_ABORT_(result) THREAD); \ - if (HAS_PENDING_EXCEPTION) { \ - char buf[256]; \ - jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ - JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ - return result; \ - } \ - (void)(0 - static BasicType kindToBasicType(Handle kind, TRAPS); // The following routines are all called from compiled JVMCI code --- old/src/share/vm/runtime/java.cpp 2015-12-17 07:42:51.000000000 -1000 +++ new/src/share/vm/runtime/java.cpp 2015-12-17 07:42:50.000000000 -1000 @@ -397,7 +397,7 @@ // Note: before_exit() can be executed only once, if more than one threads // are trying to shutdown the VM at the same time, only one thread // can run before_exit() and all other threads must wait. -void before_exit(JavaThread * thread) { +void before_exit(JavaThread* thread) { #define BEFORE_EXIT_NOT_RUN 0 #define BEFORE_EXIT_RUNNING 1 #define BEFORE_EXIT_DONE 2 @@ -425,7 +425,15 @@ } #if INCLUDE_JVMCI - JVMCIRuntime::shutdown(); + // We are not using CATCH here because we want the exit to continue normally. + Thread* THREAD = thread; + JVMCIRuntime::shutdown(THREAD); + if (HAS_PENDING_EXCEPTION) { + Handle exception(THREAD, PENDING_EXCEPTION); + CLEAR_PENDING_EXCEPTION; + ttyLocker ttyl; + java_lang_Throwable::print_stack_trace(exception, tty); + } #endif // Hang forever on exit if we're reporting an error. @@ -610,9 +618,7 @@ if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; } - java_lang_Throwable::print(exception, tty); - tty->cr(); - java_lang_Throwable::print_stack_trace(exception(), tty); + java_lang_Throwable::print_stack_trace(exception, tty); tty->cr(); vm_notify_during_shutdown(NULL, NULL);