diff --git a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp index c5bcc38b5f6..b9a480af7ba 100644 --- a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp @@ -51,6 +51,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // must be non-zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask, @@ -58,12 +61,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp index 03aa1cd6cd7..14e97644575 100644 --- a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp @@ -127,6 +127,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); + if (buffer.blob() == nullptr) { + return nullptr; + } GrowableArray unfiltered_out_regs; int out_arg_bytes = ForeignGlobals::java_calling_convention(out_sig_bt, total_out_args, unfiltered_out_regs); @@ -324,6 +327,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } #ifndef PRODUCT if (lt.is_enabled()) { diff --git a/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp index 5fb9509926f..7175f727437 100644 --- a/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp @@ -51,6 +51,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // must be non-zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask, @@ -58,12 +61,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp index 727ebe2b568..a1c8f46ce2d 100644 --- a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp @@ -128,6 +128,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); + if (buffer.blob() == nullptr) { + return nullptr; + } Register callerSP = R2, // C/C++ uses R2 as TOC, but we can reuse it here tmp = R11_scratch1, // same as shuffle_reg @@ -332,6 +335,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } + #ifndef ABI_ELFv2 // Need to patch the FunctionDescriptor after relocating. address fd_addr = blob->code_begin(); diff --git a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp index fefb40f4b1e..9c4ea56d0c8 100644 --- a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp @@ -52,6 +52,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // must be non-zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask, @@ -59,12 +62,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp index abfea10fd02..142d9d63693 100644 --- a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp @@ -128,6 +128,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); + if (buffer.blob() == nullptr) { + return nullptr; + } GrowableArray unfiltered_out_regs; int out_arg_bytes = ForeignGlobals::java_calling_convention(out_sig_bt, total_out_args, unfiltered_out_regs); @@ -344,6 +347,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } + #ifndef PRODUCT if (lt.is_enabled()) { ResourceMark rm; diff --git a/src/hotspot/cpu/s390/downcallLinker_s390.cpp b/src/hotspot/cpu/s390/downcallLinker_s390.cpp index d3e11104e48..22bd644e2b8 100644 --- a/src/hotspot/cpu/s390/downcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/downcallLinker_s390.cpp @@ -52,6 +52,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_args); int locs_size = 1; //must be non zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, @@ -60,12 +63,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/s390/upcallLinker_s390.cpp b/src/hotspot/cpu/s390/upcallLinker_s390.cpp index 10be41d6c28..20c9b35db62 100644 --- a/src/hotspot/cpu/s390/upcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/upcallLinker_s390.cpp @@ -126,6 +126,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 0); + if (buffer.blob() == nullptr) { + return nullptr; + } Register call_target_address = Z_R1_scratch; @@ -283,6 +286,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } + #ifndef PRODUCT if (lt.is_enabled()) { ResourceMark rm; diff --git a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp index 1a40429b7bd..41039e0cfd8 100644 --- a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp @@ -49,6 +49,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // can not be zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask, @@ -56,12 +59,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp index ca170c5013e..89e7a466264 100644 --- a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp @@ -177,6 +177,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); + if (buffer.blob() == nullptr) { + return nullptr; + } GrowableArray unfiltered_out_regs; int out_arg_bytes = ForeignGlobals::java_calling_convention(out_sig_bt, total_out_args, unfiltered_out_regs); @@ -379,6 +382,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } #ifndef PRODUCT if (lt.is_enabled()) { diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 75cf3fbf2d4..ff449324d7c 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -759,6 +759,10 @@ UpcallStub* UpcallStub::create(const char* name, CodeBuffer* cb, jobject receive MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); blob = new (size) UpcallStub(name, cb, size, receiver, frame_data_offset); } + if (blob == nullptr) { + return nullptr; // caller must handle this + } + // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); diff --git a/src/hotspot/share/prims/nativeEntryPoint.cpp b/src/hotspot/share/prims/nativeEntryPoint.cpp index 69014c9d64c..2dbff08a7cb 100644 --- a/src/hotspot/share/prims/nativeEntryPoint.cpp +++ b/src/hotspot/share/prims/nativeEntryPoint.cpp @@ -78,10 +78,14 @@ JNI_ENTRY(jlong, NEP_makeDowncallStub(JNIEnv* env, jclass _unused, jobject metho output_regs.push(ForeignGlobals::parse_vmstorage(ret_moves_oop->obj_at(i))); } - return (jlong) DowncallLinker::make_downcall_stub(basic_type, pslots, ret_bt, abi, - input_regs, output_regs, - needs_return_buffer, captured_state_mask, - needs_transition)->code_begin(); + RuntimeStub* stub = DowncallLinker::make_downcall_stub(basic_type, pslots, ret_bt, abi, + input_regs, output_regs, + needs_return_buffer, captured_state_mask, + needs_transition); + if (stub == nullptr) { + return 0; + } + return (jlong) stub->code_begin(); JNI_END JNI_ENTRY(jboolean, NEP_freeDowncallStub(JNIEnv* env, jclass _unused, jlong invoker)) diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/NativeEntryPoint.java b/src/java.base/share/classes/jdk/internal/foreign/abi/NativeEntryPoint.java index 51c7304b7c6..e65cee68ac7 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/NativeEntryPoint.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/NativeEntryPoint.java @@ -71,6 +71,9 @@ public class NativeEntryPoint { return NEP_CACHE.get(key, k -> { long downcallStub = makeDowncallStub(methodType, abi, argMoves, returnMoves, needsReturnBuffer, capturedStateMask, needsTransition); + if (downcallStub == 0) { + throw new OutOfMemoryError("Failed to allocate downcall stub"); + } NativeEntryPoint nep = new NativeEntryPoint(methodType, downcallStub); CLEANER.register(nep, () -> freeDowncallStub(downcallStub)); return nep; diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/UpcallLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/UpcallLinker.java index c5d53a4c5fe..272cfc3ca4e 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/UpcallLinker.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/UpcallLinker.java @@ -106,6 +106,9 @@ public class UpcallLinker { doBindings = insertArguments(exactInvoker(doBindings.type()), 0, doBindings); long entryPoint = makeUpcallStub(doBindings, abi, conv, callingSequence.needsReturnBuffer(), callingSequence.returnBufferSize()); + if (entryPoint == 0) { + throw new OutOfMemoryError("Failed to allocate upcall stub"); + } return UpcallStubs.makeUpcall(entryPoint, scope); }; } diff --git a/test/jdk/java/foreign/NativeTestHelper.java b/test/jdk/java/foreign/NativeTestHelper.java index d12593f7b85..1ea45437da1 100644 --- a/test/jdk/java/foreign/NativeTestHelper.java +++ b/test/jdk/java/foreign/NativeTestHelper.java @@ -175,9 +175,13 @@ public class NativeTestHelper { } public static MemorySegment upcallStub(Class holder, String name, FunctionDescriptor descriptor) { + return upcallStub(holder, name, descriptor, Arena.ofAuto()); + } + + public static MemorySegment upcallStub(Class holder, String name, FunctionDescriptor descriptor, Arena arena) { try { MethodHandle target = MethodHandles.lookup().findStatic(holder, name, descriptor.toMethodType()); - return LINKER.upcallStub(target, descriptor, Arena.ofAuto()); + return LINKER.upcallStub(target, descriptor, arena); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } diff --git a/test/jdk/java/foreign/TestAddressDereference.java b/test/jdk/java/foreign/TestAddressDereference.java index 6dc9575e5ae..3ebec596263 100644 --- a/test/jdk/java/foreign/TestAddressDereference.java +++ b/test/jdk/java/foreign/TestAddressDereference.java @@ -128,6 +128,7 @@ public class TestAddressDereference extends UpcallTestHelper { if (!badAlign) return; runInNewProcess(UpcallTestRunner.class, true, new String[] {Long.toString(alignment), layout.toString() }) + .assertFailed() .assertStdErrContains("alignment constraint for address"); } diff --git a/test/jdk/java/foreign/TestStubAllocFailure.java b/test/jdk/java/foreign/TestStubAllocFailure.java new file mode 100644 index 00000000000..d3a1ef6e3de --- /dev/null +++ b/test/jdk/java/foreign/TestStubAllocFailure.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @library ../ /test/lib + * @requires jdk.foreign.linker != "FALLBACK" + * @run testng/othervm/native + * --enable-native-access=ALL-UNNAMED + * TestStubAllocFailure + */ + +import java.lang.foreign.*; +import java.io.IOException; +import java.util.List; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +public class TestStubAllocFailure extends UpcallTestHelper { + + @Test + public void testUpcallAllocFailure() throws IOException, InterruptedException { + runInNewProcess(UpcallRunner.class, true, List.of("-XX:ReservedCodeCacheSize=3M"), List.of()) + .assertSuccess(); + } + + public static class UpcallRunner extends NativeTestHelper { + public static void main(String[] args) throws Throwable { + try (Arena arena = Arena.ofConfined()) { + while (true) { + // allocate stubs until we crash + upcallStub(UpcallRunner.class, "target", FunctionDescriptor.ofVoid(), arena); + } + } catch (OutOfMemoryError e) { + assertTrue(e.getMessage().contains("Failed to allocate upcall stub")); + } + } + + public static void target() { + fail("Should not get here"); + } + } +} diff --git a/test/jdk/java/foreign/TestUpcallException.java b/test/jdk/java/foreign/TestUpcallException.java index fa922b9fb39..f7dca7bc19c 100644 --- a/test/jdk/java/foreign/TestUpcallException.java +++ b/test/jdk/java/foreign/TestUpcallException.java @@ -48,6 +48,7 @@ public class TestUpcallException extends UpcallTestHelper { @Test(dataProvider = "exceptionCases") public void testException(Class target, boolean useSpec) throws InterruptedException, IOException { runInNewProcess(target, useSpec) + .assertFailed() .assertStdErrContains("Testing upcall exceptions"); } diff --git a/test/jdk/java/foreign/UpcallTestHelper.java b/test/jdk/java/foreign/UpcallTestHelper.java index 2939c4bfd37..e24c35e498c 100644 --- a/test/jdk/java/foreign/UpcallTestHelper.java +++ b/test/jdk/java/foreign/UpcallTestHelper.java @@ -22,25 +22,37 @@ */ import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.Utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; public class UpcallTestHelper extends NativeTestHelper { - public record Output(List stdout, List stderr) { + public record Output(int result, List stdout, List stderr) { private static void assertContains(List lines, String shouldInclude, String name) { assertTrue(lines.stream().anyMatch(line -> line.contains(shouldInclude)), "Did not find '" + shouldInclude + "' in " + name); } + public Output assertFailed() { + assertNotEquals(result, 0); + return this; + } + + public Output assertSuccess() { + assertEquals(result, 0); + return this; + } + public Output assertStdErrContains(String shouldInclude) { assertContains(stderr, shouldInclude, "stderr"); return this; @@ -53,27 +65,33 @@ public class UpcallTestHelper extends NativeTestHelper { } public Output runInNewProcess(Class target, boolean useSpec, String... programArgs) throws IOException, InterruptedException { + return runInNewProcess(target, useSpec, List.of(), List.of(programArgs)); + } + + public Output runInNewProcess(Class target, boolean useSpec, List vmArgs, List programArgs) throws IOException, InterruptedException { assert !target.isArray(); List command = new ArrayList<>(List.of( "--enable-native-access=ALL-UNNAMED", "-Djava.library.path=" + System.getProperty("java.library.path"), - "-Djdk.internal.foreign.UpcallLinker.USE_SPEC=" + useSpec, - target.getName() + "-Djdk.internal.foreign.UpcallLinker.USE_SPEC=" + useSpec )); - command.addAll(Arrays.asList(programArgs)); + command.addAll(vmArgs); + command.add(target.getName()); + command.addAll(programArgs); Process process = ProcessTools.createTestJavaProcessBuilder(command).start(); - int result = process.waitFor(); - assertNotEquals(result, 0); + long timeOut = (long) (Utils.TIMEOUT_FACTOR * 1L); + boolean completed = process.waitFor(timeOut, TimeUnit.MINUTES); + assertTrue(completed, "Time out while waiting for process"); List outLines = linesFromStream(process.getInputStream()); outLines.forEach(System.out::println); List errLines = linesFromStream(process.getErrorStream()); errLines.forEach(System.err::println); - return new Output(outLines, errLines); + return new Output(process.exitValue(), outLines, errLines); } private static List linesFromStream(InputStream stream) throws IOException { diff --git a/test/jdk/java/foreign/critical/TestCriticalUpcall.java b/test/jdk/java/foreign/critical/TestCriticalUpcall.java index fe19720bf93..c2f2d5572c1 100644 --- a/test/jdk/java/foreign/critical/TestCriticalUpcall.java +++ b/test/jdk/java/foreign/critical/TestCriticalUpcall.java @@ -43,7 +43,7 @@ public class TestCriticalUpcall extends UpcallTestHelper { @Test public void testUpcallFailure() throws IOException, InterruptedException { // test to see if we catch a trivial downcall doing an upcall - runInNewProcess(Runner.class, true).assertStdOutContains("wrong thread state for upcall"); + runInNewProcess(Runner.class, true).assertFailed().assertStdOutContains("wrong thread state for upcall"); } public static class Runner extends NativeTestHelper { diff --git a/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java b/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java index d78e1a293d7..5f97dbf288d 100644 --- a/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java +++ b/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java @@ -53,7 +53,7 @@ public class TestPassHeapSegment extends UpcallTestHelper { @Test(dataProvider = "specs") public void testNoHeapReturns(boolean spec) throws IOException, InterruptedException { - runInNewProcess(Runner.class, spec).assertStdErrContains("Heap segment not allowed"); + runInNewProcess(Runner.class, spec).assertFailed().assertStdErrContains("Heap segment not allowed"); } public static class Runner {