diff --git a/src/java.base/share/classes/java/lang/foreign/VaList.java b/src/java.base/share/classes/java/lang/foreign/VaList.java index bae18f8b3ed..f81beceb846 100644 --- a/src/java.base/share/classes/java/lang/foreign/VaList.java +++ b/src/java.base/share/classes/java/lang/foreign/VaList.java @@ -23,6 +23,13 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package java.lang.foreign; import java.util.Objects; @@ -31,6 +38,9 @@ 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.javac.PreviewFeature; @@ -57,7 +67,8 @@ * @since 19 */ @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN) -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 { /** * {@return the memory session associated with this variable argument list} @@ -246,7 +257,8 @@ static VaList empty() { * @since 19 */ @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN) - 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/java.base/share/classes/java/lang/invoke/X-VarHandleSegmentView.java.template b/src/java.base/share/classes/java/lang/invoke/X-VarHandleSegmentView.java.template index 303acbdaeae..8445e5aa2c7 100644 --- a/src/java.base/share/classes/java/lang/invoke/X-VarHandleSegmentView.java.template +++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandleSegmentView.java.template @@ -22,6 +22,13 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package java.lang.invoke; import jdk.internal.foreign.AbstractMemorySegmentImpl; @@ -35,6 +42,8 @@ import java.util.Objects; import static java.lang.invoke.MethodHandleStatics.UNSAFE; +import sun.security.action.GetPropertyAction; + #warn final class VarHandleSegmentAs$Type$s extends VarHandleSegmentViewBase { @@ -47,6 +56,8 @@ final class VarHandleSegmentAs$Type$s extends VarHandleSegmentViewBase { static final VarForm FORM = new VarForm(VarHandleSegmentAs$Type$s.class, MemorySegment.class, $type$.class, long.class); + static final boolean isAixOS = GetPropertyAction.privilegedGetProperty("os.name").startsWith("AIX") ? true : false; + VarHandleSegmentAs$Type$s(boolean be, long length, long alignmentMask, boolean exact) { super(FORM, be, length, alignmentMask, exact); } @@ -106,9 +117,17 @@ final class VarHandleSegmentAs$Type$s extends VarHandleSegmentViewBase { @ForceInline static long offset(AbstractMemorySegmentImpl bb, long offset, long alignmentMask) { long address = offsetNoVMAlignCheck(bb, offset, alignmentMask); - if ((address & VM_ALIGN) != 0) { - throw VarHandleSegmentViewBase.newIllegalArgumentExceptionForMisalignedAccess(address); +#if[floatingPoint] + /* Ignore the alignement check for float/double on AIX/PPC to handle the case of [float/int, double] + * given the size of [float/int, double] on AIX/PPC 64-bit is 12 bytes without padding while the + * same struct is 16 bytes with padding on other platforms + */ + if (!isAixOS) { + if ((address & VM_ALIGN) != 0) { + throw VarHandleSegmentViewBase.newIllegalArgumentExceptionForMisalignedAccess(address); + } } +#end[floatingPoint] return address; } @@ -116,10 +135,18 @@ final class VarHandleSegmentAs$Type$s extends VarHandleSegmentViewBase { static long offsetNoVMAlignCheck(AbstractMemorySegmentImpl bb, long offset, long alignmentMask) { long base = bb.unsafeGetOffset(); long address = base + offset; - long maxAlignMask = bb.maxAlignMask(); - if (((address | maxAlignMask) & alignmentMask) != 0) { - throw VarHandleSegmentViewBase.newIllegalArgumentExceptionForMisalignedAccess(address); +#if[floatingPoint] + /* Ignore the alignement check for float/double on AIX/PPC to handle the case of [float/int, double] + * given the size of [float/int, double] on AIX/PPC 64-bit is 12 bytes without padding while the + * same struct is 16 bytes with padding on other platforms + */ + if (!isAixOS) { + long maxAlignMask = bb.maxAlignMask(); + if (((address | maxAlignMask) & alignmentMask) != 0) { + throw VarHandleSegmentViewBase.newIllegalArgumentExceptionForMisalignedAccess(address); + } } +#end[floatingPoint] return address; } diff --git a/src/java.base/share/classes/jdk/internal/foreign/CABI.java b/src/java.base/share/classes/jdk/internal/foreign/CABI.java index 1ab38dbfa96..1dcd031ad72 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/CABI.java +++ b/src/java.base/share/classes/jdk/internal/foreign/CABI.java @@ -23,6 +23,13 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign; import static java.lang.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 UnsupportedOperationException( "Unsupported os, arch, or address size: " + os + ", " + arch + ", " + addressSize); } diff --git a/src/java.base/share/classes/jdk/internal/foreign/LayoutPath.java b/src/java.base/share/classes/jdk/internal/foreign/LayoutPath.java index 6d339f2b882..5bbfcd454b8 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/LayoutPath.java +++ b/src/java.base/share/classes/jdk/internal/foreign/LayoutPath.java @@ -23,6 +23,13 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign; import jdk.internal.vm.annotation.ForceInline; @@ -40,6 +47,8 @@ import java.util.Objects; import java.util.function.UnaryOperator; +import sun.security.action.GetPropertyAction; + /** * This class provide support for constructing layout paths; that is, starting from a root path (see {@link #rootPath(MemoryLayout)}, * a path can be constructed by selecting layout elements using the selector methods provided by this class @@ -52,6 +61,7 @@ public class LayoutPath { private static final MethodHandle MH_ADD_SCALED_OFFSET; private static final MethodHandle MH_SLICE; + private static final boolean isAixOS = GetPropertyAction.privilegedGetProperty("os.name").startsWith("AIX") ? true : false; static { try { @@ -143,7 +153,15 @@ public VarHandle dereferenceHandle() { if (!(layout instanceof ValueLayout valueLayout)) { throw new IllegalArgumentException("Path does not select a value layout"); } - checkAlignment(this); + + /* Ignore the alignement check for float/double on AIX/PPC to handle the case of [float/int, double] + * given the size of [float/int, double] on AIX/PPC 64-bit is 12 bytes without padding while the + * same struct is 16 bytes with padding on other platforms + */ + Class javaType = valueLayout.carrier(); + if (!isAixOS || ((javaType != float.class) && (javaType != double.class))) { + checkAlignment(this); + } VarHandle handle = Utils.makeSegmentViewVarHandle(valueLayout); for (int i = strides.length - 1; i >= 0; i--) { diff --git a/src/java.base/share/classes/jdk/internal/foreign/PlatformLayouts.java b/src/java.base/share/classes/jdk/internal/foreign/PlatformLayouts.java index 4b7c33694df..b64221effb6 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/PlatformLayouts.java +++ b/src/java.base/share/classes/jdk/internal/foreign/PlatformLayouts.java @@ -23,17 +23,27 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign; import java.lang.foreign.MemoryLayout; import java.lang.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/java.base/share/classes/jdk/internal/foreign/SystemLookup.java b/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java index 0e526577c62..19f316287e8 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java +++ b/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java @@ -23,6 +23,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign; import java.lang.foreign.MemoryAddress; @@ -36,6 +42,7 @@ import java.util.Optional; import java.util.function.Function; import jdk.internal.loader.NativeLibrary; +import jdk.internal.loader.NativeLibraries; import jdk.internal.loader.RawNativeLibraries; import sun.security.action.GetPropertyAction; @@ -59,7 +66,8 @@ private SystemLookup() { } private static final SymbolLookup makeSystemLookup() { try { return switch (CABI.current()) { - case SysV, LinuxAArch64, MacOsAArch64 -> libLookup(libs -> libs.load(jdkLibraryPath("syslookup"))); + case SysV, LinuxAArch64, MacOsAArch64, SysVPPC64le, SysVS390x -> libLookup(libs -> libs.load(jdkLibraryPath("syslookup"))); + case AIX -> makeAixLookup(); case Win64 -> makeWindowsLookup(); // out of line to workaround javac crash }; } catch (Throwable ex) { @@ -70,6 +78,25 @@ private static final SymbolLookup makeSystemLookup() { } } + /* The method is to wrap up the SymbolLookup address generated by forward-porting + * the default library loading solution introduced in Java 16, which remains valid + * on AIX. + */ + private static SymbolLookup makeAixLookup() { + NativeLibrary lib = NativeLibraries.defaultLibrary; + return name -> { + Objects.requireNonNull(name); + try { + long addr = lib.lookup(name); + return (addr == 0) ? + Optional.empty() : + Optional.of(MemorySegment.ofAddress(MemoryAddress.ofLong(addr), 0, MemorySession.global())); + } catch (NoSuchMethodException e) { + return Optional.empty(); + } + }; + } + private static SymbolLookup makeWindowsLookup() { Path system32 = Path.of(System.getenv("SystemRoot"), "System32"); Path ucrtbase = system32.resolve("ucrtbase.dll"); @@ -120,7 +147,7 @@ private static SymbolLookup libLookup(Function "lib"; + case SysV, LinuxAArch64, MacOsAArch64, SysVPPC64le, SysVS390x, AIX -> "lib"; case Win64 -> "bin"; }; String libname = System.mapLibraryName(name); diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java index 2cafff4f424..ad4a4680267 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java @@ -22,11 +22,21 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign.abi; import jdk.internal.foreign.SystemLookup; 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; @@ -38,8 +48,8 @@ import java.lang.invoke.MethodType; import java.util.Objects; -public abstract sealed class AbstractLinker implements Linker permits LinuxAArch64Linker, MacOsAArch64Linker, - SysVx64Linker, Windowsx64Linker { +public abstract sealed class AbstractLinker implements Linker permits LinuxAArch64Linker, MacOsAArch64Linker, AixPPC64Linker, + SysVPPC64leLinker, SysVS390xLinker, SysVx64Linker, Windowsx64Linker { private final SoftReferenceCache DOWNCALL_CACHE = new SoftReferenceCache<>(); diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java b/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java index a54d8eb38b8..7ed0fbb88a9 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java +++ b/src/java.base/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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign.abi; import jdk.internal.access.JavaLangAccess; @@ -33,6 +40,9 @@ import jdk.internal.foreign.Scoped; 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; @@ -238,6 +248,9 @@ public static Linker 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(); }; } @@ -349,6 +362,9 @@ public static VaList newVaList(Consumer actions, MemorySession s case SysV -> SysVx64Linker.newVaList(actions, session); case LinuxAArch64 -> LinuxAArch64Linker.newVaList(actions, session); case MacOsAArch64 -> MacOsAArch64Linker.newVaList(actions, session); + case SysVPPC64le -> SysVPPC64leLinker.newVaList(actions, session); + case SysVS390x -> SysVS390xLinker.newVaList(actions, session); + case AIX -> AixPPC64Linker.newVaList(actions, session); }; } @@ -358,6 +374,9 @@ public static VaList newVaListOfAddress(MemoryAddress ma, MemorySession session) case SysV -> SysVx64Linker.newVaListOfAddress(ma, session); case LinuxAArch64 -> LinuxAArch64Linker.newVaListOfAddress(ma, session); case MacOsAArch64 -> MacOsAArch64Linker.newVaListOfAddress(ma, session); + case SysVPPC64le -> SysVPPC64leLinker.newVaListOfAddress(ma, session); + case SysVS390x -> SysVS390xLinker.newVaListOfAddress(ma, session); + case AIX -> AixPPC64Linker.newVaListOfAddress(ma, session); }; } @@ -367,6 +386,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/java.base/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java index 59123bfd0c7..bf6e700067a 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java @@ -23,6 +23,13 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign.abi.aarch64; import java.lang.foreign.FunctionDescriptor; @@ -149,26 +156,15 @@ public Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean for return new Bindings(csb.build(), returnInMemory); } - public MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { - Bindings bindings = getBindings(mt, cDesc, false); - - MethodHandle handle = new DowncallLinker(C, bindings.callingSequence).getBoundMethodHandle(); - - if (bindings.isInMemoryReturn) { - handle = SharedUtils.adaptDowncallForIMR(handle, cDesc); - } - + /* Replace DowncallLinker in OpenJDK with the implementation of DowncallLinker specific to OpenJ9 */ + public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { + MethodHandle handle = DowncallLinker.getBoundMethodHandle(mt, cDesc); return handle; } - public MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, MemorySession session) { - 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 UpcallLinker.make(C, target, bindings.callingSequence, session); + /* Replace UpcallLinker in OpenJDK with the implementation of UpcallLinker specific to OpenJ9 */ + public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, MemorySession session) { + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ } private static boolean isInMemoryReturn(Optional returnLayout) { diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64Linker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64Linker.java new file mode 100644 index 00000000000..bd5f871981e --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64Linker.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020, 2022, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.aix; + +import jdk.internal.foreign.abi.AbstractLinker; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.VaList; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +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/ppc64 and might be updated accordingly in terms of VaList in the future. + */ +public final class AixPPC64Linker extends AbstractLinker { + private static AixPPC64Linker instance; + + public static AixPPC64Linker getInstance() { + if (instance == null) { + instance = new AixPPC64Linker(); + } + return instance; + } + + @Override + protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function) { + return CallArranger.arrangeDowncall(inferredMethodType, function); + } + + @Override + protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, MemorySession session) { + return CallArranger.arrangeUpcall(target, targetType, function, session); + } + + public static VaList newVaList(Consumer actions, MemorySession session) { + AixPPC64VaList.Builder builder = AixPPC64VaList.builder(session); + actions.accept(builder); + return builder.build(); + } + + public static VaList newVaListOfAddress(MemoryAddress ma, MemorySession session) { + return AixPPC64VaList.ofAddress(ma, session); + } + + public static VaList emptyVaList() { + return AixPPC64VaList.empty(); + } +} diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64VaList.java b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64VaList.java new file mode 100644 index 00000000000..b2bbe995931 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/AixPPC64VaList.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.aix; + +import java.lang.foreign.*; + +import jdk.internal.foreign.MemorySessionImpl; +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/ppc64 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 { + 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, MemorySession session) { + throw new InternalError("ofAddress() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySession session() { + throw new InternalError("session() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySessionImpl sessionImpl() { + return MemorySessionImpl.toSessionImpl(session()); + } + + @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(MemorySession session) { + return new AixPPC64VaList.Builder(session); + } + + public static non-sealed class Builder implements VaList.Builder { + + public Builder(MemorySession session) { + 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/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/CallArranger.java new file mode 100644 index 00000000000..fc36870e603 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/aix/CallArranger.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, 2022, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.aix; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +import jdk.internal.foreign.abi.DowncallLinker; +import jdk.internal.foreign.abi.UpcallLinker; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * PPC64 CallArranger specialized for AIX C ABI + */ +public class CallArranger { + + /* Replace DowncallLinker in OpenJDK with the implementation of DowncallLinker specific to OpenJ9 */ + public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { + MethodHandle handle = DowncallLinker.getBoundMethodHandle(mt, cDesc); + return handle; + } + + /* Replace UpcallLinker in OpenJDK with the implementation of UpcallLinker specific to OpenJ9 */ + public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, MemorySession session) { + return UpcallLinker.make(target, mt, cDesc, session); + } +} diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/CallArranger.java new file mode 100644 index 00000000000..3e4db604b3e --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/CallArranger.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, 2022, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.sysv; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +import jdk.internal.foreign.abi.DowncallLinker; +import jdk.internal.foreign.abi.UpcallLinker; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * PPC64LE CallArranger specialized for SysV C ABI + */ +public class CallArranger { + + /* Replace DowncallLinker in OpenJDK with the implementation of DowncallLinker specific to OpenJ9 */ + public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { + MethodHandle handle = DowncallLinker.getBoundMethodHandle(mt, cDesc); + return handle; + } + + /* Replace UpcallLinker in OpenJDK with the implementation of UpcallLinker specific to OpenJ9 */ + public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, MemorySession session) { + return UpcallLinker.make(target, mt, cDesc, session); + } +} diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leLinker.java new file mode 100644 index 00000000000..988ca6252e8 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leLinker.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020, 2022, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.sysv; + +import jdk.internal.foreign.abi.AbstractLinker; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.VaList; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +import java.util.function.Consumer; + +/** + * ABI implementation based on System V ABI PPC64LE + * + * Note: This file is copied from x64/sysv 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 extends AbstractLinker { + private static SysVPPC64leLinker instance; + + public static SysVPPC64leLinker getInstance() { + if (instance == null) { + instance = new SysVPPC64leLinker(); + } + return instance; + } + + @Override + protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function) { + return CallArranger.arrangeDowncall(inferredMethodType, function); + } + + @Override + protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, MemorySession session) { + return CallArranger.arrangeUpcall(target, targetType, function, session); + } + + public static VaList newVaList(Consumer actions, MemorySession session) { + SysVPPC64leVaList.Builder builder = SysVPPC64leVaList.builder(session); + actions.accept(builder); + return builder.build(); + } + + public static VaList newVaListOfAddress(MemoryAddress ma, MemorySession session) { + return SysVPPC64leVaList.ofAddress(ma, session); + } + + public static VaList emptyVaList() { + return SysVPPC64leVaList.empty(); + } +} diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leVaList.java b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leVaList.java new file mode 100644 index 00000000000..c3b55da5c1d --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/sysv/SysVPPC64leVaList.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.ppc64.sysv; + +import java.lang.foreign.*; + +import jdk.internal.foreign.MemorySessionImpl; +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 { + 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, MemorySession session) { + throw new InternalError("ofAddress() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySession session() { + throw new InternalError("session() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySessionImpl sessionImpl() { + return MemorySessionImpl.toSessionImpl(session()); + } + + @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(MemorySession session) { + return new SysVPPC64leVaList.Builder(session); + } + + public static non-sealed class Builder implements VaList.Builder { + + public Builder(MemorySession session) { + 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/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/CallArranger.java new file mode 100644 index 00000000000..eb23f9e5266 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/CallArranger.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, 2022, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.s390x.sysv; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +import jdk.internal.foreign.abi.DowncallLinker; +import jdk.internal.foreign.abi.UpcallLinker; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * S390x CallArranger specialized for SysV C ABI + */ +public class CallArranger { + + /* Replace DowncallLinker in OpenJDK with the implementation of DowncallLinker specific to OpenJ9 */ + public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { + MethodHandle handle = DowncallLinker.getBoundMethodHandle(mt, cDesc); + return handle; + } + + /* Replace UpcallLinker in OpenJDK with the implementation of UpcallLinker specific to OpenJ9 */ + public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, MemorySession session) { + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ + } +} diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xLinker.java new file mode 100644 index 00000000000..7f673a8736b --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xLinker.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020, 2022, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.s390x.sysv; + +import jdk.internal.foreign.abi.AbstractLinker; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.VaList; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +import java.util.function.Consumer; + +/** + * ABI implementation based on System V ABI s390x + * + * Note: This file is copied from x64/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 extends AbstractLinker { + private static SysVS390xLinker instance; + + public static SysVS390xLinker getInstance() { + if (instance == null) { + instance = new SysVS390xLinker(); + } + return instance; + } + + @Override + protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function) { + return CallArranger.arrangeDowncall(inferredMethodType, function); + } + + @Override + protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, MemorySession session) { + return CallArranger.arrangeUpcall(target, targetType, function, session); + } + + public static VaList newVaList(Consumer actions, MemorySession session) { + SysVS390xVaList.Builder builder = SysVS390xVaList.builder(session); + actions.accept(builder); + return builder.build(); + } + + public static VaList newVaListOfAddress(MemoryAddress ma, MemorySession session) { + return SysVS390xVaList.ofAddress(ma, session); + } + + public static VaList emptyVaList() { + return SysVS390xVaList.empty(); + } +} diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xVaList.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xVaList.java new file mode 100644 index 00000000000..9a5461536ca --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390x/sysv/SysVS390xVaList.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020, 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. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + +package jdk.internal.foreign.abi.s390x.sysv; + +import java.lang.foreign.*; + +import jdk.internal.foreign.MemorySessionImpl; +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 s390x/x64 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 SysVS390xVaList implements VaList, Scoped { + 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, MemorySession session) { + throw new InternalError("ofAddress() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySession session() { + throw new InternalError("session() is not yet implemented"); //$NON-NLS-1$ + } + + @Override + public MemorySessionImpl sessionImpl() { + return MemorySessionImpl.toSessionImpl(session()); + } + + @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(MemorySession session) { + return new SysVS390xVaList.Builder(session); + } + + public static non-sealed class Builder implements VaList.Builder { + + public Builder(MemorySession session) { + 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/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 897ac3b9be9..9e7a0ed6008 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 @@ -23,6 +23,13 @@ * questions. * */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.foreign.abi.x64.sysv; import jdk.internal.foreign.abi.ABIDescriptor; @@ -118,27 +125,15 @@ public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, bool return new Bindings(csb.build(), returnInMemory, argCalc.storageCalculator.nVectorReg); } + /* Replace DowncallLinker in OpenJDK with the implementation of DowncallLinker specific to OpenJ9 */ public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { - Bindings bindings = getBindings(mt, cDesc, false); - - MethodHandle handle = new DowncallLinker(CSysV, bindings.callingSequence).getBoundMethodHandle(); - handle = MethodHandles.insertArguments(handle, handle.type().parameterCount() - 1, bindings.nVectorArgs); - - if (bindings.isInMemoryReturn) { - handle = SharedUtils.adaptDowncallForIMR(handle, cDesc); - } - + MethodHandle handle = DowncallLinker.getBoundMethodHandle(mt, cDesc); return handle; } + /* Replace UpcallLinker in OpenJDK with the implementation of UpcallLinker specific to OpenJ9 */ public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, MemorySession session) { - 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 UpcallLinker.make(CSysV, target, bindings.callingSequence, session); + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ } private static boolean isInMemoryReturn(Optional returnLayout) { diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/x64/windows/CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/x64/windows/CallArranger.java index e0403e71894..972881c77bf 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/x64/windows/CallArranger.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/x64/windows/CallArranger.java @@ -22,6 +22,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + + package jdk.internal.foreign.abi.x64.windows; import jdk.internal.foreign.Utils; @@ -121,26 +129,15 @@ void setReturnBindings(Class carrier, MemoryLayout layout) { return new Bindings(csb.csb.build(), returnInMemory); } + /* Replace DowncallLinker in OpenJDK with the implementation of DowncallLinker specific to OpenJ9 */ public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc) { - Bindings bindings = getBindings(mt, cDesc, false); - - MethodHandle handle = new DowncallLinker(CWindows, bindings.callingSequence).getBoundMethodHandle(); - - if (bindings.isInMemoryReturn) { - handle = SharedUtils.adaptDowncallForIMR(handle, cDesc); - } - + MethodHandle handle = DowncallLinker.getBoundMethodHandle(mt, cDesc); return handle; } + /* Replace UpcallLinker in OpenJDK with the implementation of UpcallLinker specific to OpenJ9 */ public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, MemorySession session) { - Bindings bindings = getBindings(mt, cDesc, true); - - if (bindings.isInMemoryReturn) { - target = SharedUtils.adaptUpcallForIMR(target, false /* need the return value as well */); - } - - return UpcallLinker.make(CWindows, target, bindings.callingSequence, session); + throw new InternalError("arrangeUpcall is not yet implemented"); //$NON-NLS-1$ } private static boolean isInMemoryReturn(Optional returnLayout) { diff --git a/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java b/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java index c5ede021e00..f6dea896d5a 100644 --- a/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java +++ b/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java @@ -22,6 +22,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + + +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + package jdk.internal.loader; import jdk.internal.misc.VM; @@ -339,6 +347,20 @@ void close() { } } + public static final NativeLibrary defaultLibrary = new NativeLibraryImpl(Object.class, "", true) { + + @Override + boolean open() { + throw new UnsupportedOperationException("Cannot load default library"); + } + + @Override + public long find(String name) { + return NativeLibraries.findEntryInProcess(name); + } + + }; + /* * The run() method will be invoked when this class loader becomes * phantom reachable to unload the native library. @@ -534,4 +556,5 @@ private static native boolean load(NativeLibraryImpl impl, String name, */ private static native void unload(String name, boolean isBuiltin, long handle); private static native String findBuiltinLib(String name); + private static native long findEntryInProcess(String name); } diff --git a/src/java.base/share/native/libjava/NativeLibraries.c b/src/java.base/share/native/libjava/NativeLibraries.c index 28b632aecc2..186e77fe2af 100644 --- a/src/java.base/share/native/libjava/NativeLibraries.c +++ b/src/java.base/share/native/libjava/NativeLibraries.c @@ -23,6 +23,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + #include #include #include @@ -175,7 +181,13 @@ Java_jdk_internal_loader_NativeLibraries_load } (*env)->SetLongField(env, lib, handleID, ptr_to_jlong(handle)); - loaded = JNI_TRUE; + /* Fix this to resolve the library loading issue on macOS so as to + * ensure it returns true only when the handle is non-null given + * the official solution has not yet been released in OpenJDK. + */ + if (handle) { + loaded = JNI_TRUE; + } done: JNU_ReleaseStringPlatformChars(env, name, cname); @@ -295,3 +307,31 @@ Java_jdk_internal_loader_NativeLibraries_findBuiltinLib free(libName); return NULL; } + +#ifdef _AIX +/* + * Class: jdk_internal_loader_NativeLibraries + * Method: findEntryInProcess + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_jdk_internal_loader_NativeLibraries_findEntryInProcess + (JNIEnv *env, jclass cls, jstring name) +{ + const char *cname; + jlong res; + + if (!initIDs(env)) { + return jlong_zero; + } + + cname = (*env)->GetStringUTFChars(env, name, 0); + if (0 == cname) { + return jlong_zero; + } + + res = ptr_to_jlong(findEntryInProcess(cname)); + (*env)->ReleaseStringUTFChars(env, name, cname); + return res; +} +#endif /* _AIX */ diff --git a/src/java.base/share/native/libjava/jni_util.h b/src/java.base/share/native/libjava/jni_util.h index bd815e6f1b9..8485e0cc1bb 100644 --- a/src/java.base/share/native/libjava/jni_util.h +++ b/src/java.base/share/native/libjava/jni_util.h @@ -23,6 +23,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + #ifndef JNI_UTIL_H #define JNI_UTIL_H @@ -336,6 +342,10 @@ void* getProcessHandle(); void buildJniFunctionName(const char *sym, const char *cname, char *jniEntryName); +#ifdef _AIX +void* findEntryInProcess(const char* name); +#endif /* _AIX */ + JNIEXPORT size_t JNICALL getLastErrorString(char *buf, size_t len); diff --git a/src/java.base/unix/native/libjava/jni_util_md.c b/src/java.base/unix/native/libjava/jni_util_md.c index 460503cd794..a92d0b6a3a2 100644 --- a/src/java.base/unix/native/libjava/jni_util_md.c +++ b/src/java.base/unix/native/libjava/jni_util_md.c @@ -23,6 +23,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved + * =========================================================================== + */ + #include #include @@ -60,6 +66,12 @@ void buildJniFunctionName(const char *sym, const char *cname, } } +#ifdef _AIX +void* findEntryInProcess(const char* name) { + return JVM_FindLibraryEntry(RTLD_DEFAULT, name); +} +#endif /* _AIX */ + JNIEXPORT size_t JNICALL getLastErrorString(char *buf, size_t len) {