From 7bca76ce5477a1da627656f72a70ea5826ee52bf Mon Sep 17 00:00:00 2001 From: ChengJin01 Date: Fri, 28 Apr 2023 20:29:36 -0400 Subject: [PATCH] Disable FFI specific code for compilation in JDK21 The changes disable all internal code specific to FFI for the moment to pass the compilation due to the modified public APIs in OpenJDK. Note: The modifications in code are based on the new APIs in JDK21 & JEP442 as mentioned at https://github.com/eclipse-openj9/openj9/issues/16951. Signed-off-by: ChengJin01 --- .../internal/foreign/abi/DowncallLinker.java | 25 +- .../internal/foreign/abi/UpcallLinker.java | 46 +-- .../foreign/abi/InternalDowncallHandler.java | 351 ++++-------------- .../foreign/abi/InternalUpcallHandler.java | 64 +--- .../foreign/abi/LayoutStrPreprocessor.java | 148 ++++---- .../foreign/abi/UpcallMHMetaData.java | 44 +-- .../foreign/abi/ProgrammableInvoker.java | 8 +- .../abi/ProgrammableUpcallHandler.java | 19 +- .../foreign/abi/InternalDowncallHandler.java | 2 +- .../foreign/abi/InternalUpcallHandler.java | 2 +- .../foreign/abi/LayoutStrPreprocessor.java | 2 +- .../foreign/abi/TypeLayoutCheckHelper.java | 80 ++-- .../foreign/abi/UpcallMHMetaData.java | 2 +- runtime/j9vm/exports.cmake | 1 + runtime/j9vm/j9vmnatives.xml | 1 + runtime/j9vm/javanextvmi.cpp | 6 + runtime/oti/vmconstantpool.xml | 60 ++- runtime/redirector/forwarders.m4 | 2 + ..._internal_foreign_abi_UpCallMHMetaData.cpp | 18 +- runtime/vm/UpcallVMHelpers.cpp | 15 +- test/functional/Java19andUp/build.xml | 2 +- test/functional/Java21andUp/build.xml | 6 +- 22 files changed, 295 insertions(+), 609 deletions(-) diff --git a/jcl/src/java.base/share/classes/jdk/internal/foreign/abi/DowncallLinker.java b/jcl/src/java.base/share/classes/jdk/internal/foreign/abi/DowncallLinker.java index b3d11442a8a..7f379a8f930 100644 --- a/jcl/src/java.base/share/classes/jdk/internal/foreign/abi/DowncallLinker.java +++ b/jcl/src/java.base/share/classes/jdk/internal/foreign/abi/DowncallLinker.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF JAVA_SPEC_VERSION >= 19]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION >= 20]*/ /******************************************************************************* * Copyright IBM Corp. and others 2021 * @@ -26,17 +26,16 @@ import java.lang.invoke.MethodType; import java.lang.foreign.FunctionDescriptor; -/*[IF JAVA_SPEC_VERSION >= 20]*/ import jdk.internal.foreign.abi.LinkerOptions; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ +/*[IF JAVA_SPEC_VERSION == 20]*/ import openj9.internal.foreign.abi.InternalDowncallHandler; +/*[ENDIF] JAVA_SPEC_VERSION == 20 */ /** * The counterpart in OpenJDK is replaced with this class that wrap up a method handle * enabling the native code to the ffi_call via the libffi interface at runtime. */ public class DowncallLinker { - /*[IF JAVA_SPEC_VERSION >= 20]*/ /** * The method is ultimately invoked by Linker on the specific platforms to generate the requested * method handle to the underlying C function. @@ -46,20 +45,12 @@ public class DowncallLinker { * @param options The linker options indicating additional linking requirements to the linker * @return a method handle bound to the native method */ + @SuppressWarnings("nls") public static MethodHandle getBoundMethodHandle(MethodType functionMethodType, FunctionDescriptor funcDesc, LinkerOptions options) { + /*[IF JAVA_SPEC_VERSION >= 21]*/ + throw new InternalError("Downcall is not yet implemented"); + /*[ELSE] JAVA_SPEC_VERSION >= 21 */ return new InternalDowncallHandler(functionMethodType, funcDesc, options).getBoundMethodHandle(); + /*[ENDIF] JAVA_SPEC_VERSION >= 21 */ } - /*[ELSE] JAVA_SPEC_VERSION >= 20 */ - /** - * The method is ultimately invoked by Linker on the specific platforms to generate the requested - * method handle to the underlying C function. - * - * @param functionMethodType The MethodType of the specified native function - * @param funcDesc The function descriptor of the specified native function - * @return a method handle bound to the native method - */ - public static MethodHandle getBoundMethodHandle(MethodType functionMethodType, FunctionDescriptor funcDesc) { - return new InternalDowncallHandler(functionMethodType, funcDesc).getBoundMethodHandle(); - } - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ } diff --git a/jcl/src/java.base/share/classes/jdk/internal/foreign/abi/UpcallLinker.java b/jcl/src/java.base/share/classes/jdk/internal/foreign/abi/UpcallLinker.java index 689020c2acd..51430a64301 100644 --- a/jcl/src/java.base/share/classes/jdk/internal/foreign/abi/UpcallLinker.java +++ b/jcl/src/java.base/share/classes/jdk/internal/foreign/abi/UpcallLinker.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF JAVA_SPEC_VERSION >= 19]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION >= 20]*/ /******************************************************************************* * Copyright IBM Corp. and others 2021 * @@ -27,15 +27,14 @@ import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.MemorySegment; -/*[IF JAVA_SPEC_VERSION >= 20]*/ -import java.lang.foreign.SegmentScope; -/*[ELSE] JAVA_SPEC_VERSION >= 20 */ -import java.lang.foreign.MemorySession; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ /*[IF JAVA_SPEC_VERSION >= 21]*/ import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory; -/*[ENDIF] JAVA_SPEC_VERSION >= 21 */ +import jdk.internal.foreign.abi.LinkerOptions; +/*[ELSE] JAVA_SPEC_VERSION >= 21 */ +import java.lang.foreign.SegmentScope; +import jdk.internal.foreign.abi.LinkerOptions; import openj9.internal.foreign.abi.InternalUpcallHandler; +/*[ENDIF] JAVA_SPEC_VERSION >= 21 */ /** * The counterpart in OpenJDK is replaced with this class that wrap up @@ -43,16 +42,13 @@ */ public final class UpcallLinker { + /*[IF JAVA_SPEC_VERSION == 20]*/ private final long thunkAddr; /* The constructor creates an upcall handler specific to the requested java method * by generating a native thunk in upcall on a given platform. */ - /*[IF JAVA_SPEC_VERSION >= 20]*/ UpcallLinker(MethodHandle target, MethodType methodType, FunctionDescriptor descriptor, SegmentScope session) - /*[ELSE] JAVA_SPEC_VERSION >= 20 */ - UpcallLinker(MethodHandle target, MethodType methodType, FunctionDescriptor descriptor, MemorySession session) - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { InternalUpcallHandler internalUpcallHandler = new InternalUpcallHandler(target, methodType, descriptor, session); /* The thunk address must be set given entryPoint() is used in OpenJDK. */ @@ -68,7 +64,6 @@ public long entryPoint() { return thunkAddr; } - /*[IF JAVA_SPEC_VERSION >= 20]*/ /** * The method invoked via Clinker generates a native thunk to create * a native symbol that holds an entry point to the native function @@ -81,24 +76,11 @@ public long entryPoint() { * @return the native symbol */ public static MemorySegment make(MethodHandle target, MethodType methodType, FunctionDescriptor descriptor, SegmentScope session) - /*[ELSE] JAVA_SPEC_VERSION >= 20 */ - /** - * The method invoked via Clinker generates a native thunk to create - * a native symbol that holds an entry point to the native function - * intended for the requested java method in upcall. - * - * @param target the upcall method handle to the requested java method - * @param methodType the MethodType of the upcall method handle - * @param descriptor the FunctionDescriptor of the upcall method handle - * @param session the MemorySession of the upcall method handle - * @return the native symbol - */ - public static MemorySegment make(MethodHandle target, MethodType methodType, FunctionDescriptor descriptor, MemorySession session) - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { UpcallLinker upcallLinker = new UpcallLinker(target, methodType, descriptor, session); return UpcallStubs.makeUpcall(upcallLinker.entryPoint(), session); } + /*[ENDIF] JAVA_SPEC_VERSION == 20 */ /*[IF JAVA_SPEC_VERSION >= 21]*/ /** @@ -129,12 +111,16 @@ public static UpcallStubFactory makeFactory(MethodType methodType, ABIDescriptor * * @param methodType the MethodType of the upcall method handle * @param descriptor the FunctionDescriptor of the upcall method handle + * @param options the LinkerOptions indicating additional linking requirements to the linker * @return a factory instance that wraps up the upcall specific code + * @throws InternalError as the upcalll specific code is not yet implemented */ - public static UpcallStubFactory makeFactory(MethodType methodType, FunctionDescriptor descriptor) { - return (target, session) -> { - return UpcallLinker.make(target, methodType, descriptor, session); - }; + @SuppressWarnings("nls") + public static UpcallStubFactory makeFactory(MethodType methodType, FunctionDescriptor descriptor, LinkerOptions options) { + // return (target, arena) -> { + // return UpcallLinker.make(target, methodType, descriptor, arena, options); + // }; + throw new InternalError("Upcall is not yet implemented"); } /*[ENDIF] JAVA_SPEC_VERSION >= 21 */ } diff --git a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java index 722592dd13e..8e4c58c4d46 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java +++ b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF JAVA_SPEC_VERSION >= 19]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 20]*/ /******************************************************************************* * Copyright IBM Corp. and others 2022 * @@ -24,13 +24,11 @@ import java.util.HashMap; import java.util.List; -/*[IF JAVA_SPEC_VERSION >= 17]*/ -/*[IF JAVA_SPEC_VERSION >= 18]*/ +/*[IF JAVA_SPEC_VERSION >= 20]*/ import java.util.Objects; -/*[ENDIF] JAVA_SPEC_VERSION >= 18 */ +/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ import java.util.concurrent.ConcurrentHashMap; import java.util.Set; -/*[ENDIF] JAVA_SPEC_VERSION >= 17 */ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -42,60 +40,41 @@ /*[IF JAVA_SPEC_VERSION >= 20]*/ import java.lang.foreign.Arena; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ -/*[IF JAVA_SPEC_VERSION >= 19]*/ -/*[IF JAVA_SPEC_VERSION == 19]*/ -import java.lang.foreign.Addressable; -/*[ENDIF] JAVA_SPEC_VERSION == 19 */ import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.GroupLayout; -/*[IF JAVA_SPEC_VERSION == 19]*/ -import java.lang.foreign.MemoryAddress; -/*[ENDIF] JAVA_SPEC_VERSION == 19 */ import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; -/*[IF JAVA_SPEC_VERSION == 19]*/ -import java.lang.foreign.MemorySession; -/*[ENDIF] JAVA_SPEC_VERSION == 19 */ import java.lang.foreign.SegmentAllocator; -/*[IF JAVA_SPEC_VERSION >= 20]*/ +/*[IF JAVA_SPEC_VERSION == 20]*/ import java.lang.foreign.SegmentScope; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ -import java.lang.foreign.ValueLayout; -/*[IF JAVA_SPEC_VERSION >= 20]*/ -import static java.lang.foreign.ValueLayout.*; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ +/*[ENDIF] JAVA_SPEC_VERSION == 20 */ import java.lang.foreign.VaList; -/*[IF JAVA_SPEC_VERSION >= 20]*/ +import java.lang.foreign.ValueLayout; import jdk.internal.foreign.Utils; import jdk.internal.foreign.abi.LinkerOptions; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ import jdk.internal.foreign.MemorySessionImpl; -/*[ELSE] JAVA_SPEC_VERSION >= 19 */ +/*[ELSE] JAVA_SPEC_VERSION >= 20 */ import jdk.incubator.foreign.Addressable; import jdk.incubator.foreign.FunctionDescriptor; import jdk.incubator.foreign.GroupLayout; import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.MemoryLayout; import jdk.incubator.foreign.MemorySegment; -/*[IF JAVA_SPEC_VERSION == 18]*/ -import jdk.incubator.foreign.NativeSymbol; -import jdk.incubator.foreign.VaList; -/*[ENDIF] JAVA_SPEC_VERSION == 18 */ -/*[IF JAVA_SPEC_VERSION >= 17]*/ import jdk.incubator.foreign.ResourceScope; -/*[IF JAVA_SPEC_VERSION == 17]*/ import jdk.incubator.foreign.ResourceScope.Handle; -/*[ENDIF] JAVA_SPEC_VERSION == 17 */ import jdk.incubator.foreign.SegmentAllocator; -/*[ENDIF] JAVA_SPEC_VERSION >= 17 */ import jdk.incubator.foreign.ValueLayout; -/*[ENDIF] JAVA_SPEC_VERSION >= 19 */ +/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ + +/*[IF JAVA_SPEC_VERSION >= 20]*/ +import static java.lang.foreign.ValueLayout.*; +/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ /** * The internal implementation of downcall handler wraps up a method handle enabling * the native code to the ffi_call via the libffi interface at runtime. */ +@SuppressWarnings("nls") public class InternalDowncallHandler { private final MethodType funcMethodType; @@ -103,9 +82,6 @@ public class InternalDowncallHandler { /*[IF JAVA_SPEC_VERSION >= 20]*/ private final LinkerOptions linkerOpts; /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ - /*[IF JAVA_SPEC_VERSION == 16]*/ - private Addressable functionAddr; - /*[ENDIF] JAVA_SPEC_VERSION == 16 */ private long cifNativeThunkAddr; private long argTypesAddr; private MemoryLayout[] argLayoutArray; @@ -117,9 +93,7 @@ public class InternalDowncallHandler { */ /*[IF JAVA_SPEC_VERSION >= 20]*/ private Set memArgScopeSet; - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - private Set memArgScopeSet; - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ private Set memArgScopeSet; /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ @@ -181,28 +155,28 @@ private static final class PrivateClassLock { static { try { /* Set up the argument filters for the primitive types and MemoryAddress. */ - booleanToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "booleanToLongArg", methodType(long.class, boolean.class)); //$NON-NLS-1$ - charToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "charToLongArg", methodType(long.class, char.class)); //$NON-NLS-1$ - byteToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "byteToLongArg", methodType(long.class, byte.class)); //$NON-NLS-1$ - shortToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "shortToLongArg", methodType(long.class, short.class)); //$NON-NLS-1$ - intToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "intToLongArg", methodType(long.class, int.class)); //$NON-NLS-1$ - floatToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "floatToLongArg", methodType(long.class, float.class)); //$NON-NLS-1$ - doubleToLongArgFilter = lookup.findStatic(Double.class, "doubleToLongBits", methodType(long.class, double.class)); //$NON-NLS-1$ + booleanToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "booleanToLongArg", methodType(long.class, boolean.class)); + charToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "charToLongArg", methodType(long.class, char.class)); + byteToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "byteToLongArg", methodType(long.class, byte.class)); + shortToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "shortToLongArg", methodType(long.class, short.class)); + intToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "intToLongArg", methodType(long.class, int.class)); + floatToLongArgFilter = lookup.findStatic(InternalDowncallHandler.class, "floatToLongArg", methodType(long.class, float.class)); + doubleToLongArgFilter = lookup.findStatic(Double.class, "doubleToLongBits", methodType(long.class, double.class)); /* Set up the return value filters for the primitive types and MemoryAddress. */ - longObjToVoidRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToVoidRet", methodType(void.class, Object.class)); //$NON-NLS-1$ - longObjToBooleanRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToBooleanRet", methodType(boolean.class, Object.class)); //$NON-NLS-1$ - longObjToCharRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToCharRet", methodType(char.class, Object.class)); //$NON-NLS-1$ - longObjToByteRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToByteRet", methodType(byte.class, Object.class)); //$NON-NLS-1$ - longObjToShortRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToShortRet", methodType(short.class, Object.class)); //$NON-NLS-1$ - longObjToIntRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToIntRet", methodType(int.class, Object.class)); //$NON-NLS-1$ - longObjToLongRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToLongRet", methodType(long.class, Object.class)); //$NON-NLS-1$ - longObjToFloatRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToFloatRet", methodType(float.class, Object.class)); //$NON-NLS-1$ - longObjToDoubleRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToDoubleRet", methodType(double.class, Object.class)); //$NON-NLS-1$ - /*[IF JAVA_SPEC_VERSION <= 19]*/ - longObjToMemAddrRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToMemAddrRet", methodType(MemoryAddress.class, Object.class)); //$NON-NLS-1$ - /*[ENDIF] JAVA_SPEC_VERSION <= 19 */ - objToMemSegmtRetFilter = lookup.findStatic(InternalDowncallHandler.class, "objToMemSegmtRet", methodType(MemorySegment.class, Object.class)); //$NON-NLS-1$ + longObjToVoidRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToVoidRet", methodType(void.class, Object.class)); + longObjToBooleanRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToBooleanRet", methodType(boolean.class, Object.class)); + longObjToCharRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToCharRet", methodType(char.class, Object.class)); + longObjToByteRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToByteRet", methodType(byte.class, Object.class)); + longObjToShortRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToShortRet", methodType(short.class, Object.class)); + longObjToIntRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToIntRet", methodType(int.class, Object.class)); + longObjToLongRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToLongRet", methodType(long.class, Object.class)); + longObjToFloatRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToFloatRet", methodType(float.class, Object.class)); + longObjToDoubleRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToDoubleRet", methodType(double.class, Object.class)); + /*[IF JAVA_SPEC_VERSION == 17]*/ + longObjToMemAddrRetFilter = lookup.findStatic(InternalDowncallHandler.class, "longObjToMemAddrRet", methodType(MemoryAddress.class, Object.class)); + /*[ENDIF] JAVA_SPEC_VERSION == 17 */ + objToMemSegmtRetFilter = lookup.findStatic(InternalDowncallHandler.class, "objToMemSegmtRet", methodType(MemorySegment.class, Object.class)); } catch (IllegalAccessException | NoSuchMethodException e) { throw new InternalError(e); } @@ -251,15 +225,12 @@ private static final long floatToLongArg(float argValue) { return Float.floatToIntBits(argValue); } - /*[IF JAVA_SPEC_VERSION >= 17]*/ /* Save the active session of the specified passed-in memory specific argument in the downcall handler * given the argument might be created within different sessions/scopes. */ /*[IF JAVA_SPEC_VERSION >= 20]*/ private final void addMemArgScope(SegmentScope memArgScope) throws IllegalStateException - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - private final void addMemArgScope(MemorySession memArgScope) throws IllegalStateException - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ private final void addMemArgScope(ResourceScope memArgScope) throws IllegalStateException /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { @@ -272,23 +243,16 @@ private final void addMemArgScope(ResourceScope memArgScope) throws IllegalState /* Validate the memory related scope to ensure that it is kept alive during the downcall. */ /*[IF JAVA_SPEC_VERSION >= 20]*/ private void validateMemScope(SegmentScope memScope) throws IllegalStateException - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - private void validateMemScope(MemorySession memScope) throws IllegalStateException - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ private void validateMemScope(ResourceScope memScope) throws IllegalStateException /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { if (!memScope.isAlive()) { - /*[IF JAVA_SPEC_VERSION == 19]*/ - String scopeName = "session"; - /*[ELSE] JAVA_SPEC_VERSION == 19 */ String scopeName = "scope"; - /*[ENDIF] JAVA_SPEC_VERSION == 19 */ - throw new IllegalStateException("Already closed: attempted to access the memory value in a closed " + scopeName); //$NON-NLS-1$ + throw new IllegalStateException("Already closed: attempted to access the memory value in a closed " + scopeName); } } - /*[ENDIF] JAVA_SPEC_VERSION >= 17 */ /*[IF JAVA_SPEC_VERSION >= 20]*/ /* Intended for memSegmtOfPtrToLongArgFilter that converts the memory segment @@ -298,67 +262,17 @@ private final long memSegmtOfPtrToLongArg(MemorySegment argValue) throws Illegal addMemArgScope(argValue.scope()); return UpcallMHMetaData.getNativeArgRetSegmentOfPtr(argValue); } - /*[ELSEIF JAVA_SPEC_VERSION >= 18] */ - /* Intended for memAddrToLongArgFilter that converts the memory address to long. - * Note: the passed-in argument can be an instance of MemoryAddress, MemorySegment - * or VaList which extends Addressable in OpenJDK since Java 18 featured with - * JEP419 (Second Incubator). - */ - private final long memAddrToLongArg(Addressable argValue) throws IllegalStateException { - /* Only check MemorySegment and VaList given MemoryAddress.scope() doesn't exist in JDK17. */ - if (argValue instanceof MemorySegment value) { - /*[IF JAVA_SPEC_VERSION == 19]*/ - addMemArgScope(value.session()); - /*[ELSE] JAVA_SPEC_VERSION == 19 */ - addMemArgScope(value.scope()); - /*[ENDIF] JAVA_SPEC_VERSION == 19 */ - } else if (argValue instanceof VaList value) { - /*[IF JAVA_SPEC_VERSION == 19]*/ - addMemArgScope(value.session()); - /*[ELSE] JAVA_SPEC_VERSION == 19 */ - addMemArgScope(value.scope()); - /*[ENDIF] JAVA_SPEC_VERSION == 19 */ - } - /*[IF JAVA_SPEC_VERSION == 18]*/ - else if (argValue instanceof NativeSymbol value) { - addMemArgScope(value.scope()); - } - /*[ENDIF] JAVA_SPEC_VERSION == 18 */ - - /* Instead of assigning nativeAddr with argValue.address().toRawLongValue() by fefault, - * (which triggers the exception in the case of the on-heap segment in JDK19), the - * argument is validated at first in the case of MemorySegment/MemoryAddress. - */ - long nativeAddr = 0; - if (argValue instanceof MemorySegment value) { - nativeAddr = UpcallMHMetaData.getNativeArgRetSegmentOfPtr(value); - } else if (argValue instanceof MemoryAddress value) { - nativeAddr = UpcallMHMetaData.getNativeArgRetAddrOfPtr(value); - } else { - nativeAddr = argValue.address().toRawLongValue(); - } - return nativeAddr; - } - /*[ELSEIF JAVA_SPEC_VERSION == 17]*/ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ /* Intended for memAddrToLongArgFilter that converts the memory address to long. */ private final long memAddrToLongArg(MemoryAddress argValue) throws IllegalStateException { addMemArgScope(argValue.scope()); return UpcallMHMetaData.getNativeArgRetAddrOfPtr(argValue); } - /*[ELSE] JAVA_SPEC_VERSION == 17 */ - /* Intended for memAddrToLongArgFilter that converts the memory address to long. */ - private static final long memAddrToLongArg(MemoryAddress argValue) { - return argValue.address().toRawLongValue(); - } /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ /* Intended for memSegmtToLongArgFilter that converts the memory segment to long. */ private final long memSegmtToLongArg(MemorySegment argValue) throws IllegalStateException { - /*[IF JAVA_SPEC_VERSION == 19]*/ - addMemArgScope(argValue.session()); - /*[ELSE] JAVA_SPEC_VERSION == 19 */ addMemArgScope(argValue.scope()); - /*[ENDIF] JAVA_SPEC_VERSION == 19 */ return UpcallMHMetaData.getNativeArgRetSegment(argValue); } @@ -448,7 +362,7 @@ private static final MemorySegment objToMemSegmtRet(Object retValue) { * @param options The linker options indicating additional linking requirements to the linker */ public InternalDowncallHandler(MethodType functionMethodType, FunctionDescriptor functionDescriptor, LinkerOptions options) - /*[ELSEIF JAVA_SPEC_VERSION >= 17]*/ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ /** * The internal constructor is responsible for mapping the preprocessed layouts * of return type & argument types to the underlying prep_cif in native. @@ -457,23 +371,13 @@ public InternalDowncallHandler(MethodType functionMethodType, FunctionDescriptor * @param funcDesc The function descriptor of the specified native function */ public InternalDowncallHandler(MethodType functionMethodType, FunctionDescriptor functionDescriptor) - /*[ELSE] JAVA_SPEC_VERSION >= 17 */ - /** - * The internal constructor is responsible for mapping the preprocessed layouts - * of return type & argument types to the underlying prep_cif in native. - * - * @param downcallAddr The downcall symbol - * @param functionMethodType The MethodType of the specified native function - * @param funcDesc The function descriptor of the specified native function - */ - public InternalDowncallHandler(Addressable downcallAddr, MethodType functionMethodType, FunctionDescriptor functionDescriptor) /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { realReturnLayout = functionDescriptor.returnLayout().orElse(null); // set to null for void List argLayouts = functionDescriptor.argumentLayouts(); argLayoutArray = argLayouts.toArray(new MemoryLayout[argLayouts.size()]); - /*[IF JAVA_SPEC_VERSION <= 17]*/ + /*[IF JAVA_SPEC_VERSION == 17]*/ /* The layout check against the method type is still required for Java 16 & 17 in that * both the function descriptor and the method type are passed in as arguments by users. * Note: skip the validity check on function descriptor in Java 18 as it is done before @@ -482,20 +386,7 @@ public InternalDowncallHandler(Addressable downcallAddr, MethodType functionMeth * check the layout against the method type. */ TypeLayoutCheckHelper.checkIfValidLayoutAndType(functionMethodType, argLayoutArray, realReturnLayout); - - /*[IF JAVA_SPEC_VERSION == 16]*/ - /* 1) The native function address has been removed from the parameter lists of downcallHandle() APIs - * since JDK17 so as to being passed in as the first argument when invoking the returned downcall handle - * or bound as the first argument via MethodHandles.insertArguments() beforehand in OpenJDK. - /* 2) As explained in the Spec of LibraryLookup in JDK16, the downcall must hold a strong reference to - * the native library symbol to prevent the underlying native library from being unloaded during the - * native calls, which is no longer required since JDK17 as the symbol intende for for the current thread - * is directly passed to the native invocation so as to fit in the multithreading environment. - * Note: the passed-in addressable parameter can be either LibraryLookup.Symbol or MemoryAddress. - */ - functionAddr = downcallAddr; - /*[ENDIF] JAVA_SPEC_VERSION == 16 */ - /*[ENDIF] JAVA_SPEC_VERSION <= 17 */ + /*[ENDIF] JAVA_SPEC_VERSION == 17 */ funcMethodType = functionMethodType; funcDescriptor = functionDescriptor; @@ -513,15 +404,12 @@ public InternalDowncallHandler(Addressable downcallAddr, MethodType functionMeth try { /*[IF JAVA_SPEC_VERSION >= 20]*/ - longObjToMemSegmtRetFilter = lookup.bind(this, "longObjToMemSegmtRet", methodType(MemorySegment.class, Object.class)); //$NON-NLS-1$ - memSegmtOfPtrToLongArgFilter = lookup.bind(this, "memSegmtOfPtrToLongArg", methodType(long.class, MemorySegment.class)); //$NON-NLS-1$ - /*[ELSEIF JAVA_SPEC_VERSION >= 18]*/ - memAddrToLongArgFilter = lookup.bind(this, "memAddrToLongArg", methodType(long.class, Addressable.class)); //$NON-NLS-1$ - /*[ELSE] JAVA_SPEC_VERSION >= 18 */ - memAddrToLongArgFilter = lookup.bind(this, "memAddrToLongArg", methodType(long.class, MemoryAddress.class)); //$NON-NLS-1$ + longObjToMemSegmtRetFilter = lookup.bind(this, "longObjToMemSegmtRet", methodType(MemorySegment.class, Object.class)); + memSegmtOfPtrToLongArgFilter = lookup.bind(this, "memSegmtOfPtrToLongArg", methodType(long.class, MemorySegment.class)); + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ + memAddrToLongArgFilter = lookup.bind(this, "memAddrToLongArg", methodType(long.class, MemoryAddress.class)); /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ - - memSegmtToLongArgFilter = lookup.bind(this, "memSegmtToLongArg", methodType(long.class, MemorySegment.class)); //$NON-NLS-1$ + memSegmtToLongArgFilter = lookup.bind(this, "memSegmtToLongArg", methodType(long.class, MemorySegment.class)); } catch (ReflectiveOperationException e) { throw new InternalError(e); } @@ -533,7 +421,7 @@ public InternalDowncallHandler(Addressable downcallAddr, MethodType functionMeth private void generateAdapter() { int argLayoutCount = argLayoutArray.length; String[] argLayoutStrs = new String[argLayoutCount]; - StringBuilder argLayoutStrsLine = new StringBuilder("(|"); //$NON-NLS-1$ + StringBuilder argLayoutStrsLine = new StringBuilder("(|"); for (int argIndex = 0; argIndex < argLayoutCount; argIndex++) { MemoryLayout argLayout = argLayoutArray[argIndex]; /* Prefix the size of layout to the layout string to be parsed in native. */ @@ -546,28 +434,22 @@ private void generateAdapter() { * as the corresponding layout doesn't exist in the Spec. * Note: 'V' stands for the void type and 0 means zero byte. */ - String retLayoutStr = "0V"; //$NON-NLS-1$ + String retLayoutStr = "0V"; if (realReturnLayout != null) { retLayoutStr = LayoutStrPreprocessor.getSimplifiedLayoutString(realReturnLayout, true); } - synchronized(privateClassLock) { + synchronized (privateClassLock) { /* If a prep_cif for a given function descriptor exists, then the corresponding return & argument layouts * were already set up for this prep_cif, in which case there is no need to check the layouts. * If not the case, check at first whether the same return & argument layouts exist in the cache * in case of duplicate memory allocation for the same layouts. * - * Note: (Java <= 17) - * 1) C_LONG (Linux) and C_LONG_LONG(Windows/AIX 64bit) should be treated as the same layout in the cache. + * Note: (JDK17) + * 1) C_LONG (Linux) and C_LONG_LONG (Windows/AIX 64bit) should be treated as the same layout in the cache. * 2) the same layout kind with or without the layout name should be treated as the same layout. * e.g. C_INT without the layout name = b32[abi/kind=INT] * and C_INT with the layout name = b32(int)[abi/kind=INT,layout/name=int] - * Note: (Java >= 18) - * the signature information are removed from the string of function descriptor since Java 18, - * e.g. (b32[abi/kind=INT],b32[abi/kind=INT])b32[abi/kind=INT] are replaced by ([8%b32, 8%b32])8%b32. - * So we have to unify the code in Java 17 & 18 to parse the layout with different solutions: - * 1) generate the layout string with CLinker.TypeKind in Java 17. - * 2) generate the layout string with MemoryLayout.carrier() (the type idenfied by the layout) in Java 18. */ /*[IF JAVA_SPEC_VERSION >= 20]*/ int varArgIdx = LayoutStrPreprocessor.getVarArgIndex(funcDescriptor, linkerOpts); @@ -609,21 +491,17 @@ public MethodHandle getBoundMethodHandle() { try { /*[IF JAVA_SPEC_VERSION >= 20]*/ Class downcallAddrClass = MemorySegment.class; - /*[ELSEIF JAVA_SPEC_VERSION == 18]*/ - Class downcallAddrClass = NativeSymbol.class; - /*[ELSE] JAVA_SPEC_VERSION == 18 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ Class downcallAddrClass = Addressable.class; /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ /*[IF JAVA_SPEC_VERSION >= 20]*/ MethodType nativeMethodType = methodType(Object.class, downcallAddrClass, SegmentAllocator.class, MemorySegment.class, long[].class); - /*[ELSEIF JAVA_SPEC_VERSION >= 17]*/ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ MethodType nativeMethodType = methodType(Object.class, downcallAddrClass, SegmentAllocator.class, long[].class); - /*[ELSE] JAVA_SPEC_VERSION >= 17 */ - MethodType nativeMethodType = methodType(Object.class, long[].class); /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ - MethodHandle boundHandle = lookup.bind(this, "runNativeMethod", nativeMethodType); //$NON-NLS-1$ + MethodHandle boundHandle = lookup.bind(this, "runNativeMethod", nativeMethodType); /* Replace the original handle with the specified types of the C function. */ boundHandle = permuteMH(boundHandle, funcMethodType); @@ -642,11 +520,9 @@ private MethodHandle permuteMH(MethodHandle targetHandle, MethodType nativeMetho * for the execution state to the native function's arguments. */ int argPosition = 3; - /*[ELSEIF JAVA_SPEC_VERSION >= 17]*/ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ /* Skip the native function address and the segment allocator to the native function's arguments. */ int argPosition = 2; - /*[ELSE] JAVA_SPEC_VERSION >= 17 */ - int argPosition = 0; /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ MethodHandle resultHandle = targetHandle.asCollector(argPosition, long[].class, nativeArgCount); @@ -692,15 +568,12 @@ private MethodHandle getArgumentFilter(Class argTypeClass, MemoryLayout argLa } else if (argTypeClass == double.class) { filterMH = doubleToLongArgFilter; } else - /*[IF JAVA_SPEC_VERSION <= 19]*/ + /*[IF JAVA_SPEC_VERSION == 17]*/ if ((argTypeClass == MemoryAddress.class) - /*[IF JAVA_SPEC_VERSION >= 18]*/ - || (argTypeClass == Addressable.class) - /*[ENDIF] JAVA_SPEC_VERSION >= 18 */ ) { filterMH = memAddrToLongArgFilter; } else - /*[ENDIF] JAVA_SPEC_VERSION <= 19 */ + /*[ENDIF] JAVA_SPEC_VERSION == 17 */ if (argTypeClass == MemorySegment.class) { /*[IF JAVA_SPEC_VERSION >= 20]*/ /* The address layout for pointer might come with different representations of ADDRESS. */ @@ -739,15 +612,12 @@ private MethodHandle getReturnValFilter(Class returnType) { } else if (returnType == double.class) { filterMH = longObjToDoubleRetFilter; } else - /*[IF JAVA_SPEC_VERSION <= 19]*/ + /*[IF JAVA_SPEC_VERSION == 17]*/ if ((returnType == MemoryAddress.class) - /*[IF JAVA_SPEC_VERSION >= 18]*/ - || (returnType == Addressable.class) - /*[ENDIF] JAVA_SPEC_VERSION >= 18 */ ) { filterMH = longObjToMemAddrRetFilter; } else - /*[ENDIF] JAVA_SPEC_VERSION <= 19 */ + /*[ENDIF] JAVA_SPEC_VERSION == 17 */ if (returnType == MemorySegment.class) { /*[IF JAVA_SPEC_VERSION >= 20]*/ /* A returned pointer is wrapped as a zero-sized memory segment given all @@ -766,30 +636,15 @@ private MethodHandle getReturnValFilter(Class returnType) { return filterMH; } - /*[IF JAVA_SPEC_VERSION >= 19]*/ + /*[IF JAVA_SPEC_VERSION >= 20]*/ /* Set up the dependency from the sessions of memory related arguments to the specified session - * so as to keep these arguments' sessions alive till the specified session is closed. + * so as to keep these arguments' session alive till the specified session is closed. */ - /*[IF JAVA_SPEC_VERSION >= 20]*/ private void SetDependency(SegmentScope session) - /*[ELSE] JAVA_SPEC_VERSION >= 20 */ - private void SetDependency(MemorySession session) - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { Objects.requireNonNull(session); - /*[IF JAVA_SPEC_VERSION >= 20]*/ for (SegmentScope memArgSession : memArgScopeSet) - /*[ELSE] JAVA_SPEC_VERSION >= 20 */ - for (MemorySession memArgSession : memArgScopeSet) - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { - /* keepAlive() is replaced with whileAlive(Runnable action) since JDK19 in which case - * the only way to invoke the native in downcall is to wrap it up in another thread - * (for the critical action) rather than the current thread owning the downcall handler, - * which is incorrect in our situation given the downcall must be executed by the owner - * thread according to the API Spec. So we have to directly implement the equivalent of - * keepAlive() in JDK19 to set up the state of arguments' session. - */ if (memArgSession.isAlive()) { MemorySessionImpl memArgSessionImpl = (MemorySessionImpl)memArgSession; Thread owner = memArgSessionImpl.ownerThread(); @@ -803,26 +658,10 @@ private void SetDependency(MemorySession session) } } } - /*[ELSEIF JAVA_SPEC_VERSION == 18]*/ - /* Set up the dependency from the scopes of memory related arguments to the specified scope - * so as to keep these arguments' scopes alive till the specified scope is closed. + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ + /* Occupy the scope by setting the scope's state in downcall so as to keep these + * arguments' scope alive till the specified session is closed. */ - private void SetDependency(ResourceScope scope) { - Objects.requireNonNull(scope); - for (ResourceScope memArgScope : memArgScopeSet) { - if (memArgScope.isAlive()) { - Thread owner = memArgScope.ownerThread(); - /* The check is intended for the confined scope or - * the shared scope(e.g. implicit/global scope). - */ - if ((owner == Thread.currentThread()) || (owner == null)) { - scope.keepAlive(memArgScope); // keepAlive() is only used in JDK18 - } - } - } - } - /*[ELSEIF JAVA_SPEC_VERSION == 17]*/ - /* Occupy the scope by setting the scope's state in downcall which is similiar to keepAlive() in JDK18. */ private void acquireScope() { for (ResourceScope memArgScope : memArgScopeSet) { if (memArgScope.isAlive()) { @@ -838,7 +677,7 @@ private void acquireScope() { } } - /* Release the scope with the scope's handle in downcall */ + /* Release the scope with the scope's handle in downcall. */ private void releaseScope() { for (ResourceScope memArgScope : memArgScopeSet) { if (memArgScope.isAlive()) { @@ -853,31 +692,23 @@ private void releaseScope() { } } } - /*[ENDIF] JAVA_SPEC_VERSION >= 19 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ /* The method (bound by the method handle to the native code) intends to invoke the C function via the inlined code. */ - /*[IF JAVA_SPEC_VERSION >= 17]*/ /*[IF JAVA_SPEC_VERSION >= 20]*/ Object runNativeMethod(MemorySegment downcallAddr, SegmentAllocator segmtAllocator, MemorySegment stateSegmt, long[] args) throws IllegalArgumentException, IllegalStateException - /*[ELSEIF JAVA_SPEC_VERSION == 18]*/ - Object runNativeMethod(NativeSymbol downcallAddr, SegmentAllocator segmtAllocator, long[] args) throws IllegalArgumentException, IllegalStateException - /*[ELSE] JAVA_SPEC_VERSION == 18 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator, long[] args) throws IllegalArgumentException, IllegalStateException /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ - /*[ELSE] JAVA_SPEC_VERSION >= 17 */ - Object runNativeMethod(long[] args) - /*[ENDIF] JAVA_SPEC_VERSION >= 17 */ { - /*[IF JAVA_SPEC_VERSION >= 17]*/ /*[IF JAVA_SPEC_VERSION >= 20]*/ if (downcallAddr == MemorySegment.NULL) /*[ELSE] JAVA_SPEC_VERSION >= 20 */ if (downcallAddr.address() == MemoryAddress.NULL) /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { - throw new IllegalArgumentException("A non-null memory address is expected for downcall"); //$NON-NLS-1$ + throw new IllegalArgumentException("A non-null memory address is expected for downcall"); } - /*[ENDIF] JAVA_SPEC_VERSION >= 17 */ /*[IF JAVA_SPEC_VERSION >= 20]*/ /* The scope of the downcall function address needs to be validated in OpenJ9 @@ -894,18 +725,13 @@ Object runNativeMethod(long[] args) * JDK20+. */ if ((realReturnLayout != null) && (realReturnLayout instanceof GroupLayout)) { - /*[IF JAVA_SPEC_VERSION >= 17]*/ - /* The segment allocator (introduced since Java 17 to replace NativeScope in Java 16) is confined - * by the memory session(Java19)/resource scope(Java17/18) defined in user applications in which - * case the allocated memory will be released automatically once the session/scope is closed. + /* The segment allocator (introduced since Java 17) is confined by the memory session/scope + * defined in the user applications in which case the allocated memory will be released + * automatically once the session/scope is closed. */ retStruSegmt = segmtAllocator.allocate(realReturnLayout); - /*[ELSE] JAVA_SPEC_VERSION >= 17 */ - /* The memory segment will be released explicitly by users via close() in java code in Java 16. */ - retStruSegmt = MemorySegment.allocateNative(realReturnLayout); - /*[ENDIF] JAVA_SPEC_VERSION >= 17 */ if (retStruSegmt == null) { - throw new OutOfMemoryError("Failed to allocate native memory for the returned memory segment"); //$NON-NLS-1$ + throw new OutOfMemoryError("Failed to allocate native memory for the returned memory segment"); } /*[IF JAVA_SPEC_VERSION >= 20]*/ retMemAddr = retStruSegmt.address(); @@ -917,44 +743,21 @@ Object runNativeMethod(long[] args) long returnVal = 0; /* The session/scope associated with memory specific arguments must be kept alive in downcall since JDK17. */ if (!memArgScopeSet.isEmpty()) { - /*[IF JAVA_SPEC_VERSION > 17]*/ /*[IF JAVA_SPEC_VERSION >= 20]*/ - try (Arena arena = Arena.openConfined()) - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - try (MemorySession nativeSession = MemorySession.openConfined()) - /*[ELSEIF JAVA_SPEC_VERSION == 18]*/ - try (ResourceScope nativeScope = ResourceScope.newConfinedScope()) - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ - { - /*[IF JAVA_SPEC_VERSION >= 20]*/ + try (Arena arena = Arena.openConfined()) { SetDependency(arena.scope()); - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - SetDependency(nativeSession); - /*[ELSEIF JAVA_SPEC_VERSION == 18]*/ - SetDependency(nativeScope); - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ - - /*[IF JAVA_SPEC_VERSION >= 20]*/ returnVal = invokeNative(stateSegmt.address(), retMemAddr, downcallAddr.address(), cifNativeThunkAddr, args); - /*[ELSE] JAVA_SPEC_VERSION >= 20 */ - returnVal = invokeNative(retMemAddr, downcallAddr.address().toRawLongValue(), cifNativeThunkAddr, args); - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ } - /*[ELSE] JAVA_SPEC_VERSION > 17 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ acquireScope(); returnVal = invokeNative(retMemAddr, downcallAddr.address().toRawLongValue(), cifNativeThunkAddr, args); releaseScope(); - /*[ENDIF] JAVA_SPEC_VERSION > 17 */ - } - else - { + /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ + } else { /*[IF JAVA_SPEC_VERSION >= 20]*/ returnVal = invokeNative(stateSegmt.address(), retMemAddr, downcallAddr.address(), cifNativeThunkAddr, args); - /*[ELSEIF JAVA_SPEC_VERSION >= 17]*/ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ returnVal = invokeNative(retMemAddr, downcallAddr.address().toRawLongValue(), cifNativeThunkAddr, args); - /*[ELSE] JAVA_SPEC_VERSION >= 17 */ - /* The given function address never changes since the initialization of the downcall handler in JDK16. */ - returnVal = invokeNative(retMemAddr, functionAddr.address().toRawLongValue(), cifNativeThunkAddr, args); /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ } diff --git a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalUpcallHandler.java b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalUpcallHandler.java index 11186040314..ebf90d9ff96 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalUpcallHandler.java +++ b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalUpcallHandler.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF JAVA_SPEC_VERSION >= 19]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 20]*/ /******************************************************************************* * Copyright IBM Corp. and others 2022 * @@ -28,30 +28,22 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; -/*[IF JAVA_SPEC_VERSION >= 19]*/ +/*[IF JAVA_SPEC_VERSION >= 20]*/ import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; -/*[IF JAVA_SPEC_VERSION >= 20]*/ import java.lang.foreign.SegmentScope; /*[ELSE] JAVA_SPEC_VERSION >= 20 */ -import java.lang.foreign.MemorySession; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ -/*[ELSE] JAVA_SPEC_VERSION >= 19 */ import jdk.incubator.foreign.FunctionDescriptor; import jdk.incubator.foreign.MemoryLayout; -/*[IF JAVA_SPEC_VERSION <= 18]*/ -/*[IF JAVA_SPEC_VERSION == 18]*/ -import jdk.incubator.foreign.NativeSymbol; -/*[ENDIF] JAVA_SPEC_VERSION == 18 */ import jdk.incubator.foreign.ResourceScope; -/*[ENDIF] JAVA_SPEC_VERSION <= 18 */ -/*[ENDIF] JAVA_SPEC_VERSION >= 19 */ +/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ /** * The internal implementation of upcall handler wraps up an upcall handle * enabling the native call to the java code at runtime. */ +@SuppressWarnings("nls") public final class InternalUpcallHandler { private final MemoryLayout[] argLayoutArray; @@ -68,22 +60,9 @@ public final class InternalUpcallHandler { * @param mt The method type of the target method handle * @param cDesc The function descriptor of the target method handle * @param session The segment scope related to the upcall handler - * @return an internal upcall handler with the thunk address */ public InternalUpcallHandler(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, SegmentScope session) - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - /** - * The constructor creates an upcall handler specific to the requested java method - * by generating a native thunk in upcall on a given platform. - * - * @param target The target method handle in upcall - * @param mt The method type of the target method handle - * @param cDesc The function descriptor of the target method handle - * @param session The memory session related to the upcall handler - * @return an internal upcall handler with the thunk address - */ - public InternalUpcallHandler(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, MemorySession session) - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ /** * The constructor creates an upcall handler specific to the requested java method * by generating a native thunk in upcall on a given platform. @@ -92,7 +71,6 @@ public InternalUpcallHandler(MethodHandle target, MethodType mt, FunctionDescrip * @param mt The method type of the target method handle * @param cDesc The function descriptor of the target method handle * @param scope The resource scope related to the upcall handler - * @return an internal upcall handler with the thunk address */ public InternalUpcallHandler(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ @@ -101,22 +79,18 @@ public InternalUpcallHandler(MethodHandle target, MethodType mt, FunctionDescrip argLayoutArray = argLayouts.toArray(new MemoryLayout[argLayouts.size()]); realReturnLayout = cDesc.returnLayout().orElse(null); // Set to null for void - /*[IF JAVA_SPEC_VERSION <= 17]*/ - /* The layout check against the method type is still required for Java 16 & 17 in that - * both the function descriptor and the method type are passed in as arguments by users. - * Note: skip the validity check on function descriptor in Java 18 as it is done before - * initializing ProgrammableUpcallHandler in OpenJDK. Meanwhile, the method type is - * directly deduced from the function descriptor itself, in which case there is no need - * to check the layout against the method type. + /*[IF JAVA_SPEC_VERSION == 17]*/ + /* The layout check against the method type is still required for Java 17 in that both + * the function descriptor and the method type are passed in as arguments by users. */ TypeLayoutCheckHelper.checkIfValidLayoutAndType(mt, argLayoutArray, realReturnLayout); - /*[ENDIF] JAVA_SPEC_VERSION <= 17 */ + /*[ENDIF] JAVA_SPEC_VERSION == 17 */ - /*[IF JAVA_SPEC_VERSION >= 19]*/ + /*[IF JAVA_SPEC_VERSION >= 20]*/ thunkAddr = getUpcallThunkAddr(target, session); - /*[ELSE] JAVA_SPEC_VERSION >= 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ thunkAddr = getUpcallThunkAddr(target, scope); - /*[ENDIF] JAVA_SPEC_VERSION >= 19 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ } /** @@ -134,9 +108,7 @@ public long upcallThunkAddr() { */ /*[IF JAVA_SPEC_VERSION >= 20]*/ private long getUpcallThunkAddr(MethodHandle target, SegmentScope sessionOrScope) - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - private long getUpcallThunkAddr(MethodHandle target, MemorySession sessionOrScope) - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ private long getUpcallThunkAddr(MethodHandle target, ResourceScope sessionOrScope) /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { @@ -153,15 +125,15 @@ private long getUpcallThunkAddr(MethodHandle target, ResourceScope sessionOrScop * Note: 'V' stands for the void type. */ if (realReturnLayout == null) { - nativeSignatureStrs[argLayoutCount] = "0#V"; //$NON-NLS-1$ + nativeSignatureStrs[argLayoutCount] = "0#V"; } else { nativeSignatureStrs[argLayoutCount] = LayoutStrPreprocessor.getSimplifiedLayoutString(realReturnLayout, false); } - /* The thunk must be created for each upcall handler given the UpcallMHMetaData object uniquely bound - * to the thunk is only alive for a SegmentScope(JDK20+)/MemorySession(JDK19)/ResourceScope(JDK17/18) - * specified in java, which means the upcall handler and its UpcallMHMetaData object will be cleaned - * up automatically once their session/scope is closed. + /* The thunk must be created for each upcall handler given the UpcallMHMetaData object uniquely + * bound to the thunk is only alive for a SegmentScope(JDK20+)/ResourceScope(JDK17) specified in + * java, which means the upcall handler and its UpcallMHMetaData object will be cleaned up + * automatically once their session/scope is closed. */ metaData = new UpcallMHMetaData(target, argLayoutCount, sessionOrScope); return allocateUpcallStub(metaData, nativeSignatureStrs); diff --git a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/LayoutStrPreprocessor.java b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/LayoutStrPreprocessor.java index 7da5253399e..9291edec5bd 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/LayoutStrPreprocessor.java +++ b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/LayoutStrPreprocessor.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF JAVA_SPEC_VERSION >= 19]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 20]*/ /******************************************************************************* * Copyright IBM Corp. and others 2022 * @@ -24,75 +24,67 @@ import java.util.List; -/*[IF JAVA_SPEC_VERSION >= 19]*/ +/*[IF JAVA_SPEC_VERSION >= 20]*/ import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.GroupLayout; -/*[IF JAVA_SPEC_VERSION == 19]*/ -import java.lang.foreign.MemoryAddress; -/*[ENDIF] JAVA_SPEC_VERSION == 19 */ import java.lang.foreign.MemoryLayout; -/*[IF JAVA_SPEC_VERSION >= 20]*/ import java.lang.foreign.MemorySegment; import java.lang.foreign.PaddingLayout; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ import java.lang.foreign.SequenceLayout; import java.lang.foreign.ValueLayout; -/*[IF JAVA_SPEC_VERSION >= 20]*/ import jdk.internal.foreign.abi.LinkerOptions; -/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ -/*[ELSE] JAVA_SPEC_VERSION >= 19 */ -/*[IF JAVA_SPEC_VERSION <= 17]*/ +/*[ELSE] JAVA_SPEC_VERSION >= 20 */ import jdk.incubator.foreign.CLinker.TypeKind; import static jdk.incubator.foreign.CLinker.TypeKind.*; -/*[ENDIF] JAVA_SPEC_VERSION <= 17 */ import jdk.incubator.foreign.FunctionDescriptor; import jdk.incubator.foreign.GroupLayout; import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.MemoryLayout; import jdk.incubator.foreign.SequenceLayout; import jdk.incubator.foreign.ValueLayout; -/*[ENDIF] JAVA_SPEC_VERSION >= 19 */ +/*[ENDIF] JAVA_SPEC_VERSION >= 20 */ /** * The methods of the class are used to preprocess the layout specified in the function * descriptor of downcall or upcall by removing all unnecessary attributes and converting * it to a simplified symbol string. */ +@SuppressWarnings("nls") final class LayoutStrPreprocessor { - /*[IF JAVA_SPEC_VERSION <= 17]*/ + /*[IF JAVA_SPEC_VERSION == 17]*/ private static final String VARARGS_ATTR_NAME; static { - final String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ - final String arch = System.getProperty("os.arch").toLowerCase(); //$NON-NLS-1$ + final String osName = System.getProperty("os.name").toLowerCase(); + final String arch = System.getProperty("os.arch").toLowerCase(); /* Note: the attributes intended for the layout with variadic argument are defined in OpenJDK. */ - if ((arch.equals("amd64") || arch.equals("x86_64"))) { //$NON-NLS-1$ //$NON-NLS-2$ - if (osName.startsWith("windows")) { //$NON-NLS-1$ - VARARGS_ATTR_NAME = "abi/windows/varargs"; //$NON-NLS-1$ + if ((arch.equals("amd64") || arch.equals("x86_64"))) { + if (osName.startsWith("windows")) { + VARARGS_ATTR_NAME = "abi/windows/varargs"; } else { - VARARGS_ATTR_NAME = "abi/sysv/varargs";; //$NON-NLS-1$ + VARARGS_ATTR_NAME = "abi/sysv/varargs"; } - } else if (arch.equals("aarch64")) { //$NON-NLS-1$ - if (osName.startsWith("mac")) { //$NON-NLS-1$ - VARARGS_ATTR_NAME = "abi/aarch64/stack_varargs";; //$NON-NLS-1$ + } else if (arch.equals("aarch64")) { + if (osName.startsWith("mac")) { + VARARGS_ATTR_NAME = "abi/aarch64/stack_varargs"; } else { - VARARGS_ATTR_NAME = "abi/sysv/varargs"; //$NON-NLS-1$; + VARARGS_ATTR_NAME = "abi/sysv/varargs"; } - } else if (arch.startsWith("ppc64")) { //$NON-NLS-1$ - if (osName.startsWith("linux")) { //$NON-NLS-1$ - VARARGS_ATTR_NAME = "abi/ppc64/sysv/varargs"; //$NON-NLS-1$ + } else if (arch.startsWith("ppc64")) { + if (osName.startsWith("linux")) { + VARARGS_ATTR_NAME = "abi/ppc64/sysv/varargs"; } else { - VARARGS_ATTR_NAME = "abi/ppc64/aix/varargs"; //$NON-NLS-1$ + VARARGS_ATTR_NAME = "abi/ppc64/aix/varargs"; } - } else if (arch.equals("s390x") && osName.startsWith("linux")) { //$NON-NLS-1$ //$NON-NLS-2$ - VARARGS_ATTR_NAME = "abi/s390x/sysv/varargs"; //$NON-NLS-1$ + } else if (arch.equals("s390x") && osName.startsWith("linux")) { + VARARGS_ATTR_NAME = "abi/s390x/sysv/varargs"; } else { - throw new InternalError("Unsupported platform: " + arch + "_" + osName); //$NON-NLS-1$ //$NON-NLS-2$ + throw new InternalError("Unsupported platform: " + arch + "_" + osName); } } - /*[ENDIF] JAVA_SPEC_VERSION <= 17 */ + /*[ENDIF] JAVA_SPEC_VERSION == 17 */ /* Get the index of the variadic argument layout in the function descriptor if exists. */ /*[IF JAVA_SPEC_VERSION >= 20]*/ @@ -108,9 +100,6 @@ static int getVarArgIndex(FunctionDescriptor funcDesc) */ int varArgIdx = -1; - /*[IF JAVA_SPEC_VERSION == 19]*/ - varArgIdx = funcDesc.firstVariadicArgumentIndex(); - /*[ELSE] JAVA_SPEC_VERSION == 19 */ for (int argIndex = 0; argIndex < argLayoutsSize; argIndex++) { /*[IF JAVA_SPEC_VERSION >= 20]*/ if (options.isVarargsIndex(argIndex)) @@ -122,7 +111,6 @@ static int getVarArgIndex(FunctionDescriptor funcDesc) break; } } - /*[ENDIF] JAVA_SPEC_VERSION == 19 */ return varArgIdx; } @@ -160,7 +148,7 @@ private static long getTotalPaddingBytesOfStruct(MemoryLayout targetLayout) { * 3) 7 padding bytes for struct [bool/byte, long/double]. */ if ((tempPaddingBytes <= 0) || (tempPaddingBytes > 7)) { - throw new IllegalArgumentException("The padding bits is invalid: x" + (tempPaddingBytes * 8)); //$NON-NLS-1$ + throw new IllegalArgumentException("The padding bits is invalid: x" + (tempPaddingBytes * 8)); } paddingBytes += tempPaddingBytes; } else { @@ -174,7 +162,7 @@ private static long getTotalPaddingBytesOfStruct(MemoryLayout targetLayout) { /* Preprocess the layout to generate a concise layout string with all kind symbols * extracted from the layout to simplify parsing the layout string in native. - * e.g. a struct layout string with nested struct is as follows: (Only for Java <= 17) + * e.g. a struct layout string with nested struct is as follows: (Only for Java 17) * [ * [ * b32(elem1)[abi/kind=INT,layout/name=elem1] @@ -201,25 +189,23 @@ private static long getTotalPaddingBytesOfStruct(MemoryLayout targetLayout) { * where "#" denotes the start of struct. * * Note: - * 1) the prefix "ByteSize#CountOfElmemnt" and "#CountOfElmemnt" are not required in + * The prefix "ByteSize#CountOfElmemnt" and "#CountOfElmemnt" are not required in * the upcall given the converted layout stirngs are further parsed for the generated * thunk in native, which is logically different from downcall. - * 2) the parsing of primitives in layouts in Java 18 is based on the MemoryLayout.carrier() - * rather than the CLinker.TypeKind which is entirely removed in OpenJDK. */ private static StringBuilder preprocessLayout(MemoryLayout targetLayout, boolean isDownCall) { - StringBuilder targetLayoutString = new StringBuilder(""); //$NON-NLS-1$ + StringBuilder targetLayoutString = new StringBuilder(""); - /* Directly obtain the kind symbol of the primitive layout */ + /* Directly obtain the kind symbol of the primitive layout. */ if (targetLayout instanceof ValueLayout valueLayout) { targetLayoutString.append(getPrimitiveTypeSymbol(valueLayout)); - } else if (targetLayout instanceof SequenceLayout arrayLayout) { // Intended for nested arrays + } else if (targetLayout instanceof SequenceLayout arrayLayout) { /* Intended for nested arrays. */ MemoryLayout elementLayout = arrayLayout.elementLayout(); - /*[IF JAVA_SPEC_VERSION >= 19]*/ + /*[IF JAVA_SPEC_VERSION >= 20]*/ long elementCount = arrayLayout.elementCount(); - /*[ELSE] JAVA_SPEC_VERSION >= 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ long elementCount = arrayLayout.elementCount().getAsLong(); - /*[ENDIF] JAVA_SPEC_VERSION >= 19 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ /* The padding bytes is required in the native signature for upcall thunk generation. */ if (isPaddingLayout(elementLayout) && !isDownCall) { @@ -227,10 +213,10 @@ private static StringBuilder preprocessLayout(MemoryLayout targetLayout, boolean } else { targetLayoutString.append(elementCount).append(':').append(preprocessLayout(elementLayout, isDownCall)); } - } else if (targetLayout instanceof GroupLayout structLayout) { // Intended for the nested structs + } else if (targetLayout instanceof GroupLayout structLayout) { /* Intended for the nested structs. */ List elementLayoutList = structLayout.memberLayouts(); int structElementCount = elementLayoutList.size(); - StringBuilder elementLayoutStrs = new StringBuilder(""); //$NON-NLS-1$ + StringBuilder elementLayoutStrs = new StringBuilder(""); int paddingElements = 0; for (int elemIndex = 0; elemIndex < structElementCount; elemIndex++) { MemoryLayout structElement = elementLayoutList.get(elemIndex); @@ -264,76 +250,68 @@ private static boolean isPaddingLayout(MemoryLayout targetLayout) { /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ } - /* Map the specified primitive layout's kind to the symbol for primitive type in VM Spec - * - * Note: - * CLinker.TypeKind is entirely removed since Java 18, in which case we need to - * reply on MemoryLayout.carrier() (simply the type identified by the layout) for the native - * signature of the layout. - */ - /*[IF JAVA_SPEC_VERSION >= 18]*/ + /* Map the specified primitive layout's kind to the symbol for primitive type in VM Spec. */ + /*[IF JAVA_SPEC_VERSION >= 20]*/ private static String getPrimitiveTypeSymbol(ValueLayout targetLayout) { Class javaType = targetLayout.carrier(); - String typeSymbol = ""; //$NON-NLS-1$ + String typeSymbol = ""; - if (javaType == byte.class) { // JAVA_BYTE corresponds to C_CHAR (1 byte) in native - typeSymbol = "C"; //$NON-NLS-1$ - } else if (javaType == char.class) { // JAVA_CHAR in Java corresponds to C_SHORT (2 bytes) in native - typeSymbol = "S"; //$NON-NLS-1$ - } else if (javaType == long.class) { // JAVA_CHAR in Java corresponds to C_SHORT (2 bytes) in native - typeSymbol = "J"; //$NON-NLS-1$ // Map JAVA_LONG to 'J' so as to keep consistent with the existing VM Spec - } else - /*[IF JAVA_SPEC_VERSION >= 20]*/ - if (javaType == MemorySegment.class) - /*[ELSE] JAVA_SPEC_VERSION >= 20 */ - if (javaType == MemoryAddress.class) - /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ - { - typeSymbol = "P"; //$NON-NLS-1$ + if (javaType == byte.class) { + /* JAVA_BYTE corresponds to C_CHAR (1 byte) in native. */ + typeSymbol = "C"; + } else if (javaType == char.class) { + /* JAVA_CHAR in Java corresponds to C_SHORT (2 bytes) in native. */ + typeSymbol = "S"; + } else if (javaType == long.class) { + /* Map JAVA_LONG to 'J' so as to keep consistent with the existing VM Spec. */ + typeSymbol = "J"; + } else if (javaType == MemorySegment.class) { + typeSymbol = "P"; } else { /* Obtain the 1st character of the type class as the symbol of the native signature. */ typeSymbol = javaType.getSimpleName().substring(0, 1).toUpperCase(); } + return typeSymbol; } - /*[ELSE] JAVA_SPEC_VERSION >= 18 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ private static String getPrimitiveTypeSymbol(ValueLayout targetLayout) { /* Extract the kind from the specified layout with the ATTR_NAME "abi/kind". * e.g. b32[abi/kind=INT] */ TypeKind kind = (TypeKind)targetLayout.attribute(TypeKind.ATTR_NAME) - .orElseThrow(() -> new IllegalArgumentException("The layout's ABI class is empty")); //$NON-NLS-1$ - String typeSymbol = ""; //$NON-NLS-1$ + .orElseThrow(() -> new IllegalArgumentException("The layout's ABI class is empty")); + String typeSymbol = ""; switch (kind) { case CHAR: - typeSymbol = "C"; //$NON-NLS-1$ + typeSymbol = "C"; break; case SHORT: - typeSymbol = "S"; //$NON-NLS-1$ + typeSymbol = "S"; break; case INT: - typeSymbol = "I"; //$NON-NLS-1$ + typeSymbol = "I"; break; case LONG: - case LONG_LONG: // A 8-byte long type on 64bit Windows as specified in the Spec. + case LONG_LONG: /* A 8-byte long type on 64bit Windows as specified in the Spec. */ /* Map the long layout to 'J' so as to keep consistent with the existing VM Spec. */ - typeSymbol = "J"; //$NON-NLS-1$ + typeSymbol = "J"; break; case FLOAT: - typeSymbol = "F"; //$NON-NLS-1$ + typeSymbol = "F"; break; case DOUBLE: - typeSymbol = "D"; //$NON-NLS-1$ + typeSymbol = "D"; break; case POINTER: - typeSymbol = "P"; //$NON-NLS-1$ + typeSymbol = "P"; break; default: - throw new IllegalArgumentException("The layout's ABI Class is undefined: layout = " + targetLayout); //$NON-NLS-1$ + throw new IllegalArgumentException("The layout's ABI Class is undefined: layout = " + targetLayout); } return typeSymbol; } - /*[ENDIF] JAVA_SPEC_VERSION >= 18 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ } diff --git a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/UpcallMHMetaData.java b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/UpcallMHMetaData.java index 0a25cc71a2c..63fb43be94e 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/UpcallMHMetaData.java +++ b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/UpcallMHMetaData.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF JAVA_SPEC_VERSION >= 19]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 20]*/ /******************************************************************************* * Copyright IBM Corp. and others 2022 * @@ -30,12 +30,7 @@ import java.lang.foreign.MemorySegment; import java.lang.foreign.SegmentScope; import jdk.internal.foreign.MemorySessionImpl; -/*[ELSEIF JAVA_SPEC_VERSION == 19]*/ -import java.lang.foreign.Addressable; -import java.lang.foreign.MemoryAddress; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.MemorySession; -/*[ELSE] JAVA_SPEC_VERSION == 19 */ +/*[ELSE] JAVA_SPEC_VERSION >= 20 */ import jdk.incubator.foreign.Addressable; import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.MemorySegment; @@ -46,6 +41,7 @@ * The meta data consists of the callee MH and a cache of 2 elements for MH resolution, * which are used to generate an upcall handler to the requested java method. */ +@SuppressWarnings("nls") final class UpcallMHMetaData { /* The target method handle intended for upcall which is placed on the java stack @@ -69,9 +65,7 @@ final class UpcallMHMetaData { /*[IF JAVA_SPEC_VERSION >= 20]*/ private SegmentScope scope; - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - private MemorySession session; - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ private ResourceScope scope; /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ @@ -87,24 +81,20 @@ final class UpcallMHMetaData { /*[IF JAVA_SPEC_VERSION >= 20]*/ UpcallMHMetaData(MethodHandle targetHandle, int nativeArgCount, SegmentScope scope) - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - UpcallMHMetaData(MethodHandle targetHandle, int nativeArgCount, MemorySession session) - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ UpcallMHMetaData(MethodHandle targetHandle, int nativeArgCount, ResourceScope scope) /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ { calleeMH = targetHandle; calleeType = targetHandle.type(); nativeArgArray = new Object[nativeArgCount]; - /* Only hold the confined session/scope (owned by the current thread) - * or the shared session/scope will be used to construct a MemorySegment - * object for argument in the native dispatcher in upcall. + /* Only hold the confined scope (owned by the current thread) or the shared scope + * will be used to construct a MemorySegment object for argument in the upcall + * dispatcher. */ /*[IF JAVA_SPEC_VERSION >= 20]*/ this.scope = ((scope != null) && (((MemorySessionImpl)scope).ownerThread() != null)) ? scope : Arena.openShared().scope(); - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - this.session = ((session != null) && (session.ownerThread() != null)) ? session : MemorySession.openShared(); - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ this.scope = ((scope != null) && (scope.ownerThread() != null)) ? scope : ResourceScope.newSharedScope(); /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ } @@ -127,7 +117,7 @@ static long getNativeArgRetSegmentOfPtr(MemorySegment argRetSegmentOfPtr) { /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ } - /*[IF JAVA_SPEC_VERSION <= 19]*/ + /*[IF JAVA_SPEC_VERSION == 17]*/ /* Determine whether the memory address of the passed-in/returned pointer is allocated * in the native memory or not and return its native address if valid. * @@ -135,19 +125,13 @@ static long getNativeArgRetSegmentOfPtr(MemorySegment argRetSegmentOfPtr) { * The method is shared in java (downcall) and in native (upcall) via the calling-in from the dispatcher. */ static long getNativeArgRetAddrOfPtr(MemoryAddress argRetAddrOfPtr) { - /*[IF JAVA_SPEC_VERSION > 17]*/ - /* Validate the native address as MemoryAddress.isNative() is removed in JDK18/19. */ - if (argRetAddrOfPtr.toRawLongValue() == 0) - /*[ELSE] JAVA_SPEC_VERSION > 17 */ - if (!argRetAddrOfPtr.isNative()) - /*[ENDIF] JAVA_SPEC_VERSION > 17 */ - { + if (!argRetAddrOfPtr.isNative()) { throw new IllegalArgumentException("A heap address is not allowed: " + argRetAddrOfPtr); } return argRetAddrOfPtr.toRawLongValue(); } - /*[ENDIF] JAVA_SPEC_VERSION <= 19 */ + /*[ENDIF] JAVA_SPEC_VERSION == 17 */ /* Determine whether the passed-in/returned segment is allocated in the native memory or not * and return its native address if valid; otherwise, return the address of an newly allocated @@ -171,9 +155,7 @@ static long getNativeArgRetSegment(MemorySegment argRetSegment) { if (!argRetSegment.isNative()) { /*[IF JAVA_SPEC_VERSION >= 20]*/ SegmentScope scope = SegmentScope.global(); - /*[ELSEIF JAVA_SPEC_VERSION == 19]*/ - MemorySession scope = MemorySession.global(); - /*[ELSE] JAVA_SPEC_VERSION == 19 */ + /*[ELSE] JAVA_SPEC_VERSION >= 20 */ ResourceScope scope = ResourceScope.globalScope(); /*[ENDIF] JAVA_SPEC_VERSION >= 20 */ nativeSegment = MemorySegment.allocateNative(argRetSegment.byteSize(), scope); diff --git a/jcl/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ProgrammableInvoker.java b/jcl/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ProgrammableInvoker.java index f5152fd96a0..84a15661609 100644 --- a/jcl/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ProgrammableInvoker.java +++ b/jcl/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ProgrammableInvoker.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF (JAVA_SPEC_VERSION >= 16) & (JAVA_SPEC_VERSION <= 18)]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 17]*/ /******************************************************************************* * Copyright IBM Corp. and others 2021 * @@ -43,13 +43,7 @@ public class ProgrammableInvoker { * @param funcDesc The function descriptor of the specified native function * @return a method handle bound to the native method */ - /*[IF JAVA_SPEC_VERSION >= 17]*/ public static MethodHandle getBoundMethodHandle(MethodType functionMethodType, FunctionDescriptor funcDesc) { return new InternalDowncallHandler(functionMethodType, funcDesc).getBoundMethodHandle(); } - /*[ELSE] JAVA_SPEC_VERSION >= 17 */ - public static MethodHandle getBoundMethodHandle(Addressable downcallAddr, MethodType functionMethodType, FunctionDescriptor funcDesc) { - return new InternalDowncallHandler(downcallAddr, functionMethodType, funcDesc).getBoundMethodHandle(); - } - /*[ENDIF] JAVA_SPEC_VERSION >= 17 */ } diff --git a/jcl/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ProgrammableUpcallHandler.java b/jcl/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ProgrammableUpcallHandler.java index 9524a3b9728..eb7ff293979 100644 --- a/jcl/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ProgrammableUpcallHandler.java +++ b/jcl/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/ProgrammableUpcallHandler.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF (JAVA_SPEC_VERSION >= 16) & (JAVA_SPEC_VERSION <= 18)]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 17]*/ /******************************************************************************* * Copyright IBM Corp. and others 2022 * @@ -26,9 +26,6 @@ import java.lang.invoke.MethodType; import jdk.incubator.foreign.FunctionDescriptor; -/*[IF JAVA_SPEC_VERSION == 18]*/ -import jdk.incubator.foreign.NativeSymbol; -/*[ENDIF] JAVA_SPEC_VERSION == 18 */ import jdk.incubator.foreign.ResourceScope; import openj9.internal.foreign.abi.InternalUpcallHandler; @@ -36,12 +33,7 @@ * The counterpart in OpenJDK is replaced with this class that wraps up * an upcall handler enabling the native call to the java code at runtime. */ -/*[IF JAVA_SPEC_VERSION >= 18]*/ -/* UpcallHandler has been removed in Java 18 */ -public final class ProgrammableUpcallHandler -/*[ELSE] JAVA_SPEC_VERSION >= 18 */ public final class ProgrammableUpcallHandler implements UpcallHandler -/*[ENDIF] JAVA_SPEC_VERSION >= 18 */ { private final long thunkAddr; @@ -72,16 +64,9 @@ public long entryPoint() { * @param mt The MethodType of the upcall method handle * @param cDesc The FunctionDescriptor of the upcall method handle * @param scope The ResourceScope of the upcall method handle - * @return the native function symbol(JDK18) or the upcall hander(JDK17) in upcall + * @return the upcall hander in upcall */ - /*[IF JAVA_SPEC_VERSION == 18]*/ - public static NativeSymbol makeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) { - ProgrammableUpcallHandler upcallHandler = new ProgrammableUpcallHandler(target, mt, cDesc, scope); - return UpcallStubs.makeUpcall(upcallHandler.entryPoint(), scope); - } - /*[ELSE] JAVA_SPEC_VERSION == 18 */ public static UpcallHandler makeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) { return new ProgrammableUpcallHandler(target, mt, cDesc, scope); } - /*[ENDIF] JAVA_SPEC_VERSION == 18 */ } diff --git a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java index 92fcc3f50c3..1ac20df7966 100644 --- a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java +++ b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF (JAVA_SPEC_VERSION >= 16) & (JAVA_SPEC_VERSION <= 18)]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 17]*/ /*[IF] Final copyright notice is included. */ /******************************************************************************* * Copyright IBM Corp. and others 2022 diff --git a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/InternalUpcallHandler.java b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/InternalUpcallHandler.java index 444fd5e5261..19201252711 100644 --- a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/InternalUpcallHandler.java +++ b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/InternalUpcallHandler.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF (JAVA_SPEC_VERSION >= 16) & (JAVA_SPEC_VERSION <= 18)]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 17]*/ /*[IF] Final copyright notice is included. */ /******************************************************************************* * Copyright IBM Corp. and others 2022 diff --git a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/LayoutStrPreprocessor.java b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/LayoutStrPreprocessor.java index c5804d232c9..846c1354e5f 100644 --- a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/LayoutStrPreprocessor.java +++ b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/LayoutStrPreprocessor.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF (JAVA_SPEC_VERSION >= 16) & (JAVA_SPEC_VERSION <= 18)]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 17]*/ /*[IF] Final copyright notice is included. */ /******************************************************************************* * Copyright IBM Corp. and others 2022 diff --git a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/TypeLayoutCheckHelper.java b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/TypeLayoutCheckHelper.java index 51f1188b332..1057282d240 100644 --- a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/TypeLayoutCheckHelper.java +++ b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/TypeLayoutCheckHelper.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF (JAVA_SPEC_VERSION >= 16) & (JAVA_SPEC_VERSION <= 17)]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 17]*/ /******************************************************************************* * Copyright IBM Corp. and others 2022 * @@ -40,11 +40,12 @@ */ final class TypeLayoutCheckHelper { - /* Verify whether the specified layout and the corresponding type are valid and match each other */ + /* Verify whether the specified layout and the corresponding type are valid and match each other. */ + @SuppressWarnings("nls") static void checkIfValidLayoutAndType(MethodType targetMethodType, MemoryLayout[] argumentLayouts, MemoryLayout returnLayout) { Class retType = targetMethodType.returnType(); if (!validateArgRetTypeClass(retType) && (retType != void.class)) { - throw new IllegalArgumentException("The return type must be primitive/void, MemoryAddress or MemorySegment" + ": retType = " + retType); //$NON-NLS-1$ //$NON-NLS-2$ + throw new IllegalArgumentException("The return type must be primitive/void, MemoryAddress or MemorySegment" + ": retType = " + retType); } validateLayoutAgainstType(returnLayout, targetMethodType.returnType()); @@ -53,20 +54,20 @@ static void checkIfValidLayoutAndType(MethodType targetMethodType, MemoryLayout[ int argTypeCount = argTypes.length; int argLayoutCount = argumentLayouts.length; if (argTypeCount != argLayoutCount) { - throw new IllegalArgumentException("The arity (" + argTypeCount //$NON-NLS-1$ - + ") of the argument types is inconsistent with the arity (" //$NON-NLS-1$ - + argLayoutCount + ") of the argument layouts"); //$NON-NLS-1$ + throw new IllegalArgumentException("The arity (" + argTypeCount + + ") of the argument types is inconsistent with the arity (" + + argLayoutCount + ") of the argument layouts"); } for (int argIndex = 0; argIndex < argLayoutCount; argIndex++) { if (!validateArgRetTypeClass(argTypes[argIndex])) { - throw new IllegalArgumentException("The passed-in argument type at index " + argIndex + " is neither primitive nor MemoryAddress nor MemorySegment"); //$NON-NLS-1$ //$NON-NLS-2$ + throw new IllegalArgumentException("The passed-in argument type at index " + argIndex + " is neither primitive nor MemoryAddress nor MemorySegment"); } validateLayoutAgainstType(argumentLayouts[argIndex], argTypes[argIndex]); } } - /* Verify whether the specified type is primitive, MemoryAddress (for pointer) or MemorySegment (for struct) */ + /* Verify whether the specified type is primitive, MemoryAddress (pointer) or MemorySegment (struct). */ private static boolean validateArgRetTypeClass(Class targetType) { if (!targetType.isPrimitive() && (targetType != MemoryAddress.class) @@ -77,48 +78,50 @@ private static boolean validateArgRetTypeClass(Class targetType) { return true; } - /* Check the validity of the layout against the corresponding type */ + /* Check the validity of the layout against the corresponding type. */ + @SuppressWarnings("nls") private static void validateLayoutAgainstType(MemoryLayout targetLayout, Class targetType) { if (targetLayout != null) { if (!targetLayout.hasSize()) { - throw new IllegalArgumentException("The layout's size is expected: layout = " + targetLayout); //$NON-NLS-1$ + throw new IllegalArgumentException("The layout's size is expected: layout = " + targetLayout); } else if (targetLayout.bitSize() <= 0) { - throw new IllegalArgumentException("The layout's size must be greater than zero: layout = " + targetLayout); //$NON-NLS-1$ + throw new IllegalArgumentException("The layout's size must be greater than zero: layout = " + targetLayout); } } - /* The struct (specified by GroupLayout) for MemorySegment corresponds to GroupLayout in terms of layout */ + /* The struct (specified by GroupLayout) for MemorySegment corresponds to GroupLayout in terms of layout. */ if (targetType == MemorySegment.class) { if (!GroupLayout.class.isInstance(targetLayout)) { - throw new IllegalArgumentException("GroupLayout is expected: layout = " + targetLayout); //$NON-NLS-1$ + throw new IllegalArgumentException("GroupLayout is expected: layout = " + targetLayout); } /* Check the void layout (null for void) and the void type */ } else if (((targetType == void.class) && (targetLayout != null)) || ((targetType != void.class) && (targetLayout == null)) ) { - throw new IllegalArgumentException("Mismatch between the layout and the type: layout = " //$NON-NLS-1$ - + ((targetLayout == null) ? "VOID" : targetLayout) //$NON-NLS-1$ - + ", type = " + targetType); //$NON-NLS-1$ - /* Check the primitive type and MemoryAddress against the ValueLayout */ + throw new IllegalArgumentException("Mismatch between the layout and the type: layout = " + + ((targetLayout == null) ? "VOID" : targetLayout) + + ", type = " + targetType); + /* Check the primitive type and MemoryAddress against the ValueLayout. */ } else if (targetType != void.class) { if (!ValueLayout.class.isInstance(targetLayout)) { - throw new IllegalArgumentException("ValueLayout is expected: layout = " + targetLayout); //$NON-NLS-1$ + throw new IllegalArgumentException("ValueLayout is expected: layout = " + targetLayout); } - /* Check the size and kind of the ValueLayout for the primitive types and MemoryAddress */ + /* Check the size and kind of the ValueLayout for the primitive types and MemoryAddress. */ validateValueLayoutSize(targetLayout, targetType); validateValueLayoutKind(targetLayout, targetType); } } - /* Check the size of the specified primitive layout to determine whether it matches the specified type */ + /* Check the size of the specified primitive layout to determine whether it matches the specified type. */ + @SuppressWarnings("nls") private static void validateValueLayoutSize(MemoryLayout TypeLayout, Class targetType) { int layoutSize = (int)TypeLayout.bitSize(); boolean mismatchedSize = false; switch (layoutSize) { case 8: - /* The 8-bit layout is shared by boolean and byte - * given the boolean size specified in Java18 is 8 bits. + /* The 8-bit layout is shared by boolean and byte given + * the boolean size specified in Java18 is 8 bits. */ if ((targetType != boolean.class) && (targetType != byte.class)) { mismatchedSize = true; @@ -141,8 +144,8 @@ private static void validateValueLayoutSize(MemoryLayout TypeLayout, Class ta } break; case 64: - /* The 64-bit layout size is shared by long, double and MemoryAddress - * given the corresponding pointer size for MemoryAddress is 64 bits in C. + /* The 64-bit layout size is shared by long, double and MemoryAddress given + * the corresponding pointer size for MemoryAddress is 64 bits in C. */ if ((targetType != long.class) && (targetType != double.class) @@ -157,23 +160,24 @@ private static void validateValueLayoutSize(MemoryLayout TypeLayout, Class ta } if (mismatchedSize) { - throw new IllegalArgumentException("Mismatched size between the layout and the type: layout = " //$NON-NLS-1$ - + TypeLayout + ", type = " + targetType.getSimpleName()); //$NON-NLS-1$ + throw new IllegalArgumentException("Mismatched size between the layout and the type: layout = " + + TypeLayout + ", type = " + targetType.getSimpleName()); } } - /* Check the kind (type) of the specified primitive layout to determine whether it matches the specified type */ + /* Check the kind (type) of the specified primitive layout to determine whether it matches the specified type. */ + @SuppressWarnings("nls") private static void validateValueLayoutKind(MemoryLayout targetLayout, Class targetType) { boolean kindAttrFound = false; List layoutAttrList = targetLayout.attributes().toList(); for (String attrStr : layoutAttrList) { - if (attrStr.equalsIgnoreCase("abi/kind")) { //$NON-NLS-1$ + if (attrStr.equalsIgnoreCase("abi/kind")) { kindAttrFound = true; break; } } if (!kindAttrFound) { - throw new IllegalArgumentException("The layout's ABI Class is undefined: layout = " + targetLayout); //$NON-NLS-1$ + throw new IllegalArgumentException("The layout's ABI Class is undefined: layout = " + targetLayout); } /* Extract the kind from the specified layout with the ATTR_NAME "abi/kind". @@ -181,41 +185,41 @@ private static void validateValueLayoutKind(MemoryLayout targetLayout, Class */ boolean mismatchType = false; TypeKind kind = (TypeKind)targetLayout.attribute(TypeKind.ATTR_NAME) - .orElseThrow(() -> new IllegalArgumentException("The layout's ABI class is empty")); //$NON-NLS-1$ + .orElseThrow(() -> new IllegalArgumentException("The layout's ABI class is empty")); switch (kind) { case CHAR: - /* the CHAR layout (8bits) in Java maps to bool or byte in C */ + /* The CHAR layout (8 bits) in Java maps to bool or byte in C. */ break; case SHORT: - /* the SHORT layout (16bits) in Java maps to char or short in C */ + /* The SHORT layout (16 bits) in Java maps to char or short in C. */ break; case INT: - /* the INT layout (32bits) in Java maps to int in C */ + /* The INT layout (32 bits) in Java maps to int in C. */ if (targetType != int.class) { mismatchType = true; } break; case LONG: case LONG_LONG: - /* the LONG/LONG_LONG layout (64bits) in Java only matches long in C */ + /* The LONG/LONG_LONG layout (64 bits) in Java only matches long in C. */ if (targetType != long.class) { mismatchType = true; } break; case FLOAT: - /* the FLOAT layout (32bits) in Java only matches float in C */ + /* The FLOAT layout (32 bits) in Java only matches float in C. */ if (targetType != float.class) { mismatchType = true; } break; case DOUBLE: - /* the DOUBLE layout (64bits) in Java only matches double in C */ + /* The DOUBLE layout (64 bits) in Java only matches double in C. */ if (targetType != double.class) { mismatchType = true; } break; case POINTER: - /* the POINTER layout (64bits) in Java only matches MemoryAddress */ + /* The POINTER layout (64 bits) in Java only matches MemoryAddress. */ if (targetType != MemoryAddress.class) { mismatchType = true; } @@ -226,7 +230,7 @@ private static void validateValueLayoutKind(MemoryLayout targetLayout, Class } if (mismatchType) { - throw new IllegalArgumentException("Mismatch between the layout and the type: layout = " + targetLayout + ", type = " + targetType); //$NON-NLS-1$ //$NON-NLS-2$ + throw new IllegalArgumentException("Mismatch between the layout and the type: layout = " + targetLayout + ", type = " + targetType); } } } diff --git a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/UpcallMHMetaData.java b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/UpcallMHMetaData.java index 4d4838161cc..3aa6c6451bd 100644 --- a/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/UpcallMHMetaData.java +++ b/jcl/src/jdk.incubator.foreign/share/classes/openj9/internal/foreign/abi/UpcallMHMetaData.java @@ -1,4 +1,4 @@ -/*[INCLUDE-IF (JAVA_SPEC_VERSION >= 16) & (JAVA_SPEC_VERSION <= 18)]*/ +/*[INCLUDE-IF JAVA_SPEC_VERSION == 17]*/ /*[IF] Final copyright notice is included. */ /******************************************************************************* * Copyright IBM Corp. and others 2022 diff --git a/runtime/j9vm/exports.cmake b/runtime/j9vm/exports.cmake index 7c6d7168025..672053ddbbc 100644 --- a/runtime/j9vm/exports.cmake +++ b/runtime/j9vm/exports.cmake @@ -432,6 +432,7 @@ if(JAVA_SPEC_VERSION LESS 21) ) else() jvm_add_exports(jvm + JVM_IsForeignLinkerSupported JVM_VirtualThreadMount JVM_VirtualThreadUnmount ) diff --git a/runtime/j9vm/j9vmnatives.xml b/runtime/j9vm/j9vmnatives.xml index 57d244efea8..9d70c9d7c15 100644 --- a/runtime/j9vm/j9vmnatives.xml +++ b/runtime/j9vm/j9vmnatives.xml @@ -439,6 +439,7 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-excepti + diff --git a/runtime/j9vm/javanextvmi.cpp b/runtime/j9vm/javanextvmi.cpp index 7997e818dc3..c7454b36dce 100644 --- a/runtime/j9vm/javanextvmi.cpp +++ b/runtime/j9vm/javanextvmi.cpp @@ -506,6 +506,12 @@ JVM_VirtualThreadUnmount(JNIEnv* env, jobject vthread, jboolean hide, jboolean l JVM_VirtualThreadUnmountEnd(env, vthread, lastUnmount); } } + +JNIEXPORT jboolean JNICALL +JVM_IsForeignLinkerSupported() +{ + return JNI_TRUE; +} #endif /* JAVA_SPEC_VERSION >= 21 */ #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) diff --git a/runtime/oti/vmconstantpool.xml b/runtime/oti/vmconstantpool.xml index a042da92770..9b1a196cb88 100644 --- a/runtime/oti/vmconstantpool.xml +++ b/runtime/oti/vmconstantpool.xml @@ -154,19 +154,18 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-excepti - - - - - - - - - - - - - + + + + + + + + + + + + - - + + -