Skip to content

Commit

Permalink
[JEP424]Implement the Linker's downcall & upcall handler
Browse files Browse the repository at this point in the history
The changes aim to enable the Linker's downcall & upcall handler
to support primitives and struct by replacing DowncallLinker
& UpcallLinker with the equivalent implemented in OpenJ9.
In addition, the changes also include the code that handles
the default library loading on AIX.

Signed-off-by: Cheng Jin <jincheng@ca.ibm.com>
  • Loading branch information
Cheng Jin committed Jun 13, 2022
1 parent 332135c commit 70e8e4d
Show file tree
Hide file tree
Showing 24 changed files with 1,355 additions and 64 deletions.
16 changes: 14 additions & 2 deletions src/java.base/share/classes/java/lang/foreign/VaList.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
* questions.
*
*/

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

package java.lang.foreign;

import java.util.Objects;
Expand All @@ -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;
Expand All @@ -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}
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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);
}
Expand Down Expand Up @@ -106,20 +117,36 @@ 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;
}

@ForceInline
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;
}

Expand Down
22 changes: 20 additions & 2 deletions src/java.base/share/classes/jdk/internal/foreign/CABI.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,7 +39,10 @@ public enum CABI {
SysV,
Win64,
LinuxAArch64,
MacOsAArch64;
MacOsAArch64,
SysVPPC64le,
SysVS390x,
AIX;

private static final CABI current;

Expand All @@ -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);
}
Expand Down
20 changes: 19 additions & 1 deletion src/java.base/share/classes/jdk/internal/foreign/LayoutPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
* questions.
*
*/

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

package jdk.internal.foreign;

import jdk.internal.vm.annotation.ForceInline;
Expand All @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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--) {
Expand Down
Loading

0 comments on commit 70e8e4d

Please sign in to comment.