8145435: [JVMCI] some tests on Windows fail with: assert(!thread->is_Java_thread()) failed: must not be java thread
Reviewed-by: never, dnsimon, dholmes, coleenp
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Tue Dec 22 13:41:09 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Wed Dec 23 07:27:42 2015 -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;
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Tue Dec 22 13:41:09 2015 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Dec 23 07:27:42 2015 -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();
@@ -1732,20 +1720,25 @@
return "\t<<no stack trace available>>";
}
-
-// 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())));
+/**
+ * Print the throwable message and its stack trace plus all causes by walking the
+ * cause chain. The output looks the same as of Throwable.printStackTrace().
+ */
+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;
}
while (result.not_null()) {
-
// Get method id, bci, version and mirror from chunk
typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result));
typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result));
@@ -1770,20 +1763,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();
}
}
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Tue Dec 22 13:41:09 2015 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Dec 23 07:27:42 2015 -1000
@@ -552,9 +552,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;
};
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Tue Dec 22 13:41:09 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Wed Dec 23 07:27:42 2015 -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) {
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp Tue Dec 22 13:41:09 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp Wed Dec 23 07:27:42 2015 -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();
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Tue Dec 22 13:41:09 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Wed Dec 23 07:27:42 2015 -1000
@@ -935,16 +935,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);
}
}
@@ -962,32 +961,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
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp Tue Dec 22 13:41:09 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp Wed Dec 23 07:27:42 2015 -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
--- a/hotspot/src/share/vm/runtime/java.cpp Tue Dec 22 13:41:09 2015 -0800
+++ b/hotspot/src/share/vm/runtime/java.cpp Wed Dec 23 07:27:42 2015 -1000
@@ -398,7 +398,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
@@ -426,7 +426,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.
@@ -612,9 +620,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);