diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 42a0f9279d8..71cbf24a3e0 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -892,6 +892,9 @@ protected void onValueUpdate(EconomicMap, Object> values, String ol @Option(help = "Specifies the number of entries that diagnostic buffers have.", type = OptionType.Debug)// public static final HostedOptionKey DiagnosticBufferSize = new HostedOptionKey<>(30); + @Option(help = "Determines if implicit exceptions are fatal if they don't have a stack trace.", type = OptionType.Debug)// + public static final RuntimeOptionKey ImplicitExceptionWithoutStacktraceIsFatal = new RuntimeOptionKey<>(false); + @SuppressWarnings("unused")// @APIOption(name = "configure-reflection-metadata")// @Option(help = "Enable runtime instantiation of reflection objects for non-invoked methods.", type = OptionType.Expert, deprecated = true)// diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/ImplicitExceptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/ImplicitExceptions.java index ea7e4814bd9..ca8f8679683 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/ImplicitExceptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/ImplicitExceptions.java @@ -27,6 +27,7 @@ import java.lang.reflect.GenericSignatureFormatError; import com.oracle.svm.core.SubstrateDiagnostics; +import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.code.FactoryMethodMarker; import com.oracle.svm.core.heap.RestrictHeapAccess; import com.oracle.svm.core.jdk.InternalVMMethod; @@ -157,8 +158,10 @@ public static void deactivateImplicitExceptionsAreFatal() { implicitExceptionsAreFatal.set(implicitExceptionsAreFatal.get() - 1); } - private static void vmErrorIfImplicitExceptionsAreFatal() { - if ((implicitExceptionsAreFatal.get() > 0 || ExceptionUnwind.exceptionsAreFatal()) && !SubstrateDiagnostics.isFatalErrorHandlingThread()) { + private static void vmErrorIfImplicitExceptionsAreFatal(boolean cachedException) { + if (cachedException && SubstrateOptions.ImplicitExceptionWithoutStacktraceIsFatal.getValue()) { + throw VMError.shouldNotReachHere("AssertionError without stack trace."); + } else if ((implicitExceptionsAreFatal.get() > 0 || ExceptionUnwind.exceptionsAreFatal()) && !SubstrateDiagnostics.isFatalErrorHandlingThread()) { throw VMError.shouldNotReachHere("Implicit exception thrown in code where such exceptions are fatal errors"); } } @@ -166,21 +169,21 @@ private static void vmErrorIfImplicitExceptionsAreFatal() { /** Foreign call: {@link #CREATE_NULL_POINTER_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static NullPointerException createNullPointerException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new NullPointerException(); } /** Foreign call: {@link #CREATE_OUT_OF_BOUNDS_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArrayIndexOutOfBoundsException createIntrinsicOutOfBoundsException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new ArrayIndexOutOfBoundsException(); } /** Foreign call: {@link #CREATE_OUT_OF_BOUNDS_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArrayIndexOutOfBoundsException createOutOfBoundsException(int index, int length) { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); /* * JDK 11 added the length to the error message, we can do that for all Java versions to be * consistent. @@ -192,7 +195,7 @@ private static ArrayIndexOutOfBoundsException createOutOfBoundsException(int ind @SubstrateForeignCallTarget(stubCallingConvention = true) private static ClassCastException createClassCastException(Object object, Object expectedClass) { assert object != null : "null can be cast to any type, so it cannot show up as a source of a ClassCastException"; - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); String expectedClassName; if (expectedClass instanceof Class) { expectedClassName = ((Class) expectedClass).getTypeName(); @@ -206,84 +209,84 @@ private static ClassCastException createClassCastException(Object object, Object @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArrayStoreException createArrayStoreException(Object value) { assert value != null : "null can be stored into any array, so it cannot show up as a source of an ArrayStoreException"; - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new ArrayStoreException(value.getClass().getTypeName()); } /** Foreign call: {@link #CREATE_INCOMPATIBLE_CLASS_CHANGE_ERROR}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static IncompatibleClassChangeError createIncompatibleClassChangeError() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new IncompatibleClassChangeError(); } /** Foreign call: {@link #CREATE_ILLEGAL_ARGUMENT_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static IllegalArgumentException createIllegalArgumentException(String message) { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new IllegalArgumentException(message); } /** Foreign call: {@link #CREATE_NEGATIVE_ARRAY_SIZE_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static NegativeArraySizeException createNegativeArraySizeException(int length) { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new NegativeArraySizeException(String.valueOf(length)); } /** Foreign call: {@link #CREATE_DIVISION_BY_ZERO_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArithmeticException createDivisionByZeroException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new ArithmeticException("/ by zero"); } /** Foreign call: {@link #CREATE_INTEGER_OVERFLOW_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArithmeticException createIntegerOverflowException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new ArithmeticException("integer overflow"); } /** Foreign call: {@link #CREATE_LONG_OVERFLOW_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArithmeticException createLongOverflowException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new ArithmeticException("long overflow"); } /** Foreign call: {@link #CREATE_ASSERTION_ERROR_NULLARY}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static AssertionError createAssertionErrorNullary() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new AssertionError(); } /** Foreign call: {@link #CREATE_ASSERTION_ERROR_OBJECT}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static AssertionError createAssertionErrorObject(Object detailMessage) { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); return new AssertionError(detailMessage); } /** Foreign call: {@link #THROW_NEW_NULL_POINTER_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewNullPointerException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new NullPointerException(); } /** Foreign call: {@link #THROW_NEW_INTRINSIC_OUT_OF_BOUNDS_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewIntrinsicOutOfBoundsException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new ArrayIndexOutOfBoundsException(); } /** Foreign call: {@link #THROW_NEW_OUT_OF_BOUNDS_EXCEPTION_WITH_ARGS}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewOutOfBoundsExceptionWithArgs(int index, int length) { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); /* * JDK 11 added the length to the error message, we can do that for all Java versions to be * consistent. @@ -294,7 +297,7 @@ private static void throwNewOutOfBoundsExceptionWithArgs(int index, int length) /** Foreign call: {@link #THROW_NEW_CLASS_CAST_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewClassCastException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new ClassCastException(); } @@ -302,7 +305,7 @@ private static void throwNewClassCastException() { @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewClassCastExceptionWithArgs(Object object, Object expectedClass) { assert object != null : "null can be cast to any type, so it cannot show up as a source of a ClassCastException"; - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); String expectedClassName; if (expectedClass instanceof Class) { expectedClassName = ((Class) expectedClass).getTypeName(); @@ -315,7 +318,7 @@ private static void throwNewClassCastExceptionWithArgs(Object object, Object exp /** Foreign call: {@link #THROW_NEW_ARRAY_STORE_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewArrayStoreException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new ArrayStoreException(); } @@ -323,70 +326,70 @@ private static void throwNewArrayStoreException() { @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewArrayStoreExceptionWithArgs(Object value) { assert value != null : "null can be stored into any array, so it cannot show up as a source of an ArrayStoreException"; - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new ArrayStoreException(value.getClass().getTypeName()); } /** Foreign call: {@link #THROW_NEW_INCOMPATIBLE_CLASS_CHANGE_ERROR}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewIncompatibleClassChangeError() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new IncompatibleClassChangeError(); } /** Foreign call: {@link #THROW_NEW_ILLEGAL_ARGUMENT_EXCEPTION_WITH_ARGS}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewIllegalArgumentExceptionWithArgs(String message) { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new IllegalArgumentException(message); } /** Foreign call: {@link #THROW_NEW_NEGATIVE_ARRAY_SIZE_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewNegativeArraySizeException(int length) { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new NegativeArraySizeException(String.valueOf(length)); } /** Foreign call: {@link #THROW_NEW_ARITHMETIC_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewArithmeticException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new ArithmeticException(); } /** Foreign call: {@link #THROW_NEW_DIVISION_BY_ZERO_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewDivisionByZeroException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new ArithmeticException("/ by zero"); } /** Foreign call: {@link #THROW_NEW_INTEGER_OVERFLOW_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewIntegerOverflowException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new ArithmeticException("integer overflow"); } /** Foreign call: {@link #THROW_NEW_LONG_OVERFLOW_EXCEPTION}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewLongOverflowException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new ArithmeticException("long overflow"); } /** Foreign call: {@link #THROW_NEW_ASSERTION_ERROR_NULLARY}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewAssertionErrorNullary() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new AssertionError(); } /** Foreign call: {@link #THROW_NEW_ASSERTION_ERROR_OBJECT}. */ @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwNewAssertionErrorObject(Object detailMessage) { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(false); throw new AssertionError(detailMessage); } @@ -394,7 +397,7 @@ private static void throwNewAssertionErrorObject(Object detailMessage) { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static NullPointerException getCachedNullPointerException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_NULL_POINTER_EXCEPTION; } @@ -402,7 +405,7 @@ private static NullPointerException getCachedNullPointerException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArrayIndexOutOfBoundsException getCachedOutOfBoundsException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_OUT_OF_BOUNDS_EXCEPTION; } @@ -410,7 +413,7 @@ private static ArrayIndexOutOfBoundsException getCachedOutOfBoundsException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static ClassCastException getCachedClassCastException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_CLASS_CAST_EXCEPTION; } @@ -418,7 +421,7 @@ private static ClassCastException getCachedClassCastException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArrayStoreException getCachedArrayStoreException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_ARRAY_STORE_EXCEPTION; } @@ -426,7 +429,7 @@ private static ArrayStoreException getCachedArrayStoreException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static IncompatibleClassChangeError getCachedIncompatibleClassChangeError() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_INCOMPATIBLE_CLASS_CHANGE_ERROR; } @@ -434,7 +437,7 @@ private static IncompatibleClassChangeError getCachedIncompatibleClassChangeErro @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static IllegalArgumentException getCachedIllegalArgumentException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_ILLEGAL_ARGUMENT_EXCEPTION; } @@ -442,7 +445,7 @@ private static IllegalArgumentException getCachedIllegalArgumentException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static NegativeArraySizeException getCachedNegativeArraySizeException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_NEGATIVE_ARRAY_SIZE_EXCEPTION; } @@ -450,7 +453,7 @@ private static NegativeArraySizeException getCachedNegativeArraySizeException() @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static ArithmeticException getCachedArithmeticException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_ARITHMETIC_EXCEPTION; } @@ -458,7 +461,7 @@ private static ArithmeticException getCachedArithmeticException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static AssertionError getCachedAssertionError() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); return CACHED_ASSERTION_ERROR; } @@ -466,7 +469,7 @@ private static AssertionError getCachedAssertionError() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedNullPointerException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_NULL_POINTER_EXCEPTION; } @@ -474,7 +477,7 @@ private static void throwCachedNullPointerException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedOutOfBoundsException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_OUT_OF_BOUNDS_EXCEPTION; } @@ -482,7 +485,7 @@ private static void throwCachedOutOfBoundsException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedClassCastException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_CLASS_CAST_EXCEPTION; } @@ -490,7 +493,7 @@ private static void throwCachedClassCastException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedArrayStoreException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_ARRAY_STORE_EXCEPTION; } @@ -498,7 +501,7 @@ private static void throwCachedArrayStoreException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedIncompatibleClassChangeError() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_INCOMPATIBLE_CLASS_CHANGE_ERROR; } @@ -506,7 +509,7 @@ private static void throwCachedIncompatibleClassChangeError() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedIllegalArgumentException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_ILLEGAL_ARGUMENT_EXCEPTION; } @@ -514,7 +517,7 @@ private static void throwCachedIllegalArgumentException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedNegativeArraySizeException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_NEGATIVE_ARRAY_SIZE_EXCEPTION; } @@ -522,7 +525,7 @@ private static void throwCachedNegativeArraySizeException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedArithmeticException() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_ARITHMETIC_EXCEPTION; } @@ -530,7 +533,7 @@ private static void throwCachedArithmeticException() { @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Called to report an implicit exception in code that must not allocate.") @SubstrateForeignCallTarget(stubCallingConvention = true) private static void throwCachedAssertionError() { - vmErrorIfImplicitExceptionsAreFatal(); + vmErrorIfImplicitExceptionsAreFatal(true); throw CACHED_ASSERTION_ERROR; }