diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index fb4b059b5bd..f35858fe586 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -764,7 +764,7 @@ class SerializeClosure; template(decodeAndThrowThrowable_name, "decodeAndThrowThrowable") \ template(encodeAnnotations_name, "encodeAnnotations") \ template(encodeAnnotations_signature, "([BLjava/lang/Class;Ljdk/internal/reflect/ConstantPool;Z[Ljava/lang/Class;)[B")\ - template(decodeAndThrowThrowable_signature, "(IJZ)V") \ + template(decodeAndThrowThrowable_signature, "(IJZZ)V") \ template(classRedefinedCount_name, "classRedefinedCount") \ template(classLoader_name, "classLoader") \ template(componentType_name, "componentType") \ diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index cf6e7b2a81a..8a56beb9d02 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -36,11 +36,11 @@ #include "oops/objArrayKlass.hpp" #include "oops/typeArrayOop.inline.hpp" #include "prims/jvmtiExport.hpp" +#include "runtime/arguments.hpp" #include "runtime/deoptimization.hpp" #include "runtime/fieldDescriptor.inline.hpp" #include "runtime/jniHandles.inline.hpp" #include "runtime/javaCalls.hpp" -#include "runtime/thread.inline.hpp" #include "runtime/os.hpp" #include "jvmci/jniAccessMark.inline.hpp" #include "jvmci/jvmciCompiler.hpp" @@ -415,6 +415,11 @@ class ExceptionTranslation: public StackObj { // Decodes the exception in `buffer` in `_to_env` and throws it. virtual void decode(JavaThread* THREAD, DecodeFormat format, jlong buffer) = 0; + static bool debug_translated_exception() { + const char* prop_value = Arguments::get_property("jdk.internal.vm.TranslatedException.debug"); + return prop_value != nullptr && strcmp("true", prop_value) == 0; + } + public: void doit(JavaThread* THREAD) { int buffer_size = 2048; @@ -510,7 +515,7 @@ class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation { JNIAccessMark jni(_to_env, THREAD); jni()->CallStaticVoidMethod(JNIJVMCI::VMSupport::clazz(), JNIJVMCI::VMSupport::decodeAndThrowThrowable_method(), - format, buffer, false); + format, buffer, false, debug_translated_exception()); } public: HotSpotToSharedLibraryExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, const Handle& throwable) : @@ -543,6 +548,7 @@ class SharedLibraryToHotSpotExceptionTranslation : public ExceptionTranslation { jargs.push_int(format); jargs.push_long(buffer); jargs.push_int(true); + jargs.push_int(debug_translated_exception()); JavaValue result(T_VOID); JavaCalls::call_static(&result, vmSupport, diff --git a/src/java.base/share/classes/jdk/internal/vm/TranslatedException.java b/src/java.base/share/classes/jdk/internal/vm/TranslatedException.java index 92a443704e8..662ab25a122 100644 --- a/src/java.base/share/classes/jdk/internal/vm/TranslatedException.java +++ b/src/java.base/share/classes/jdk/internal/vm/TranslatedException.java @@ -122,26 +122,26 @@ final class TranslatedException extends Exception { * Prints a stack trace for {@code throwable} if the system property * {@code "jdk.internal.vm.TranslatedException.debug"} is true. */ - private static void debugPrintStackTrace(Throwable throwable) { - if (Boolean.getBoolean("jdk.internal.vm.TranslatedException.debug")) { + private static void debugPrintStackTrace(Throwable throwable, boolean debug) { + if (debug) { System.err.print("DEBUG: "); throwable.printStackTrace(); } } - private static Throwable initCause(Throwable throwable, Throwable cause) { + private static Throwable initCause(Throwable throwable, Throwable cause, boolean debug) { if (cause != null) { try { throwable.initCause(cause); } catch (IllegalStateException e) { // Cause could not be set or overwritten. - debugPrintStackTrace(e); + debugPrintStackTrace(e, debug); } } return throwable; } - private static Throwable create(String className, String message, Throwable cause) { + private static Throwable create(String className, String message, Throwable cause, boolean debug) { // Try create with reflection first. try { Class cls = Class.forName(className); @@ -157,13 +157,13 @@ final class TranslatedException extends Exception { } if (message == null) { Constructor cons = cls.getConstructor(); - return initCause((Throwable) cons.newInstance(), cause); + return initCause((Throwable) cons.newInstance(), cause, debug); } Constructor cons = cls.getDeclaredConstructor(String.class); - return initCause((Throwable) cons.newInstance(message), cause); + return initCause((Throwable) cons.newInstance(message), cause, debug); } catch (Throwable translationFailure) { - debugPrintStackTrace(translationFailure); - return initCause(new TranslatedException(message, className), cause); + debugPrintStackTrace(translationFailure, debug); + return initCause(new TranslatedException(message, className), cause, debug); } } @@ -253,7 +253,7 @@ final class TranslatedException extends Exception { * @param encodedThrowable an encoded exception in the format specified by * {@link #encodeThrowable} */ - static Throwable decodeThrowable(byte[] encodedThrowable) { + static Throwable decodeThrowable(byte[] encodedThrowable, boolean debug) { ByteArrayInputStream bais = new ByteArrayInputStream(encodedThrowable); try (DataInputStream dis = new DataInputStream(new GZIPInputStream(bais))) { Throwable cause = null; @@ -262,7 +262,7 @@ final class TranslatedException extends Exception { while (dis.available() != 0) { String exceptionClassName = dis.readUTF(); String exceptionMessage = emptyAsNull(dis.readUTF()); - throwable = create(exceptionClassName, exceptionMessage, cause); + throwable = create(exceptionClassName, exceptionMessage, cause, debug); int stackTraceDepth = dis.readInt(); StackTraceElement[] stackTrace = new StackTraceElement[stackTraceDepth + myStack.length]; int stackTraceIndex = 0; @@ -310,7 +310,7 @@ final class TranslatedException extends Exception { } return throwable; } catch (Throwable translationFailure) { - debugPrintStackTrace(translationFailure); + debugPrintStackTrace(translationFailure, debug); return new TranslatedException("Error decoding exception: " + encodedThrowable, translationFailure.getClass().getName()); } diff --git a/src/java.base/share/classes/jdk/internal/vm/VMSupport.java b/src/java.base/share/classes/jdk/internal/vm/VMSupport.java index 5c890b18804..a8c3b5d4dfa 100644 --- a/src/java.base/share/classes/jdk/internal/vm/VMSupport.java +++ b/src/java.base/share/classes/jdk/internal/vm/VMSupport.java @@ -125,8 +125,9 @@ public class VMSupport { * * @param buffer encoded info about the exception to throw (depends on {@code format}) * @param inJVMHeap [@code true} if executing in the JVM heap, {@code false} otherwise + * @param debug specifies whether debug stack traces should be enabled in case of translation failure */ - public static void decodeAndThrowThrowable(int format, long buffer, boolean inJVMHeap) throws Throwable { + public static void decodeAndThrowThrowable(int format, long buffer, boolean inJVMHeap, boolean debug) throws Throwable { if (format != 0) { String context = String.format("while encoding an exception to translate it %s the JVM heap", inJVMHeap ? "to" : "from"); @@ -142,7 +143,7 @@ public class VMSupport { } throw new InternalError("unexpected problem occurred " + context); } - throw TranslatedException.decodeThrowable(bufferToBytes(buffer)); + throw TranslatedException.decodeThrowable(bufferToBytes(buffer), debug); } private static byte[] bufferToBytes(long buffer) { diff --git a/test/jdk/jdk/internal/vm/TestTranslatedException.java b/test/jdk/jdk/internal/vm/TestTranslatedException.java index 6ad6d526bd3..145e0faf8b4 100644 --- a/test/jdk/jdk/internal/vm/TestTranslatedException.java +++ b/test/jdk/jdk/internal/vm/TestTranslatedException.java @@ -60,7 +60,7 @@ public class TestTranslatedException { encodeDecode(throwable); try { - VMSupport.decodeAndThrowThrowable(0, 0L, true); + VMSupport.decodeAndThrowThrowable(0, 0L, true, false); throw new AssertionError("expected decodeAndThrowThrowable to throw an exception"); } catch (NullPointerException decoded) { // Expected @@ -69,7 +69,7 @@ public class TestTranslatedException { } try { - VMSupport.decodeAndThrowThrowable(1, 0L, true); + VMSupport.decodeAndThrowThrowable(1, 0L, true, false); throw new AssertionError("expected decodeAndThrowThrowable to throw an exception"); } catch (InternalError decoded) { if (!decoded.getMessage().startsWith("native buffer could not be allocated")) { @@ -80,7 +80,7 @@ public class TestTranslatedException { } try { - VMSupport.decodeAndThrowThrowable(2, 0L, true); + VMSupport.decodeAndThrowThrowable(2, 0L, true, false); throw new AssertionError("expected decodeAndThrowThrowable to throw an exception"); } catch (OutOfMemoryError decoded) { // Expected @@ -89,7 +89,7 @@ public class TestTranslatedException { } try { - VMSupport.decodeAndThrowThrowable(3, 0L, true); + VMSupport.decodeAndThrowThrowable(3, 0L, true, false); throw new AssertionError("expected decodeAndThrowThrowable to throw an exception"); } catch (InternalError decoded) { // Expected @@ -98,7 +98,7 @@ public class TestTranslatedException { } try { - VMSupport.decodeAndThrowThrowable(4, 0L, true); + VMSupport.decodeAndThrowThrowable(4, 0L, true, false); throw new AssertionError("expected decodeAndThrowThrowable to throw an exception"); } catch (InternalError decoded) { // Expected @@ -112,7 +112,7 @@ public class TestTranslatedException { try { unsafe.putInt(buffer, problem.length); unsafe.copyMemory(problem, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, buffer + 4, problem.length); - VMSupport.decodeAndThrowThrowable(3, buffer, true); + VMSupport.decodeAndThrowThrowable(3, buffer, true, false); throw new AssertionError("expected decodeAndThrowThrowable to throw an exception"); } catch (InternalError decoded) { String msg = decoded.getMessage(); @@ -139,7 +139,7 @@ public class TestTranslatedException { bufferSize = -res; } else { try { - VMSupport.decodeAndThrowThrowable(format, buffer, true); + VMSupport.decodeAndThrowThrowable(format, buffer, true, false); throw new AssertionError("expected decodeAndThrowThrowable to throw an exception"); } catch (Throwable decoded) { assertThrowableEquals(throwable, decoded);