From daffdcb7a458e496547b219d19d70d97fbc74524 Mon Sep 17 00:00:00 2001 From: Cheng Jin Date: Mon, 10 Jan 2022 21:37:08 -0500 Subject: [PATCH] Implement the CLinker downcall handle of JEP389/419 on PPC64/S390 The changes aim to enable the CLinker downcall handle to support primitives and struct on AIX/ppc64, Linux/ppc64le and Linux/s390x by invoking the code in ProgrammableInvoker implemented in OpenJ9. Signed-off-by: Cheng Jin --- .../jdk/incubator/foreign/CLinker.java | 12 +- .../classes/jdk/incubator/foreign/VaList.java | 14 +- .../classes/jdk/internal/foreign/CABI.java | 22 +- .../jdk/internal/foreign/PlatformLayouts.java | 189 +++++++++++++++++- .../jdk/internal/foreign/SystemLookup.java | 13 +- .../jdk/internal/foreign/abi/SharedUtils.java | 22 ++ .../foreign/abi/aarch64/CallArranger.java | 11 +- .../foreign/abi/ppc64/aix/AixPPC64Linker.java | 106 ++++++++++ .../foreign/abi/ppc64/aix/AixPPC64VaList.java | 148 ++++++++++++++ .../foreign/abi/ppc64/aix/CallArranger.java | 59 ++++++ .../foreign/abi/ppc64/sysv/CallArranger.java | 59 ++++++ .../abi/ppc64/sysv/SysVPPC64leLinker.java | 105 ++++++++++ .../abi/ppc64/sysv/SysVPPC64leVaList.java | 148 ++++++++++++++ .../foreign/abi/s390x/sysv/CallArranger.java | 60 ++++++ .../abi/s390x/sysv/SysVS390xLinker.java | 106 ++++++++++ .../abi/s390x/sysv/SysVS390xVaList.java | 149 ++++++++++++++ .../foreign/abi/x64/sysv/CallArranger.java | 11 +- .../foreign/abi/x64/windows/CallArranger.java | 11 +- 18 files changed, 1214 insertions(+), 31 deletions(-) create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64Linker.java create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64VaList.java create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/CallArranger.java create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/CallArranger.java create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leLinker.java create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leVaList.java create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/CallArranger.java create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xLinker.java create mode 100644 src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xVaList.java diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java index 4ba44bd2dc6..847b5613453 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java @@ -23,12 +23,22 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.incubator.foreign; import jdk.internal.foreign.SystemLookup; import jdk.internal.foreign.abi.SharedUtils; import jdk.internal.foreign.abi.aarch64.linux.LinuxAArch64Linker; import jdk.internal.foreign.abi.aarch64.macos.MacOsAArch64Linker; +import jdk.internal.foreign.abi.ppc64.aix.AixPPC64Linker; +import jdk.internal.foreign.abi.ppc64.sysv.SysVPPC64leLinker; +import jdk.internal.foreign.abi.s390x.sysv.SysVS390xLinker; import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker; import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker; import jdk.internal.reflect.CallerSensitive; @@ -142,7 +152,7 @@ * @implSpec * Implementations of this interface are immutable, thread-safe and value-based. */ -public sealed interface CLinker extends SymbolLookup permits Windowsx64Linker, SysVx64Linker, LinuxAArch64Linker, MacOsAArch64Linker { +public sealed interface CLinker extends SymbolLookup permits Windowsx64Linker, SysVx64Linker, LinuxAArch64Linker, MacOsAArch64Linker, SysVPPC64leLinker, SysVS390xLinker, AixPPC64Linker { /** * Returns the C linker for the current platform. diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java index 73ede4e4e9a..a867b2fbd54 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java @@ -23,11 +23,21 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.incubator.foreign; import jdk.internal.foreign.abi.SharedUtils; import jdk.internal.foreign.abi.aarch64.linux.LinuxAArch64VaList; import jdk.internal.foreign.abi.aarch64.macos.MacOsAArch64VaList; +import jdk.internal.foreign.abi.ppc64.aix.AixPPC64VaList; +import jdk.internal.foreign.abi.ppc64.sysv.SysVPPC64leVaList; +import jdk.internal.foreign.abi.s390x.sysv.SysVS390xVaList; import jdk.internal.foreign.abi.x64.sysv.SysVVaList; import jdk.internal.foreign.abi.x64.windows.WinVaList; import jdk.internal.reflect.CallerSensitive; @@ -56,7 +66,7 @@ *

Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null} * elements to a method in this class causes a {@link NullPointerException NullPointerException} to be thrown.

*/ -sealed public interface VaList extends Addressable permits WinVaList, SysVVaList, LinuxAArch64VaList, MacOsAArch64VaList, SharedUtils.EmptyVaList { +sealed public interface VaList extends Addressable permits WinVaList, SysVVaList, LinuxAArch64VaList, MacOsAArch64VaList, SysVPPC64leVaList, SysVS390xVaList, AixPPC64VaList, SharedUtils.EmptyVaList { /** * Reads the next value as an {@code int} and advances this variable argument list's position. The behavior of this @@ -223,7 +233,7 @@ static VaList empty() { *

Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null} * elements to a method in this class causes a {@link NullPointerException NullPointerException} to be thrown.

*/ - sealed interface Builder permits WinVaList.Builder, SysVVaList.Builder, LinuxAArch64VaList.Builder, MacOsAArch64VaList.Builder { + sealed interface Builder permits WinVaList.Builder, SysVVaList.Builder, LinuxAArch64VaList.Builder, MacOsAArch64VaList.Builder, SysVPPC64leVaList.Builder, SysVS390xVaList.Builder, AixPPC64VaList.Builder { /** * Writes an {@code int} value to the variable argument list being constructed. diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/CABI.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/CABI.java index 24abdede3be..e50e151cd4c 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/CABI.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/CABI.java @@ -23,6 +23,13 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign; import static jdk.incubator.foreign.ValueLayout.ADDRESS; @@ -32,7 +39,10 @@ public enum CABI { SysV, Win64, LinuxAArch64, - MacOsAArch64; + MacOsAArch64, + SysVPPC64le, + SysVS390x, + AIX; private static final CABI current; @@ -55,7 +65,15 @@ public enum CABI { // The Linux ABI follows the standard AAPCS ABI current = LinuxAArch64; } - } else { + } else if (arch.startsWith("ppc64")) { + if (os.startsWith("Linux")) { + current = SysVPPC64le; + } else { + current = AIX; + } + } else if (arch.equals("s390x") && os.startsWith("Linux")) { + current = SysVS390x; + } else { throw new ExceptionInInitializerError( "Unsupported os, arch, or address size: " + os + ", " + arch + ", " + addressSize); } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/PlatformLayouts.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/PlatformLayouts.java index c18de05c1a5..4fc5ea17f26 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/PlatformLayouts.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/PlatformLayouts.java @@ -23,17 +23,27 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign; import jdk.incubator.foreign.MemoryLayout; import jdk.incubator.foreign.ValueLayout; public class PlatformLayouts { - public static Z pick(Z sysv, Z win64, Z aarch64) { + public static Z pick(Z sysv, Z win64, Z aarch64, Z sysvppc64le, Z sysvs390x, Z aix) { return switch (CABI.current()) { case SysV -> sysv; case Win64 -> win64; case LinuxAArch64, MacOsAArch64 -> aarch64; + case SysVPPC64le -> sysvppc64le; + case SysVS390x -> sysvs390x; + case AIX -> aix; }; } @@ -214,4 +224,181 @@ private AArch64() { */ public static final ValueLayout.OfAddress C_VA_LIST = AArch64.C_POINTER; } + + /** + * This class defines layout constants modelling standard primitive types supported by the PPC64LE SystemV ABI. + */ + public static final class SysVPPC64le { + private SysVPPC64le() { + //just the one + } + + /** + * The {@code bool} native type. + */ + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + + /** + * The {@code char} native type. + */ + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + + /** + * The {@code short} native type. + */ + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT.withBitAlignment(16); + + /** + * The {@code int} native type. + */ + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT.withBitAlignment(32); + + /** + * The {@code long} native type. + */ + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG.withBitAlignment(64); + + /** + * The {@code long long} native type. + */ + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG.withBitAlignment(64); + + /** + * The {@code float} native type. + */ + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT.withBitAlignment(32); + + /** + * The {@code double} native type. + */ + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE.withBitAlignment(64); + + /** + * The {@code T*} native type. + */ + public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64); + + /** + * The {@code va_list} native type, as it is passed to a function. + */ + public static final ValueLayout.OfAddress C_VA_LIST = SysVPPC64le.C_POINTER; + } + + /** + * This class defines layout constants modelling standard primitive types supported by the s390x SystemV ABI. + */ + public static final class SysVS390x { + private SysVS390x() { + //just the one + } + + /** + * The {@code bool} native type. + */ + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + + /** + * The {@code char} native type. + */ + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + + /** + * The {@code short} native type. + */ + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT.withBitAlignment(16); + + /** + * The {@code int} native type. + */ + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT.withBitAlignment(32); + + /** + * The {@code long} native type. + */ + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG.withBitAlignment(64); + + /** + * The {@code long long} native type. + */ + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG.withBitAlignment(64); + + /** + * The {@code float} native type. + */ + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT.withBitAlignment(32); + + /** + * The {@code double} native type. + */ + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE.withBitAlignment(64); + + /** + * The {@code T*} native type. + */ + public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64); + + /** + * The {@code va_list} native type, as it is passed to a function. + */ + public static final ValueLayout.OfAddress C_VA_LIST = SysVS390x.C_POINTER; + } + + /** + * This class defines layout constants modelling standard primitive types supported by the AIX PPC64 ABI. + */ + public static final class AIX { + private AIX() { + //just the one + } + + /** + * The {@code bool} native type. + */ + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + + /** + * The {@code char} native type. + */ + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + + /** + * The {@code short} native type. + */ + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT.withBitAlignment(16); + + /** + * The {@code int} native type. + */ + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT.withBitAlignment(32); + + /** + * The {@code long} native type. + */ + public static final ValueLayout.OfInt C_LONG = ValueLayout.JAVA_INT.withBitAlignment(32); + + /** + * The {@code long long} native type. + */ + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG.withBitAlignment(64); + + /** + * The {@code float} native type. + */ + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT.withBitAlignment(32); + + /** + * The {@code double} native type. + */ + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE.withBitAlignment(64); + + /** + * The {@code T*} native type. + */ + public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64); + + /** + * The {@code va_list} native type, as it is passed to a function. + */ + public static final ValueLayout.OfAddress C_VA_LIST = AIX.C_POINTER; + } } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SystemLookup.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SystemLookup.java index 45c637b06bf..6ff145be8bb 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SystemLookup.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SystemLookup.java @@ -23,6 +23,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign; import jdk.incubator.foreign.MemorySegment; @@ -52,10 +58,15 @@ private SystemLookup() { } * on Windows. For this reason, on Windows we do not generate any side-library, and load msvcrt.dll directly instead. */ private static final SymbolLookup syslookup = switch (CABI.current()) { - case SysV, LinuxAArch64, MacOsAArch64 -> libLookup(libs -> libs.loadLibrary("syslookup")); + case SysV, LinuxAArch64, MacOsAArch64, SysVPPC64le, SysVS390x -> libLookup(libs -> libs.loadLibrary("syslookup")); + case AIX -> makeAixLookup(); case Win64 -> makeWindowsLookup(); // out of line to workaround javac crash }; + private static SymbolLookup makeAixLookup() { // Intended for libc.a on AIX + throw new InternalError("Default library loading is not yet implemented on AIX"); //$NON-NLS-1$ + } + private static SymbolLookup makeWindowsLookup() { Path system32 = Path.of(System.getenv("SystemRoot"), "System32"); Path ucrtbase = system32.resolve("ucrtbase.dll"); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/SharedUtils.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/SharedUtils.java index 967fd203e04..6a09c3d6365 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/SharedUtils.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/SharedUtils.java @@ -22,6 +22,13 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign.abi; import jdk.incubator.foreign.Addressable; @@ -47,6 +54,9 @@ import jdk.internal.foreign.Utils; import jdk.internal.foreign.abi.aarch64.linux.LinuxAArch64Linker; import jdk.internal.foreign.abi.aarch64.macos.MacOsAArch64Linker; +import jdk.internal.foreign.abi.ppc64.aix.AixPPC64Linker; +import jdk.internal.foreign.abi.ppc64.sysv.SysVPPC64leLinker; +import jdk.internal.foreign.abi.s390x.sysv.SysVS390xLinker; import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker; import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker; import jdk.internal.vm.annotation.ForceInline; @@ -275,6 +285,9 @@ public static CLinker getSystemLinker() { case SysV -> SysVx64Linker.getInstance(); case LinuxAArch64 -> LinuxAArch64Linker.getInstance(); case MacOsAArch64 -> MacOsAArch64Linker.getInstance(); + case SysVPPC64le -> SysVPPC64leLinker.getInstance(); + case SysVS390x -> SysVS390xLinker.getInstance(); + case AIX -> AixPPC64Linker.getInstance(); }; } @@ -606,6 +619,9 @@ public static VaList newVaList(Consumer actions, ResourceScope s case SysV -> SysVx64Linker.newVaList(actions, scope); case LinuxAArch64 -> LinuxAArch64Linker.newVaList(actions, scope); case MacOsAArch64 -> MacOsAArch64Linker.newVaList(actions, scope); + case SysVPPC64le -> SysVPPC64leLinker.newVaList(actions, scope); + case SysVS390x -> SysVS390xLinker.newVaList(actions, scope); + case AIX -> AixPPC64Linker.newVaList(actions, scope); }; } @@ -615,6 +631,9 @@ public static VaList newVaListOfAddress(MemoryAddress ma, ResourceScope scope) { case SysV -> SysVx64Linker.newVaListOfAddress(ma, scope); case LinuxAArch64 -> LinuxAArch64Linker.newVaListOfAddress(ma, scope); case MacOsAArch64 -> MacOsAArch64Linker.newVaListOfAddress(ma, scope); + case SysVPPC64le -> SysVPPC64leLinker.newVaListOfAddress(ma, scope); + case SysVS390x -> SysVS390xLinker.newVaListOfAddress(ma, scope); + case AIX -> AixPPC64Linker.newVaListOfAddress(ma, scope); }; } @@ -624,6 +643,9 @@ public static VaList emptyVaList() { case SysV -> SysVx64Linker.emptyVaList(); case LinuxAArch64 -> LinuxAArch64Linker.emptyVaList(); case MacOsAArch64 -> MacOsAArch64Linker.emptyVaList(); + case SysVPPC64le -> SysVPPC64leLinker.emptyVaList(); + case SysVS390x -> SysVS390xLinker.emptyVaList(); + case AIX -> AixPPC64Linker.emptyVaList(); }; } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java index b42b81d4e74..52894032953 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java @@ -26,7 +26,7 @@ /* * =========================================================================== - * (c) Copyright IBM Corp. 2021, 2021 All Rights Reserved + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved * =========================================================================== */ @@ -158,14 +158,9 @@ public MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { return handle; } + /* Replace ProgrammableUpcallHandler in OpenJDK with the implementation of ProgrammableUpcallHandler specific to OpenJ9 */ public NativeSymbol arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) { - Bindings bindings = getBindings(mt, cDesc, true); - - if (bindings.isInMemoryReturn) { - target = SharedUtils.adaptUpcallForIMR(target, true /* drop return, since we don't have bindings for it */); - } - - return ProgrammableUpcallHandler.make(C, target, bindings.callingSequence,scope); + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ } private static boolean isInMemoryReturn(Optional returnLayout) { diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64Linker.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64Linker.java new file mode 100644 index 00000000000..47d90968f31 --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64Linker.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.aix; + + +import jdk.incubator.foreign.CLinker; +import jdk.incubator.foreign.FunctionDescriptor; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.NativeSymbol; +import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.VaList; +import jdk.internal.foreign.abi.SharedUtils; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * ABI implementation based on 64-bit PowerPC ELF ABI + * + * Note: This file is copied from x86/sysv with modification to accommodate the specifics + * on AIX/ppc64le and might be updated accordingly in terms of VaList in the future. + */ +public final class AixPPC64Linker implements CLinker { + private static AixPPC64Linker instance; + + static final long ADDRESS_SIZE = 64; // bits + + public static AixPPC64Linker getInstance() { + if (instance == null) { + instance = new AixPPC64Linker(); + } + return instance; + } + + @Override + public final MethodHandle downcallHandle(FunctionDescriptor function) { + Objects.requireNonNull(function); + MethodType type = SharedUtils.inferMethodType(function, false); + MethodHandle handle = CallArranger.arrangeDowncall(type, function); + if (!type.returnType().equals(MemorySegment.class)) { + // not returning segment, just insert a throwing allocator + handle = MethodHandles.insertArguments(handle, 1, SharedUtils.THROWING_ALLOCATOR); + } + return SharedUtils.wrapDowncall(handle, function); + } + + @Override + public final NativeSymbol upcallStub(MethodHandle target, FunctionDescriptor function, ResourceScope scope) { + Objects.requireNonNull(scope); + Objects.requireNonNull(target); + Objects.requireNonNull(function); + SharedUtils.checkExceptions(target); + MethodType type = SharedUtils.inferMethodType(function, true); + if (!type.equals(target.type())) { + throw new IllegalArgumentException("Wrong method handle type: " + target.type()); + } + return CallArranger.arrangeUpcall(target, target.type(), function, scope); + } + + public static VaList newVaList(Consumer actions, ResourceScope scope) { + AixPPC64VaList.Builder builder = AixPPC64VaList.builder(scope); + actions.accept(builder); + return builder.build(); + } + + public static VaList newVaListOfAddress(MemoryAddress ma, ResourceScope scope) { + return AixPPC64VaList.ofAddress(ma, scope); + } + + public static VaList emptyVaList() { + return AixPPC64VaList.empty(); + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64VaList.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64VaList.java new file mode 100644 index 00000000000..f6c466db0ca --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64VaList.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.aix; + +import jdk.incubator.foreign.*; +import jdk.internal.foreign.ResourceScopeImpl; +import jdk.internal.foreign.Scoped; +import jdk.internal.foreign.Utils; +import jdk.internal.foreign.abi.SharedUtils; +import static jdk.internal.foreign.PlatformLayouts.AIX; + +/** + * This file serves as a placeholder for VaList on AIX/ppc64le as the code + * at Java level is not yet implemented for the moment. Futher analysis on + * the struct is required to understand how the struct is laid out in memory + * according to the description in the publisized ABI document at + * https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.pdf. + */ +public non-sealed class AixPPC64VaList implements VaList, Scoped { + public static final Class CARRIER = MemoryAddress.class; + + public static VaList empty() { + throw new InternalError("empty() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public int nextVarg(ValueLayout.OfInt layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public long nextVarg(ValueLayout.OfLong layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public double nextVarg(ValueLayout.OfDouble layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemoryAddress nextVarg(ValueLayout.OfAddress layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySegment nextVarg(GroupLayout layout, SegmentAllocator allocator) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public void skip(MemoryLayout... layouts) { + throw new InternalError("skip() is not yet implemented"); //$NON-NLS-1$ + } + + public static VaList ofAddress(MemoryAddress ma, ResourceScope scope) { + throw new InternalError("ofAddress() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public ResourceScope scope() { + throw new InternalError("scope() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public VaList copy() { + throw new InternalError("copy() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemoryAddress address() { + throw new InternalError("address() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public String toString() { + throw new InternalError("toString() is not yet implemented"); //$NON-NLS-1$ + } + + static AixPPC64VaList.Builder builder(ResourceScope scope) { + return new AixPPC64VaList.Builder(scope); + } + + public static non-sealed class Builder implements VaList.Builder { + + public Builder(ResourceScope scope) { + throw new InternalError("Builder() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfInt layout, int value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfLong layout, long value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfDouble layout, double value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfAddress layout, Addressable value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(GroupLayout layout, MemorySegment value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + public VaList build() { + throw new InternalError("build() is not yet implemented"); //$NON-NLS-1$ + } + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/CallArranger.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/CallArranger.java new file mode 100644 index 00000000000..e42c4b48595 --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/aix/CallArranger.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.aix; + +import jdk.incubator.foreign.FunctionDescriptor; +import jdk.incubator.foreign.NativeSymbol; +import jdk.internal.foreign.abi.ProgrammableInvoker; +import jdk.internal.foreign.abi.ProgrammableUpcallHandler; +import jdk.incubator.foreign.ResourceScope; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +/** + * For the AIX PPC64 C ABI specifically, this class uses the ProgrammableInvoker API + * which is turned into a MethodHandle to invoke the native code in downcall. + */ +public class CallArranger { + + /* Replace ProgrammableInvoker in OpenJDK with the implementation of ProgrammableInvoker specific to OpenJ9 */ + public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { + MethodHandle handle = ProgrammableInvoker.getBoundMethodHandle(mt, cDesc); + return handle; + } + + /* Replace ProgrammableUpcallHandler in OpenJDK with the implementation of ProgrammableUpcallHandler specific to OpenJ9 */ + public static NativeSymbol arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) { + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/CallArranger.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/CallArranger.java new file mode 100644 index 00000000000..a25dedacc13 --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/CallArranger.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.sysv; + +import jdk.incubator.foreign.FunctionDescriptor; +import jdk.incubator.foreign.NativeSymbol; +import jdk.internal.foreign.abi.ProgrammableInvoker; +import jdk.internal.foreign.abi.ProgrammableUpcallHandler; +import jdk.incubator.foreign.ResourceScope; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +/** + * For the SysV ppc64le C ABI specifically, this class uses the ProgrammableInvoker API + * which is turned into a MethodHandle to invoke the native code. + */ +public class CallArranger { + + /* Replace ProgrammableInvoker in OpenJDK with the implementation of ProgrammableInvoker specific to OpenJ9 */ + public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { + MethodHandle handle = ProgrammableInvoker.getBoundMethodHandle(mt, cDesc); + return handle; + } + + /* Replace ProgrammableUpcallHandler in OpenJDK with the implementation of ProgrammableUpcallHandler specific to OpenJ9 */ + public static NativeSymbol arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) { + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leLinker.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leLinker.java new file mode 100644 index 00000000000..3beeeeb7332 --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leLinker.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.sysv; + +import jdk.incubator.foreign.CLinker; +import jdk.incubator.foreign.FunctionDescriptor; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.NativeSymbol; +import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.VaList; +import jdk.internal.foreign.abi.SharedUtils; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * ABI implementation based on System V ABI PPC64LE + * + * Note: This file is copied from x86/windows with modification to accommodate the specifics + * on Linux/ppc64le and might be updated accordingly in terms of VaList in the future. + */ +public final class SysVPPC64leLinker implements CLinker { + private static SysVPPC64leLinker instance; + + static final long ADDRESS_SIZE = 64; // bits + + public static SysVPPC64leLinker getInstance() { + if (instance == null) { + instance = new SysVPPC64leLinker(); + } + return instance; + } + + @Override + public final MethodHandle downcallHandle(FunctionDescriptor function) { + Objects.requireNonNull(function); + MethodType type = SharedUtils.inferMethodType(function, false); + MethodHandle handle = CallArranger.arrangeDowncall(type, function); + if (!type.returnType().equals(MemorySegment.class)) { + // not returning segment, just insert a throwing allocator + handle = MethodHandles.insertArguments(handle, 1, SharedUtils.THROWING_ALLOCATOR); + } + return SharedUtils.wrapDowncall(handle, function); + } + + @Override + public final NativeSymbol upcallStub(MethodHandle target, FunctionDescriptor function, ResourceScope scope) { + Objects.requireNonNull(scope); + Objects.requireNonNull(target); + Objects.requireNonNull(function); + SharedUtils.checkExceptions(target); + MethodType type = SharedUtils.inferMethodType(function, true); + if (!type.equals(target.type())) { + throw new IllegalArgumentException("Wrong method handle type: " + target.type()); + } + return CallArranger.arrangeUpcall(target, target.type(), function, scope); + } + + public static VaList newVaList(Consumer actions, ResourceScope scope) { + SysVPPC64leVaList.Builder builder = SysVPPC64leVaList.builder(scope); + actions.accept(builder); + return builder.build(); + } + + public static VaList newVaListOfAddress(MemoryAddress ma, ResourceScope scope) { + return SysVPPC64leVaList.ofAddress(ma, scope); + } + + public static VaList emptyVaList() { + return SysVPPC64leVaList.empty(); + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leVaList.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leVaList.java new file mode 100644 index 00000000000..069b4eb42cc --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leVaList.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.sysv; + +import jdk.incubator.foreign.*; +import jdk.internal.foreign.ResourceScopeImpl; +import jdk.internal.foreign.Scoped; +import jdk.internal.foreign.Utils; +import jdk.internal.foreign.abi.SharedUtils; +import static jdk.internal.foreign.PlatformLayouts.SysVPPC64le; + +/** + * This file serves as a placeholder for VaList on Linux/ppc64le as the code + * at Java level is not yet implemented for the moment. Futher analysis on + * the struct is required to understand how the struct is laid out in memory + * (e.g. the type & size of each field in va_list) and how the registers are + * allocated for va_list. + */ +public non-sealed class SysVPPC64leVaList implements VaList, Scoped { + public static final Class CARRIER = MemoryAddress.class; + + public static VaList empty() { + throw new InternalError("empty() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public int nextVarg(ValueLayout.OfInt layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public long nextVarg(ValueLayout.OfLong layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public double nextVarg(ValueLayout.OfDouble layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemoryAddress nextVarg(ValueLayout.OfAddress layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySegment nextVarg(GroupLayout layout, SegmentAllocator allocator) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public void skip(MemoryLayout... layouts) { + throw new InternalError("skip() is not yet implemented"); //$NON-NLS-1$ + } + + public static VaList ofAddress(MemoryAddress ma, ResourceScope scope) { + throw new InternalError("ofAddress() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public ResourceScope scope() { + throw new InternalError("scope() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public VaList copy() { + throw new InternalError("copy() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemoryAddress address() { + throw new InternalError("address() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public String toString() { + throw new InternalError("toString() is not yet implemented"); //$NON-NLS-1$ + } + + static SysVPPC64leVaList.Builder builder(ResourceScope scope) { + return new SysVPPC64leVaList.Builder(scope); + } + + public static non-sealed class Builder implements VaList.Builder { + + public Builder(ResourceScope scope) { + throw new InternalError("Builder() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfInt layout, int value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfLong layout, long value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfDouble layout, double value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfAddress layout, Addressable value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(GroupLayout layout, MemorySegment value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + public VaList build() { + throw new InternalError("build() is not yet implemented"); //$NON-NLS-1$ + } + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/CallArranger.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/CallArranger.java new file mode 100644 index 00000000000..f9f6d66bab9 --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/CallArranger.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.s390x.sysv; + +import jdk.incubator.foreign.FunctionDescriptor; +import jdk.incubator.foreign.NativeSymbol; +import jdk.internal.foreign.abi.ProgrammableInvoker; +import jdk.internal.foreign.abi.ProgrammableUpcallHandler; +import jdk.incubator.foreign.ResourceScope; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +/** + * For the SysV s390 C ABI specifically, this class uses the ProgrammableInvoker API + * which is turned into a MethodHandle to invoke the native code. + */ +public class CallArranger { + + /* Replace ProgrammableInvoker in OpenJDK with the implementation of ProgrammableInvoker specific to OpenJ9 */ + public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { + MethodHandle handle = ProgrammableInvoker.getBoundMethodHandle(mt, cDesc); + return handle; + } + + /* Replace ProgrammableUpcallHandler in OpenJDK with the implementation of ProgrammableUpcallHandler specific to OpenJ9 */ + public static NativeSymbol arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) { + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xLinker.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xLinker.java new file mode 100644 index 00000000000..6db14ecadba --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xLinker.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.s390x.sysv; + + +import jdk.incubator.foreign.CLinker; +import jdk.incubator.foreign.FunctionDescriptor; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.NativeSymbol; +import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.VaList; +import jdk.internal.foreign.abi.SharedUtils; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * ABI implementation based on System V ABI s390x + * + * Note: This file is copied from x86/sysv with modification to accommodate the specifics + * on Linux/s390x and might be updated accordingly in terms of VaList in the future. + */ +public final class SysVS390xLinker implements CLinker { + private static SysVS390xLinker instance; + + static final long ADDRESS_SIZE = 64; // bits + + public static SysVS390xLinker getInstance() { + if (instance == null) { + instance = new SysVS390xLinker(); + } + return instance; + } + + @Override + public final MethodHandle downcallHandle(FunctionDescriptor function) { + Objects.requireNonNull(function); + MethodType type = SharedUtils.inferMethodType(function, false); + MethodHandle handle = CallArranger.arrangeDowncall(type, function); + if (!type.returnType().equals(MemorySegment.class)) { + // not returning segment, just insert a throwing allocator + handle = MethodHandles.insertArguments(handle, 1, SharedUtils.THROWING_ALLOCATOR); + } + return SharedUtils.wrapDowncall(handle, function); + } + + @Override + public final NativeSymbol upcallStub(MethodHandle target, FunctionDescriptor function, ResourceScope scope) { + Objects.requireNonNull(scope); + Objects.requireNonNull(target); + Objects.requireNonNull(function); + SharedUtils.checkExceptions(target); + MethodType type = SharedUtils.inferMethodType(function, true); + if (!type.equals(target.type())) { + throw new IllegalArgumentException("Wrong method handle type: " + target.type()); + } + return CallArranger.arrangeUpcall(target, target.type(), function, scope); + } + + public static VaList newVaList(Consumer actions, ResourceScope scope) { + SysVS390xVaList.Builder builder = SysVS390xVaList.builder(scope); + actions.accept(builder); + return builder.build(); + } + + public static VaList newVaListOfAddress(MemoryAddress ma, ResourceScope scope) { + return SysVS390xVaList.ofAddress(ma, scope); + } + + public static VaList emptyVaList() { + return SysVS390xVaList.empty(); + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xVaList.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xVaList.java new file mode 100644 index 00000000000..85ba2e2babf --- /dev/null +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xVaList.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.s390x.sysv; + +import jdk.incubator.foreign.*; +import jdk.internal.foreign.ResourceScopeImpl; +import jdk.internal.foreign.Scoped; +import jdk.internal.foreign.Utils; +import jdk.internal.foreign.abi.SharedUtils; +import static jdk.internal.foreign.PlatformLayouts.SysVS390x; + +/** + * This file serves as a placeholder for VaList on Linux/s390x as the code + * at Java level is not yet implemented for the moment. Futher analysis on + * the struct is required to understand how the struct is laid out in memory + * (e.g. the type & size of each field in va_list) and how the registers are + * allocated for va_list according to the description in the publisized ABI + * document at https://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_zSeries.pdf. + */ +public non-sealed class SysVS390xVaList implements VaList, Scoped { + public static final Class CARRIER = MemoryAddress.class; + + public static VaList empty() { + throw new InternalError("empty() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public int nextVarg(ValueLayout.OfInt layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public long nextVarg(ValueLayout.OfLong layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public double nextVarg(ValueLayout.OfDouble layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemoryAddress nextVarg(ValueLayout.OfAddress layout) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySegment nextVarg(GroupLayout layout, SegmentAllocator allocator) { + throw new InternalError("nextVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public void skip(MemoryLayout... layouts) { + throw new InternalError("skip() is not yet implemented"); //$NON-NLS-1$ + } + + public static VaList ofAddress(MemoryAddress ma, ResourceScope scope) { + throw new InternalError("ofAddress() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public ResourceScope scope() { + throw new InternalError("scope() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public VaList copy() { + throw new InternalError("copy() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemoryAddress address() { + throw new InternalError("address() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public String toString() { + throw new InternalError("toString() is not yet implemented"); //$NON-NLS-1$ + } + + static SysVS390xVaList.Builder builder(ResourceScope scope) { + return new SysVS390xVaList.Builder(scope); + } + + public static non-sealed class Builder implements VaList.Builder { + + public Builder(ResourceScope scope) { + throw new InternalError("Builder() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfInt layout, int value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfLong layout, long value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfDouble layout, double value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(ValueLayout.OfAddress layout, Addressable value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public Builder addVarg(GroupLayout layout, MemorySegment value) { + throw new InternalError("addVarg() is not yet implemented"); //$NON-NLS-1$ + } + + public VaList build() { + throw new InternalError("build() is not yet implemented"); //$NON-NLS-1$ + } + } +} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java index 1ea771804e7..91e95431bb1 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java @@ -26,7 +26,7 @@ /* * =========================================================================== - * (c) Copyright IBM Corp. 2021, 2021 All Rights Reserved + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved * =========================================================================== */ @@ -133,14 +133,9 @@ public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDe return handle; } + /* Replace ProgrammableUpcallHandler in OpenJDK with the implementation of ProgrammableUpcallHandler specific to OpenJ9 */ public static NativeSymbol arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) { - Bindings bindings = getBindings(mt, cDesc, true); - - if (bindings.isInMemoryReturn) { - target = SharedUtils.adaptUpcallForIMR(target, true /* drop return, since we don't have bindings for it */); - } - - return ProgrammableUpcallHandler.make(CSysV, target, bindings.callingSequence, scope); + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ } private static boolean isInMemoryReturn(Optional returnLayout) { diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/windows/CallArranger.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/windows/CallArranger.java index 3ff6ba41f2b..4a7cb710962 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/windows/CallArranger.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/windows/CallArranger.java @@ -25,7 +25,7 @@ /* * =========================================================================== - * (c) Copyright IBM Corp. 2021, 2021 All Rights Reserved + * (c) Copyright IBM Corp. 2021, 2022 All Rights Reserved * =========================================================================== */ @@ -134,14 +134,9 @@ public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDe return handle; } + /* Replace ProgrammableUpcallHandler in OpenJDK with the implementation of ProgrammableUpcallHandler specific to OpenJ9 */ public static NativeSymbol arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) { - Bindings bindings = getBindings(mt, cDesc, true); - - if (bindings.isInMemoryReturn) { - target = SharedUtils.adaptUpcallForIMR(target, false /* need the return value as well */); - } - - return ProgrammableUpcallHandler.make(CWindows, target, bindings.callingSequence, scope); + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ } private static boolean isInMemoryReturn(Optional returnLayout) {