From 1f743eefc73acb991036ebca7fabb0407a57ff57 Mon Sep 17 00:00:00 2001 From: Danil Bubnov Date: Sun, 28 Nov 2021 23:17:57 +0500 Subject: [PATCH 1/3] Add stack alignment and MacOS specific code --- .../AArch64HotSpotJVMCIBackendFactory.java | 2 +- .../aarch64/AArch64HotSpotRegisterConfig.java | 27 +++++++++++++++---- .../aarch64/AArch64HotSpotVMConfig.java | 1 + 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java index e18c819393cd4..19f8f85a34ef1 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java @@ -94,7 +94,7 @@ private static RegisterConfig createRegisterConfig(AArch64HotSpotVMConfig config // and Darwin use it for such. Linux doesn't assign it and thus r18 can // be used as an additional register. boolean canUsePlatformRegister = config.linuxOs; - return new AArch64HotSpotRegisterConfig(target, config.useCompressedOops, canUsePlatformRegister); + return new AArch64HotSpotRegisterConfig(target, config.useCompressedOops, canUsePlatformRegister, config.macOs); } protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java index 72b13ff6ac6f6..ce687b5637eff 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java @@ -116,6 +116,8 @@ public RegisterAttributes[] getAttributesMap() { private final RegisterArray nativeGeneralParameterRegisters = new RegisterArray(r0, r1, r2, r3, r4, r5, r6, r7); private final RegisterArray simdParameterRegisters = new RegisterArray(v0, v1, v2, v3, v4, v5, v6, v7); + private final boolean macOS; + public static final Register inlineCacheRegister = rscratch2; /** @@ -162,13 +164,14 @@ private static RegisterArray initAllocatable(Architecture arch, boolean reserveF return new RegisterArray(registers); } - public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean canUsePlatformRegister) { - this(target, initAllocatable(target.arch, useCompressedOops, canUsePlatformRegister)); + public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean canUsePlatformRegister, boolean macOs) { + this(target, initAllocatable(target.arch, useCompressedOops, canUsePlatformRegister), macOs); assert callerSaved.size() >= allocatable.size(); } - public AArch64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable) { + public AArch64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable, boolean macOs) { this.target = target; + this.macOS = macOs; this.allocatable = allocatable; Set callerSaveSet = new HashSet<>(); @@ -265,11 +268,25 @@ private CallingConvention callingConvention(RegisterArray generalParameterRegist if (locations[i] == null) { ValueKind valueKind = valueKindFactory.getValueKind(kind); + int kindSize = valueKind.getPlatformKind().getSizeInBytes(); + if (macOS && currentStackOffset % kindSize != 0) { + // In MacOS natural alignment is used + // See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms + currentStackOffset += kindSize - currentStackOffset % kindSize; + } locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out); - currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize); + if (macOS) { + // In MacOS "Function arguments may consume slots on the stack that are not multiples of 8 bytes" + // See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms + currentStackOffset += kindSize; + } else { + currentStackOffset += Math.max(kindSize, target.wordSize); + } } } - + if (currentStackOffset % target.stackAlignment != 0) { + currentStackOffset += target.stackAlignment - currentStackOffset % target.stackAlignment; + } JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind(); AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind())); return new CallingConvention(currentStackOffset, returnLocation, locations); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java index fa28dacc6e500..3db49ec86fa24 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java @@ -38,6 +38,7 @@ class AArch64HotSpotVMConfig extends HotSpotVMConfigAccess { } final boolean linuxOs = Services.getSavedProperty("os.name", "").startsWith("Linux"); + final boolean macOs = Services.getSavedProperty("os.name", "").startsWith("Mac"); final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class); From c76331bcd00fef1287c84b913b911635a1f46169 Mon Sep 17 00:00:00 2001 From: Danil Bubnov Date: Sun, 28 Nov 2021 23:22:45 +0500 Subject: [PATCH 2/3] Remove NativeCallTest from ProblemList for macosx-aarch64 --- test/hotspot/jtreg/ProblemList.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 8878a66156262..8b0a0e351c5fc 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -46,7 +46,6 @@ compiler/ciReplay/TestSAServer.java 8029528 generic-all compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java 8225370 generic-all compiler/jvmci/compilerToVM/GetFlagValueTest.java 8204459 generic-all -compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java 8262901 macosx-aarch64 compiler/tiered/LevelTransitionTest.java 8067651 generic-all compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java 8190680 generic-all From 2ff8c0370f0e3515395bcf0b63e3e4df65aed9fa Mon Sep 17 00:00:00 2001 From: Danil Bubnov Date: Thu, 2 Dec 2021 11:16:20 +0500 Subject: [PATCH 3/3] Add test with an odd number of arguments --- .../jdk.vm.ci.code.test/libNativeCallTest.c | 33 +++++++++++++++ .../jdk/vm/ci/code/test/NativeCallTest.java | 40 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/libNativeCallTest.c b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/libNativeCallTest.c index 085fff1cf2768..88dbc92a04e77 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/libNativeCallTest.c +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/libNativeCallTest.c @@ -189,6 +189,39 @@ JNIEXPORT jfloat JNICALL Java_jdk_vm_ci_code_test_NativeCallTest__1L32SDILDS(JNI a, b, c, d, e, f); } +jint JNICALL I32I(jint i00, jint i01, jint i02, jint i03, jint i04, jint i05, jint i06, jint i07, + jint i08, jint i09, jint i0a, jint i0b, jint i0c, jint i0d, jint i0e, jint i0f, + jint i10, jint i11, jint i12, jint i13, jint i14, jint i15, jint i16, jint i17, + jint i18, jint i19, jint i1a, jint i1b, jint i1c, jint i1d, jint i1e, jint i1f, + jint a) { + return i00 + i01 + i02 + i03 + i04 + i05 + i06 + i07 + + i08 + i09 + i0a + i0b + i0c + i0d + i0e + i0f + + i10 + i11 + i12 + i13 + i14 + i15 + i16 + i17 + + i18 + i19 + i1a + i1b + i1c + i1d + i1e + i1f + + a; +} + +JNIEXPORT jlong JNICALL Java_jdk_vm_ci_code_test_NativeCallTest_getI32I(JNIEnv *env, jclass clazz) { + return (jlong) (intptr_t) I32I; +} + +JNIEXPORT jint JNICALL Java_jdk_vm_ci_code_test_NativeCallTest__1I32I(JNIEnv *env, jclass clazz, + jint i00, jint i01, jint i02, jint i03, + jint i04, jint i05, jint i06, jint i07, + jint i08, jint i09, jint i0a, jint i0b, + jint i0c, jint i0d, jint i0e, jint i0f, + jint i10, jint i11, jint i12, jint i13, + jint i14, jint i15, jint i16, jint i17, + jint i18, jint i19, jint i1a, jint i1b, + jint i1c, jint i1d, jint i1e, jint i1f, + jint a) { + return I32I(i00, i01, i02, i03, i04, i05, i06, i07, + i08, i09, i0a, i0b, i0c, i0d, i0e, i0f, + i10, i11, i12, i13, i14, i15, i16, i17, + i18, i19, i1a, i1b, i1c, i1d, i1e, i1f, + a); +} + #ifdef __cplusplus } #endif diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java index dce107095d54d..fb60a3980482c 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java @@ -125,6 +125,26 @@ public void testI32SDILDS() { test("I32SDILDS", getI32SDILDS(), float.class, argClazz, argValues); } + @Test + public void testI32I() { + int sCount = 32; + // Pairs of , + Object[] remainingArgs = new Object[]{ + 12, int.class + }; + Class[] argClazz = new Class[sCount + remainingArgs.length / 2]; + Object[] argValues = new Object[sCount + remainingArgs.length / 2]; + for (int i = 0; i < sCount; i++) { + argValues[i] = i; + argClazz[i] = int.class; + } + for (int i = 0; i < remainingArgs.length; i += 2) { + argValues[sCount + i / 2] = remainingArgs[i + 0]; + argClazz[sCount + i / 2] = (Class) remainingArgs[i + 1]; + } + test("I32I", getI32I(), int.class, argClazz, argValues); + } + public void test(String name, long addr, Class returnClazz, Class[] types, Object[] values) { try { test(asm -> { @@ -244,4 +264,24 @@ public static float L32SDILDS(long l00, long l01, long l02, long l03, long l04, l18, l19, l1a, l1b, l1c, l1d, l1e, l1f, a, b, c, d, e, f); } + + public static native long getI32I(); + + public static native int _I32I(int i00, int i01, int i02, int i03, int i04, int i05, int i06, int i07, + int i08, int i09, int i0a, int i0b, int i0c, int i0d, int i0e, int i0f, + int i10, int i11, int i12, int i13, int i14, int i15, int i16, int i17, + int i18, int i19, int i1a, int i1b, int i1c, int i1d, int i1e, int i1f, + int a); + + public static int I32I(int i00, int i01, int i02, int i03, int i04, int i05, int i06, int i07, + int i08, int i09, int i0a, int i0b, int i0c, int i0d, int i0e, int i0f, + int i10, int i11, int i12, int i13, int i14, int i15, int i16, int i17, + int i18, int i19, int i1a, int i1b, int i1c, int i1d, int i1e, int i1f, + int a) { + return _I32I(i00, i01, i02, i03, i04, i05, i06, i07, + i08, i09, i0a, i0b, i0c, i0d, i0e, i0f, + i10, i11, i12, i13, i14, i15, i16, i17, + i18, i19, i1a, i1b, i1c, i1d, i1e, i1f, + a); + } }