Skip to content

Commit

Permalink
Update the FFI related code intended for JEP434
Browse files Browse the repository at this point in the history
The changes update part of our code in the FFI
framework against the latest APIs specified in
JDKnext to accommodate the new features of JEP434.

Note:
This is the part of implementation intended for
#eclipse-openj9/openj9/issues/16329

Signed-off-by: ChengJin01 <[email protected]>
  • Loading branch information
ChengJin01 committed Mar 6, 2023
1 parent a0f8533 commit d82bf9c
Show file tree
Hide file tree
Showing 18 changed files with 161 additions and 108 deletions.
14 changes: 7 additions & 7 deletions src/java.base/share/classes/jdk/internal/foreign/CABI.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

/*
* ===========================================================================
* (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
* (c) Copyright IBM Corp. 2022, 2023 All Rights Reserved
* ===========================================================================
*/

Expand All @@ -42,9 +42,9 @@ public enum CABI {
MAC_OS_AARCH_64,
WIN_AARCH_64,
LINUX_RISCV_64,
SysVPPC64le,
SysVS390x,
AIX;
SYS_V_PPC_64LE,
SYS_V_S390X,
AIX_PPC_64;

private static final CABI ABI;
private static final String ARCH;
Expand Down Expand Up @@ -81,12 +81,12 @@ public enum CABI {
}
} else if (ARCH.startsWith("ppc64")) {
if (OS.startsWith("Linux")) {
ABI = SysVPPC64le;
ABI = SYS_V_PPC_64LE;
} else {
ABI = AIX;
ABI = AIX_PPC_64;
}
} else if (ARCH.equals("s390x") && OS.startsWith("Linux")) {
ABI = SysVS390x;
ABI = SYS_V_S390X;
} else {
// unsupported
ABI = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

/*
* ===========================================================================
* (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
* (c) Copyright IBM Corp. 2022, 2023 All Rights Reserved
* ===========================================================================
*/

Expand Down Expand Up @@ -325,7 +325,7 @@ private SysVPPC64le() {
/**
* The {@code T*} native type.
*/
public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64);
public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64).asUnbounded();

/**
* The {@code va_list} native type, as it is passed to a function.
Expand Down Expand Up @@ -384,7 +384,7 @@ private SysVS390x() {
/**
* The {@code T*} native type.
*/
public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64);
public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64).asUnbounded();

/**
* The {@code va_list} native type, as it is passed to a function.
Expand Down Expand Up @@ -443,7 +443,7 @@ private AIX() {
/**
* The {@code T*} native type.
*/
public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64);
public static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64).asUnbounded();

/**
* The {@code va_list} native type, as it is passed to a function.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ private SystemLookup() { }
private static SymbolLookup makeSystemLookup() {
try {
return switch (CABI.current()) {
case SYS_V, LINUX_AARCH_64, MAC_OS_AARCH_64, LINUX_RISCV_64, SysVPPC64le, SysVS390x -> libLookup(libs -> libs.load(jdkLibraryPath("syslookup")));
case AIX -> makeAixLookup();
case SYS_V, LINUX_AARCH_64, MAC_OS_AARCH_64, LINUX_RISCV_64, SYS_V_PPC_64LE, SYS_V_S390X -> libLookup(libs -> libs.load(jdkLibraryPath("syslookup")));
case AIX_PPC_64 -> makeAixLookup();
case WIN_64, WIN_AARCH_64 -> makeWindowsLookup(); // out of line to workaround javac crash
};
} catch (Throwable ex) {
Expand Down Expand Up @@ -159,7 +159,7 @@ private static SymbolLookup libLookup(Function<RawNativeLibraries, NativeLibrary
private static Path jdkLibraryPath(String name) {
Path javahome = Path.of(GetPropertyAction.privilegedGetProperty("java.home"));
String lib = switch (CABI.current()) {
case SYS_V, LINUX_AARCH_64, MAC_OS_AARCH_64, LINUX_RISCV_64, SysVPPC64le, SysVS390x, AIX -> "lib";
case SYS_V, LINUX_AARCH_64, MAC_OS_AARCH_64, LINUX_RISCV_64, SYS_V_PPC_64LE, SYS_V_S390X, AIX_PPC_64 -> "lib";
case WIN_64, WIN_AARCH_64 -> "bin";
};
String libname = System.mapLibraryName(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import java.lang.foreign.Linker;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SequenceLayout;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.util.Objects;
Expand Down Expand Up @@ -111,14 +112,46 @@ private static void checkHasNaturalAlignment(FunctionDescriptor descriptor) {
private static void checkHasNaturalAlignmentRecursive(MemoryLayout layout) {
checkHasNaturalAlignment(layout);
if (layout instanceof GroupLayout gl) {
boolean isCheckRequired = true;
for (MemoryLayout member : gl.memberLayouts()) {
checkHasNaturalAlignmentRecursive(member);
isCheckRequired = isAlignmentCheckRequired(member, isCheckRequired);
if (isCheckRequired) {
checkHasNaturalAlignmentRecursive(member);
}
}
} else if (layout instanceof SequenceLayout sl) {
checkHasNaturalAlignmentRecursive(sl.elementLayout());
}
}

private static boolean isAlignmentCheckRequired(MemoryLayout layout, boolean isCheckRequired) {
boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
boolean isRequired = isCheckRequired;

if (isAixOS) {
if (layout instanceof ValueLayout) {
ValueLayout baseLayout = (ValueLayout)layout;
/* This alignement check (which is introduced since JDK20) on double is ignored on AIX
* given the alignment of double is changed to 32bits to handle the structs such as
* [int/float, double] or [int/float, double, the 3rd element], in which
* 1) there is no padding between int/float and double.
* 2) there is no padding between double and the 3rd element.
* 3) the alignment of both double and the 3rd 64-bit element is 32bits.
* See the C_DOUBLE layout on AIX in PlatformLayouts.java
*/
if ((!isRequired || (baseLayout.carrier() == double.class))
&& (baseLayout.bitSize() == 64)
&& (baseLayout.bitAlignment() == 32)
) {
isRequired = false;
} else {
isRequired = true;
}
}
}
return isRequired;
}

private static void checkHasNaturalAlignment(MemoryLayout layout) {
if (!((AbstractLayout<?>) layout).hasNaturalAlignment()) {
throw new IllegalArgumentException("Layout bit alignment must be natural alignment: " + layout);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@
import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker;
import jdk.internal.vm.annotation.ForceInline;

import java.lang.foreign.Linker;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.GroupLayout;
import java.lang.foreign.Linker;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentScope;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.SegmentScope;
import java.lang.foreign.VaList;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
Expand Down Expand Up @@ -199,11 +199,11 @@ public static Linker getSystemLinker() {
case SYS_V -> SysVx64Linker.getInstance();
case LINUX_AARCH_64 -> LinuxAArch64Linker.getInstance();
case MAC_OS_AARCH_64 -> MacOsAArch64Linker.getInstance();
case WIN_AARCH_64 -> WindowsAArch64Linker.getInstance();
case LINUX_RISCV_64 -> LinuxRISCV64Linker.getInstance();
case SysVPPC64le -> SysVPPC64leLinker.getInstance();
case SysVS390x -> SysVS390xLinker.getInstance();
case AIX -> AixPPC64Linker.getInstance();
case WIN_AARCH_64 -> WindowsAArch64Linker.getInstance();
case SYS_V_PPC_64LE -> SysVPPC64leLinker.getInstance();
case SYS_V_S390X -> SysVS390xLinker.getInstance();
case AIX_PPC_64 -> AixPPC64Linker.getInstance();
};
}

Expand Down Expand Up @@ -317,9 +317,9 @@ public static VaList newVaList(Consumer<VaList.Builder> actions, SegmentScope sc
case MAC_OS_AARCH_64 -> MacOsAArch64Linker.newVaList(actions, scope);
case LINUX_RISCV_64 -> LinuxRISCV64Linker.newVaList(actions, scope);
case WIN_AARCH_64 -> WindowsAArch64Linker.newVaList(actions, scope);
case SysVPPC64le -> SysVPPC64leLinker.newVaList(actions, scope);
case SysVS390x -> SysVS390xLinker.newVaList(actions, scope);
case AIX -> AixPPC64Linker.newVaList(actions, scope);
case SYS_V_PPC_64LE -> SysVPPC64leLinker.newVaList(actions, scope);
case SYS_V_S390X -> SysVS390xLinker.newVaList(actions, scope);
case AIX_PPC_64 -> AixPPC64Linker.newVaList(actions, scope);
};
}

Expand All @@ -331,9 +331,9 @@ public static VaList newVaListOfAddress(long address, SegmentScope scope) {
case MAC_OS_AARCH_64 -> MacOsAArch64Linker.newVaListOfAddress(address, scope);
case LINUX_RISCV_64 -> LinuxRISCV64Linker.newVaListOfAddress(address, scope);
case WIN_AARCH_64 -> WindowsAArch64Linker.newVaListOfAddress(address, scope);
case SysVPPC64le -> SysVPPC64leLinker.newVaListOfAddress(address, scope);
case SysVS390x -> SysVS390xLinker.newVaListOfAddress(address, scope);
case AIX -> AixPPC64Linker.newVaListOfAddress(address, scope);
case SYS_V_PPC_64LE -> SysVPPC64leLinker.newVaListOfAddress(address, scope);
case SYS_V_S390X -> SysVS390xLinker.newVaListOfAddress(address, scope);
case AIX_PPC_64 -> AixPPC64Linker.newVaListOfAddress(address, scope);
};
}

Expand All @@ -345,9 +345,9 @@ public static VaList emptyVaList() {
case MAC_OS_AARCH_64 -> MacOsAArch64Linker.emptyVaList();
case LINUX_RISCV_64 -> LinuxRISCV64Linker.emptyVaList();
case WIN_AARCH_64 -> WindowsAArch64Linker.emptyVaList();
case SysVPPC64le -> SysVPPC64leLinker.emptyVaList();
case SysVS390x -> SysVS390xLinker.emptyVaList();
case AIX -> AixPPC64Linker.emptyVaList();
case SYS_V_PPC_64LE -> SysVPPC64leLinker.emptyVaList();
case SYS_V_S390X -> SysVS390xLinker.emptyVaList();
case AIX_PPC_64 -> AixPPC64Linker.emptyVaList();
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,19 @@ public Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean for

/* Replace DowncallLinker in OpenJDK with the implementation of DowncallLinker specific to OpenJ9 */
public MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) {
// MethodHandle handle = DowncallLinker.getBoundMethodHandle(mt, cDesc, options);
// return handle;
return null;
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
throw new InternalError("arrangeDowncall is not implemented on Windows/Aarch64");
}
MethodHandle handle = DowncallLinker.getBoundMethodHandle(mt, cDesc, options);
return handle;
}

/* Replace UpcallLinker in OpenJDK with the implementation of UpcallLinker specific to OpenJ9 */
public MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, SegmentScope session) {
// return UpcallLinker.make(target, mt, cDesc, session);
return null;
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
throw new InternalError("arrangeUpcall is not implemented on Windows/Aarch64");
}
return UpcallLinker.make(target, mt, cDesc, session);
}

private static boolean isInMemoryReturn(Optional<MemoryLayout> returnLayout) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* ===========================================================================
* (c) Copyright IBM Corp. 2023, 2023 All Rights Reserved
* ===========================================================================
*/

package jdk.internal.foreign.abi.aarch64.windows;

import java.lang.foreign.GroupLayout;
Expand Down Expand Up @@ -64,6 +71,7 @@ public non-sealed class WindowsAArch64VaList implements VaList {

private WindowsAArch64VaList(MemorySegment segment) {
this.segment = segment;
throw new InternalError("WindowsAArch64VaList()/VaList is not implemented on Windows/Aarch64");
}

public static VaList empty() {
Expand Down Expand Up @@ -103,6 +111,11 @@ private Object read(MemoryLayout layout) {
private Object read(MemoryLayout layout, SegmentAllocator allocator) {
Objects.requireNonNull(layout);
Object res;

if (layout != null) {
throw new InternalError("VaList is not implemented on Windows/Aarch64");
}

if (layout instanceof GroupLayout) {
TypeClass typeClass = TypeClass.classifyLayout(layout);
res = switch (typeClass) {
Expand Down Expand Up @@ -189,6 +202,7 @@ public static non-sealed class Builder implements VaList.Builder {
public Builder(SegmentScope session) {
((MemorySessionImpl) session).checkValidState();
this.session = session;
throw new InternalError("VaList is not implemented on Windows/Aarch64");
}

private Builder arg(MemoryLayout layout, Object value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,17 @@
* 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();
final class Holder {
private static final AixPPC64Linker INSTANCE = new AixPPC64Linker();
}
return instance;

return Holder.INSTANCE;
}

private AixPPC64Linker() {
/* Ensure there is only one instance. */
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import jdk.internal.foreign.abi.SharedUtils;
import jdk.internal.foreign.abi.SharedUtils.SimpleVaArg;
import jdk.internal.foreign.MemorySessionImpl;
import static jdk.internal.foreign.abi.SharedUtils.THROWING_ALLOCATOR;
import static jdk.internal.foreign.PlatformLayouts.AIX;

/**
Expand All @@ -68,9 +69,9 @@ public non-sealed class AixPPC64VaList implements VaList {
private MemorySegment segment;
private final SegmentScope session;

private AixPPC64VaList(MemorySegment segment, SegmentScope session) {
private AixPPC64VaList(MemorySegment segment) {
this.segment = segment;
this.session = session;
this.session = segment.scope();
}

public static final VaList empty() {
Expand Down Expand Up @@ -103,7 +104,7 @@ public MemorySegment nextVarg(GroupLayout layout, SegmentAllocator allocator) {
}

private Object readArg(MemoryLayout argLayout) {
return readArg(argLayout, SharedUtils.THROWING_ALLOCATOR);
return readArg(argLayout, THROWING_ALLOCATOR);
}

private Object readArg(MemoryLayout argLayout, SegmentAllocator allocator) {
Expand Down Expand Up @@ -132,15 +133,15 @@ private Object readArg(MemoryLayout argLayout, SegmentAllocator allocator) {
default -> throw new IllegalStateException("Unsupported TypeClass: " + typeClass);
}

/* Move to the next argument in the va_list buffer */
/* Move to the next argument in the va_list buffer. */
segment = segment.asSlice(argByteSize);
return argument;
}

private static long getAlignedArgSize(MemoryLayout argLayout) {
long argLayoutSize = VA_LIST_SLOT_BYTES; // Always aligned with 8 bytes for primitives/pointer by default

/* As with primitives, a struct should aligned with 8 bytes */
/* As with primitives, a struct should aligned with 8 bytes. */
if (argLayout instanceof GroupLayout) {
argLayoutSize = argLayout.byteSize();
if ((argLayoutSize % VA_LIST_SLOT_BYTES) > 0) {
Expand All @@ -151,7 +152,7 @@ private static long getAlignedArgSize(MemoryLayout argLayout) {
return argLayoutSize;
}

/* Check whether the argument to be skipped exceeds the existing memory size in the VaList */
/* Check whether the argument to be skipped exceeds the existing memory size in the VaList. */
private void checkNextArgument(MemoryLayout argLayout, long argByteSize) {
if (argByteSize > segment.byteSize()) {
throw SharedUtils.newVaListNSEE(argLayout);
Expand All @@ -171,20 +172,19 @@ public void skip(MemoryLayout... layouts) {
Objects.requireNonNull(layout);
long argByteSize = getAlignedArgSize(layout);
checkNextArgument(layout, argByteSize);
/* Skip to the next argument in the va_list buffer */
/* Skip to the next argument in the va_list buffer. */
segment = segment.asSlice(argByteSize);
}
}

public static VaList ofAddress(long addr, SegmentScope session) {
MemorySegment segment = MemorySegment.ofAddress(addr, Long.MAX_VALUE, session);
return new AixPPC64VaList(segment, session);
public static VaList ofAddress(long address, SegmentScope session) {
return new AixPPC64VaList(MemorySegment.ofAddress(address, Long.MAX_VALUE, session));
}

@Override
public VaList copy() {
((MemorySessionImpl)session).checkValidState();
return new AixPPC64VaList(segment, session);
return new AixPPC64VaList(segment);
}

@Override
Expand Down Expand Up @@ -284,7 +284,7 @@ public VaList build() {
/* Move to the next argument by the aligned size of the current argument */
cursorSegment = cursorSegment.asSlice(argByteSize);
}
return new AixPPC64VaList(segment, session);
return new AixPPC64VaList(segment);
}
}
}
Loading

0 comments on commit d82bf9c

Please sign in to comment.