@@ -311,25 +311,138 @@ void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, bool jni_enomem_is_fata
311311 }
312312}
313313
314- // Prints a pending exception (if any) and its stack trace.
315- void JVMCIEnv::describe_pending_exception (bool clear) {
314+ // Prints a pending exception (if any) and its stack trace to st.
315+ // Also partially logs the stack trace to the JVMCI event log.
316+ void JVMCIEnv::describe_pending_exception (outputStream* st) {
317+ ResourceMark rm;
318+ char * stack_trace = nullptr ;
319+ if (pending_exception_as_string (nullptr , (const char **) &stack_trace)) {
320+ st->print_raw_cr (stack_trace);
321+
322+ // Use up to half the lines of the JVMCI event log to
323+ // show the stack trace.
324+ char * cursor = stack_trace;
325+ int line = 0 ;
326+ const int max_lines = LogEventsBufferEntries / 2 ;
327+ char * last_line = nullptr ;
328+ while (*cursor != ' \0 ' ) {
329+ char * eol = strchr (cursor, ' \n ' );
330+ if (eol == nullptr ) {
331+ if (line == max_lines - 1 ) {
332+ last_line = cursor;
333+ } else if (line < max_lines) {
334+ JVMCI_event_1 (" %s" , cursor);
335+ }
336+ cursor = cursor + strlen (cursor);
337+ } else {
338+ *eol = ' \0 ' ;
339+ if (line == max_lines - 1 ) {
340+ last_line = cursor;
341+ } else if (line < max_lines) {
342+ JVMCI_event_1 (" %s" , cursor);
343+ }
344+ cursor = eol + 1 ;
345+ }
346+ line++;
347+ }
348+ if (last_line != nullptr ) {
349+ if (line > max_lines) {
350+ JVMCI_event_1 (" %s [elided %d more stack trace lines]" , last_line, line - max_lines);
351+ } else {
352+ JVMCI_event_1 (" %s" , last_line);
353+ }
354+ }
355+ }
356+ }
357+
358+ bool JVMCIEnv::pending_exception_as_string (const char ** to_string, const char ** stack_trace) {
316359 JavaThread* THREAD = JavaThread::current (); // For exception macros.
360+ JVMCIObject to_string_obj;
361+ JVMCIObject stack_trace_obj;
362+ bool had_nested_exception = false ;
317363 if (!is_hotspot ()) {
318364 JNIAccessMark jni (this , THREAD);
319- if (jni ()->ExceptionCheck ()) {
320- jthrowable ex = !clear ? jni ()->ExceptionOccurred () : nullptr ;
321- jni ()->ExceptionDescribe ();
322- if (ex != nullptr ) {
323- jni ()->Throw (ex);
365+ jthrowable ex = jni ()->ExceptionOccurred ();
366+ if (ex != NULL ) {
367+ jni ()->ExceptionClear ();
368+ jobjectArray pair = (jobjectArray) jni ()->CallStaticObjectMethod (
369+ JNIJVMCI::HotSpotJVMCIRuntime::clazz (),
370+ JNIJVMCI::HotSpotJVMCIRuntime::exceptionToString_method (),
371+ ex, to_string != nullptr , stack_trace != nullptr );
372+ if (jni ()->ExceptionCheck ()) {
373+ // As last resort, dump nested exception
374+ jni ()->ExceptionDescribe ();
375+ had_nested_exception = true ;
376+ } else {
377+ guarantee (pair != nullptr , " pair is null" );
378+ int len = jni ()->GetArrayLength (pair);
379+ guarantee (len == 2 , " bad len is %d" , len);
380+ if (to_string != nullptr ) {
381+ to_string_obj = JVMCIObject::create (jni ()->GetObjectArrayElement (pair, 0 ), false );
382+ }
383+ if (stack_trace != nullptr ) {
384+ stack_trace_obj = JVMCIObject::create (jni ()->GetObjectArrayElement (pair, 1 ), false );
385+ }
324386 }
387+ } else {
388+ return false ;
325389 }
326390 } else {
327391 if (HAS_PENDING_EXCEPTION) {
328- JVMCIRuntime::describe_pending_hotspot_exception (THREAD, clear);
392+ Handle exception (THREAD, PENDING_EXCEPTION);
393+ CLEAR_PENDING_EXCEPTION;
394+ JavaCallArguments jargs;
395+ jargs.push_oop (exception);
396+ jargs.push_int (to_string != nullptr );
397+ jargs.push_int (stack_trace != nullptr );
398+ JavaValue result (T_OBJECT);
399+ JavaCalls::call_static (&result,
400+ HotSpotJVMCI::HotSpotJVMCIRuntime::klass (),
401+ vmSymbols::exceptionToString_name (),
402+ vmSymbols::exceptionToString_signature (), &jargs, THREAD);
403+ if (HAS_PENDING_EXCEPTION) {
404+ Handle nested_exception (THREAD, PENDING_EXCEPTION);
405+ CLEAR_PENDING_EXCEPTION;
406+ java_lang_Throwable::print_stack_trace (nested_exception, tty);
407+ // Clear and ignore any exceptions raised during printing
408+ CLEAR_PENDING_EXCEPTION;
409+ had_nested_exception = true ;
410+ } else {
411+ oop pair = result.get_oop ();
412+ guarantee (pair->is_objArray (), " must be" );
413+ objArrayOop pair_arr = objArrayOop (pair);
414+ int len = pair_arr->length ();
415+ guarantee (len == 2 , " bad len is %d" , len);
416+ if (to_string != nullptr ) {
417+ to_string_obj = HotSpotJVMCI::wrap (pair_arr->obj_at (0 ));
418+ }
419+ if (stack_trace != nullptr ) {
420+ stack_trace_obj = HotSpotJVMCI::wrap (pair_arr->obj_at (1 ));
421+ }
422+ }
423+ } else {
424+ return false ;
425+ }
426+ }
427+ if (had_nested_exception) {
428+ if (to_string != nullptr ) {
429+ *to_string = " nested exception occurred converting exception to string" ;
430+ }
431+ if (stack_trace != nullptr ) {
432+ *stack_trace = " nested exception occurred converting exception stack to string" ;
433+ }
434+ } else {
435+ if (to_string_obj.is_non_null ()) {
436+ *to_string = as_utf8_string (to_string_obj);
437+ }
438+ if (stack_trace_obj.is_non_null ()) {
439+ *stack_trace = as_utf8_string (stack_trace_obj);
329440 }
330441 }
442+ return true ;
331443}
332444
445+
333446// Shared code for translating an exception from HotSpot to libjvmci or vice versa.
334447class ExceptionTranslation : public StackObj {
335448 protected:
@@ -771,10 +884,11 @@ const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {
771884 return java_lang_String::as_utf8_string (HotSpotJVMCI::resolve (str));
772885 } else {
773886 JNIAccessMark jni (this );
774- int length = jni ()->GetStringLength (str.as_jstring ());
775- int utf8_length = jni ()->GetStringUTFLength (str.as_jstring ());
887+ jstring jstr = str.as_jstring ();
888+ int length = jni ()->GetStringLength (jstr);
889+ int utf8_length = jni ()->GetStringUTFLength (jstr);
776890 char * result = NEW_RESOURCE_ARRAY (char , utf8_length + 1 );
777- jni ()->GetStringUTFRegion (str. as_jstring () , 0 , length, result);
891+ jni ()->GetStringUTFRegion (jstr , 0 , length, result);
778892 return result;
779893 }
780894}
@@ -904,7 +1018,7 @@ void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
9041018 if (has_pending_exception ()) {
9051019 // This should never happen as HotSpotJVMCIRuntime.shutdown() should
9061020 // handle all exceptions.
907- describe_pending_exception (true );
1021+ describe_pending_exception (tty );
9081022 }
9091023}
9101024
@@ -960,30 +1074,6 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime,
9601074 }
9611075}
9621076
963-
964- JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString (JVMCIObject object, JVMCIEnv* JVMCIENV) {
965- JavaThread* THREAD = JVMCI::compilation_tick (JavaThread::current ()); // For exception macros.
966- if (is_hotspot ()) {
967- JavaCallArguments jargs;
968- jargs.push_oop (Handle (THREAD, HotSpotJVMCI::resolve (object)));
969- JavaValue result (T_OBJECT);
970- JavaCalls::call_static (&result,
971- HotSpotJVMCI::HotSpotJVMCIRuntime::klass (),
972- vmSymbols::callToString_name (),
973- vmSymbols::callToString_signature (), &jargs, CHECK_ (JVMCIObject ()));
974- return wrap (result.get_oop ());
975- } else {
976- JNIAccessMark jni (this , THREAD);
977- jobject result = (jstring) jni ()->CallStaticObjectMethod (JNIJVMCI::HotSpotJVMCIRuntime::clazz (),
978- JNIJVMCI::HotSpotJVMCIRuntime::callToString_method (),
979- object.as_jobject ());
980- if (jni ()->ExceptionCheck ()) {
981- return JVMCIObject ();
982- }
983- return wrap (result);
984- }
985- }
986-
9871077void JVMCIEnv::call_HotSpotJVMCIRuntime_postTranslation (JVMCIObject object, JVMCIEnv* JVMCIENV) {
9881078 JavaThread* THREAD = JVMCI::compilation_tick (JavaThread::current ()); // For exception macros.
9891079 if (is_hotspot ()) {
0 commit comments