diff --git a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp index 68fe831f48c..2da44a4e308 100644 --- a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp @@ -201,7 +201,9 @@ void DowncallStubGenerator::generate() { __ enter(); // return address and rbp are already in place - __ subptr(rsp, allocated_frame_size); // prolog + if (allocated_frame_size > 0) { + __ subptr(rsp, allocated_frame_size); // prolog + } _frame_complete = __ pc() - start; diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java index 0a2669c3726..59224022e74 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java @@ -116,7 +116,7 @@ public class CallArranger { csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout)); } - if (!forUpcall) { + if (!forUpcall && options.isVariadicFunction()) { //add extra binding for number of used vector registers (used for variadic calls) csb.addArgumentBindings(long.class, C_LONG, List.of(vmStore(rax, long.class))); @@ -129,7 +129,9 @@ public class CallArranger { Bindings bindings = getBindings(mt, cDesc, false, options); MethodHandle handle = new DowncallLinker(CSysV, bindings.callingSequence).getBoundMethodHandle(); - handle = MethodHandles.insertArguments(handle, handle.type().parameterCount() - 1, bindings.nVectorArgs); + if (options.isVariadicFunction()) { + handle = MethodHandles.insertArguments(handle, handle.type().parameterCount() - 1, bindings.nVectorArgs); + } if (bindings.isInMemoryReturn) { handle = SharedUtils.adaptDowncallForIMR(handle, cDesc, bindings.callingSequence); diff --git a/test/jdk/java/foreign/callarranger/TestSysVCallArranger.java b/test/jdk/java/foreign/callarranger/TestSysVCallArranger.java index 1405feb04a4..ceb23f7ea06 100644 --- a/test/jdk/java/foreign/callarranger/TestSysVCallArranger.java +++ b/test/jdk/java/foreign/callarranger/TestSysVCallArranger.java @@ -71,12 +71,11 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, - { vmStore(rax, long.class) } }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -99,14 +98,13 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, { dup(), bufferLoad(0, long.class), vmStore(rdi, long.class), bufferLoad(8, int.class), vmStore(rsi, int.class)}, - { vmStore(rax, long.class) }, }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -130,14 +128,13 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, { dup(), bufferLoad(0, long.class), vmStore(rdi, long.class), bufferLoad(8, long.class), vmStore(rsi, long.class)}, - { vmStore(rax, long.class) }, }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -155,8 +152,8 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, @@ -166,7 +163,6 @@ public class TestSysVCallArranger extends CallArrangerTestBase { { vmStore(rcx, int.class) }, { vmStore(r8, int.class) }, { vmStore(r9, int.class) }, - { vmStore(rax, long.class) }, }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -186,8 +182,8 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, @@ -199,7 +195,6 @@ public class TestSysVCallArranger extends CallArrangerTestBase { { vmStore(xmm5, double.class) }, { vmStore(xmm6, double.class) }, { vmStore(xmm7, double.class) }, - { vmStore(rax, long.class) }, }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -221,8 +216,8 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, @@ -244,7 +239,6 @@ public class TestSysVCallArranger extends CallArrangerTestBase { { vmStore(xmm7, float.class) }, { vmStore(stackStorage(STACK_SLOT_SIZE, 16), float.class) }, { vmStore(stackStorage(STACK_SLOT_SIZE, 24), float.class) }, - { vmStore(rax, long.class) }, }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -278,8 +272,8 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, @@ -297,7 +291,6 @@ public class TestSysVCallArranger extends CallArrangerTestBase { { vmStore(r9, int.class) }, { vmStore(stackStorage(STACK_SLOT_SIZE, 0), int.class) }, { vmStore(stackStorage(STACK_SLOT_SIZE, 8), int.class) }, - { vmStore(rax, long.class) }, }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -321,13 +314,12 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, { unboxAddress(), vmStore(rdi, long.class) }, - { vmStore(rax, long.class) }, }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -343,13 +335,12 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, expectedBindings, - { vmStore(rax, long.class) }, }); checkReturnBindings(callingSequence, new Binding[]{}); @@ -402,13 +393,12 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertFalse(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), mt.appendParameterTypes(long.class).insertParameterTypes(0, MemorySegment.class, MemorySegment.class)); - assertEquals(callingSequence.functionDesc(), fd.appendArgumentLayouts(C_LONG).insertArgumentLayouts(0, ADDRESS, ADDRESS)); + assertEquals(callingSequence.callerMethodType(), mt.insertParameterTypes(0, MemorySegment.class, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), fd.insertArgumentLayouts(0, ADDRESS, ADDRESS)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(RETURN_BUFFER_STORAGE, long.class) }, { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, - { vmStore(rax, long.class) } }); checkReturnBindings(callingSequence, new Binding[] { @@ -434,13 +424,12 @@ public class TestSysVCallArranger extends CallArrangerTestBase { assertTrue(bindings.isInMemoryReturn()); CallingSequence callingSequence = bindings.callingSequence(); - assertEquals(callingSequence.callerMethodType(), MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class, long.class)); - assertEquals(callingSequence.functionDesc(), FunctionDescriptor.ofVoid(ADDRESS, C_POINTER, C_LONG)); + assertEquals(callingSequence.callerMethodType(), MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class)); + assertEquals(callingSequence.functionDesc(), FunctionDescriptor.ofVoid(ADDRESS, C_POINTER)); checkArgumentBindings(callingSequence, new Binding[][]{ { unboxAddress(), vmStore(TARGET_ADDRESS_STORAGE, long.class) }, - { unboxAddress(), vmStore(rdi, long.class) }, - { vmStore(rax, long.class) } + { unboxAddress(), vmStore(rdi, long.class) } }); checkReturnBindings(callingSequence, new Binding[] {});