@@ -207,14 +207,52 @@ protected ExceptionAction lookupAction(OptionValues values, Throwable cause) {
207207 return ExitVM ;
208208 }
209209 // Automatically exit on failure when assertions are enabled in libgraal
210- if (IS_IN_NATIVE_IMAGE && (cause instanceof AssertionError || cause instanceof GraalError ) && Assertions . assertionsEnabled ( )) {
210+ if (shouldExitVM (cause )) {
211211 TTY .println ("Treating CompilationFailureAction as ExitVM due to assertion failure in libgraal: " + cause );
212212 return ExitVM ;
213213 }
214214 }
215215 return super .lookupAction (values , cause );
216216 }
217217
218+ /**
219+ * Determines if {@code throwable} should result in a VM exit.
220+ */
221+ private static boolean shouldExitVM (Throwable throwable ) {
222+ // If not in libgraal, don't exit
223+ if (!IS_IN_NATIVE_IMAGE ) {
224+ return false ;
225+ }
226+ // If assertions are not enabled, don't exit.
227+ if (!Assertions .assertionsEnabled ()) {
228+ return false ;
229+ }
230+ // A normal assertion error => exit.
231+ if (throwable instanceof AssertionError ) {
232+ return true ;
233+ }
234+ // A GraalError not caused by an OOME => exit.
235+ if (throwable instanceof GraalError && isNotCausedByOOME (throwable )) {
236+ return true ;
237+ }
238+ return false ;
239+ }
240+
241+ /**
242+ * Determines if {@code throwable} has a causality chain denoting an OutOfMemoryError. This
243+ * can happen in GC stress tests and exiting the VM would cause the test to fail.
244+ */
245+ private static boolean isNotCausedByOOME (Throwable throwable ) {
246+ Throwable t = throwable ;
247+ while (t != null ) {
248+ if (t instanceof OutOfMemoryError ) {
249+ return false ;
250+ }
251+ t = t .getCause ();
252+ }
253+ return true ;
254+ }
255+
218256 @ SuppressWarnings ("try" )
219257 @ Override
220258 protected HotSpotCompilationRequestResult performCompilation (DebugContext debug ) {
0 commit comments