diff --git a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp index 9f740098e19..9c9d78e8d29 100644 --- a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -90,7 +90,8 @@ public: } }; -static const int native_invoker_code_size = 1024; +static const int native_invoker_code_base_size = 256; +static const int native_invoker_size_per_arg = 8; RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int num_args, @@ -100,8 +101,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& output_registers, bool needs_return_buffer, int captured_state_mask) { - int locs_size = 64; - CodeBuffer code("nep_invoker_blob", native_invoker_code_size, locs_size); + 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); DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask); diff --git a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp index 9856fbdbdc3..57cc9fe6274 100644 --- a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -114,6 +114,9 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr __ block_comment("} restore_callee_saved_regs "); } +static const int upcall_stub_code_base_size = 1024; +static const int upcall_stub_size_per_arg = 16; + address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, BasicType* in_sig_bt, int total_in_args, BasicType* out_sig_bt, int total_out_args, @@ -123,7 +126,8 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, ResourceMark rm; const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi); const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); - CodeBuffer buffer("upcall_stub", /* code_size = */ 2048, /* locs_size = */ 1024); + int code_size = upcall_stub_code_base_size + (total_in_args * upcall_stub_size_per_arg); + CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); Register shuffle_reg = r19; JavaCallingConvention out_conv; @@ -325,6 +329,8 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const char* name = "upcall_stub"; #endif // PRODUCT + buffer.log_section_sizes(name); + UpcallStub* blob = UpcallStub::create(name, &buffer, diff --git a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp index 06f8473403b..a702f248515 100644 --- a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -91,7 +91,8 @@ public: } }; -static const int native_invoker_code_size = 1024; +static const int native_invoker_code_base_size = 256; +static const int native_invoker_size_per_arg = 8; RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int num_args, @@ -101,8 +102,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& output_registers, bool needs_return_buffer, int captured_state_mask) { - int locs_size = 64; - CodeBuffer code("nep_invoker_blob", native_invoker_code_size, locs_size); + 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); DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask); diff --git a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp index e2322261c45..6d605d716af 100644 --- a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -114,6 +114,9 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr __ block_comment("} restore_callee_saved_regs "); } +static const int upcall_stub_code_base_size = 2048; +static const int upcall_stub_size_per_arg = 16; + address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, BasicType* in_sig_bt, int total_in_args, BasicType* out_sig_bt, int total_out_args, @@ -124,7 +127,8 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, ResourceMark rm; const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi); const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); - CodeBuffer buffer("upcall_stub", /* code_size = */ 2048, /* locs_size = */ 1024); + int code_size = upcall_stub_code_base_size + (total_in_args * upcall_stub_size_per_arg); + CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); Register shuffle_reg = x9; JavaCallingConvention out_conv; @@ -343,6 +347,8 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const char* name = "upcall_stub"; #endif // PRODUCT + buffer.log_section_sizes(name); + UpcallStub* blob = UpcallStub::create(name, &buffer, diff --git a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp index 9637057b6ab..654e55b4d84 100644 --- a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -89,7 +89,8 @@ public: } }; -static const int native_invoker_code_size = 1024; +static const int native_invoker_code_base_size = 512; +static const int native_invoker_size_per_arg = 8; RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int num_args, @@ -99,8 +100,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& output_registers, bool needs_return_buffer, int captured_state_mask) { - int locs_size = 64; - CodeBuffer code("nep_invoker_blob", native_invoker_code_size, locs_size); + 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); DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask); diff --git a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp index 3e3214b51b1..dfce6aef52d 100644 --- a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -165,6 +165,9 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr __ block_comment("} restore_callee_saved_regs "); } +static const int upcall_stub_code_base_size = 2048; +static const int upcall_stub_size_per_arg = 16; + address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, BasicType* in_sig_bt, int total_in_args, BasicType* out_sig_bt, int total_out_args, @@ -173,7 +176,8 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, bool needs_return_buffer, int ret_buf_size) { const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi); const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); - CodeBuffer buffer("upcall_stub", /* code_size = */ 2048, /* locs_size = */ 1024); + int code_size = upcall_stub_code_base_size + (total_in_args * upcall_stub_size_per_arg); + CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); VMStorage shuffle_reg = as_VMStorage(rbx); JavaCallingConvention out_conv; @@ -386,6 +390,8 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const char* name = "upcall_stub"; #endif // PRODUCT + buffer.log_section_sizes(name); + UpcallStub* blob = UpcallStub::create(name, &buffer, diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index f3b665220de..13b5c740d27 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -998,12 +998,12 @@ void CodeBuffer::log_section_sizes(const char* name) { if (xtty != NULL) { ttyLocker ttyl; // log info about buffer usage - xtty->print_cr("", name, _total_size); + xtty->print_cr("", name, _total_size); for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) { CodeSection* sect = code_section(n); if (!sect->is_allocated() || sect->is_empty()) continue; - xtty->print_cr("", - n, sect->limit() - sect->start(), sect->limit() - sect->end()); + xtty->print_cr("", + n, sect->capacity(), sect->size(), sect->remaining()); } xtty->print_cr(""); } diff --git a/test/jdk/java/foreign/largestub/TestLargeStub.java b/test/jdk/java/foreign/largestub/TestLargeStub.java new file mode 100644 index 00000000000..74e028ecd8b --- /dev/null +++ b/test/jdk/java/foreign/largestub/TestLargeStub.java @@ -0,0 +1,57 @@ +/* + * 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 + * @enablePreview + * @library ../ + * @requires ((os.arch == "amd64" | os.arch == "x86_64") & sun.arch.data.model == "64") | os.arch == "aarch64" | os.arch == "riscv64" + * @modules java.base/jdk.internal.foreign + * @run testng/othervm --enable-native-access=ALL-UNNAMED TestLargeStub + */ + +import org.testng.annotations.Test; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.util.stream.Stream; + +public class TestLargeStub extends NativeTestHelper { + @Test + public void testDowncall() { + // Link a handle with a large number of arguments, to try and overflow the code buffer + Linker.nativeLinker().downcallHandle( + FunctionDescriptor.of(C_LONG_LONG, + Stream.generate(() -> C_DOUBLE).limit(50).toArray(MemoryLayout[]::new)), + Linker.Option.captureCallState("errno")); + } + + @Test + public void testUpcall() { + // Link a handle with a large number of arguments, to try and overflow the code buffer + Linker.nativeLinker().downcallHandle( + FunctionDescriptor.of(C_LONG_LONG, + Stream.generate(() -> C_DOUBLE).limit(50).toArray(MemoryLayout[]::new))); + } +}