Skip to content

Commit 70fd5a7

Browse files
committed
Unify native downcall handle creation
1 parent ca03c39 commit 70fd5a7

7 files changed

Lines changed: 71 additions & 117 deletions

File tree

‎graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java‎

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,8 +1411,8 @@ private void generateExternalFunctionInvoker(List<CApiExternalFunctionSignatureD
14111411
lines.add("package " + EXFUNC_INVOKER_PACKAGE + ";");
14121412
lines.add("");
14131413
lines.add("import java.lang.invoke.MethodHandle;");
1414-
lines.add("import java.lang.invoke.MethodType;");
14151414
lines.add("");
1415+
lines.add("import " + NativeSimpleType.class.getCanonicalName() + ";");
14161416
lines.add("import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.EnsurePythonObjectNode;");
14171417
lines.add("import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;");
14181418
lines.add("import com.oracle.graal.python.builtins.objects.function.PArguments;");
@@ -1631,6 +1631,11 @@ private void generateNativeAccessSupport(Element[] origins) throws IOException {
16311631
lines.add(" return CAPTURE_STATE_LAYOUT.varHandle(MemoryLayout.PathElement.groupElement(stateName));");
16321632
lines.add(" }");
16331633
lines.add("");
1634+
lines.add(" private static MethodType createMethodType(boolean captureCallState, FunctionDescriptor functionDescriptor) {");
1635+
lines.add(" MethodType methodType = functionDescriptor.toMethodType().insertParameterTypes(0, long.class);");
1636+
lines.add(" return captureCallState ? methodType.insertParameterTypes(1, MemorySegment.class) : methodType;");
1637+
lines.add(" }");
1638+
lines.add("");
16341639
lines.add(" @Override");
16351640
lines.add(" protected Object createArenaImpl() {");
16361641
lines.add(" return Arena.ofShared();");
@@ -1655,8 +1660,9 @@ private void generateNativeAccessSupport(Element[] origins) throws IOException {
16551660
lines.add("");
16561661
lines.add(" @Override");
16571662
lines.add(" @SuppressWarnings(\"restricted\")");
1658-
lines.add(" protected MethodHandle createDowncallHandleImpl(MethodType methodType, boolean critical, boolean captureCallState) {");
1659-
lines.add(" FunctionDescriptor functionDescriptor = createFunctionDescriptor(methodType, captureCallState ? 2 : 1);");
1663+
lines.add(" protected MethodHandle createDowncallHandleImpl(boolean critical, boolean captureCallState, NativeSimpleType resType, NativeSimpleType[] argTypes) {");
1664+
lines.add(" FunctionDescriptor functionDescriptor = createFunctionDescriptor(resType, argTypes);");
1665+
lines.add(" MethodType methodType = createMethodType(captureCallState, functionDescriptor);");
16601666
lines.add(" List<Linker.Option> options = new ArrayList<>();");
16611667
lines.add(" if (critical) {");
16621668
lines.add(" options.add(Linker.Option.critical(false));");
@@ -1709,33 +1715,6 @@ private void generateNativeAccessSupport(Element[] origins) throws IOException {
17091715
lines.add(" return resType == NativeSimpleType.VOID ? FunctionDescriptor.ofVoid(argLayouts) : FunctionDescriptor.of(asLayout(resType), argLayouts);");
17101716
lines.add(" }");
17111717
lines.add("");
1712-
lines.add(" private static FunctionDescriptor createFunctionDescriptor(MethodType methodType, int firstNativeArg) {");
1713-
lines.add(" Class<?>[] parameterTypes = methodType.parameterArray();");
1714-
lines.add(" MemoryLayout[] argLayouts = new MemoryLayout[parameterTypes.length - firstNativeArg];");
1715-
lines.add(" for (int i = firstNativeArg; i < parameterTypes.length; i++) {");
1716-
lines.add(" argLayouts[i - firstNativeArg] = asLayout(parameterTypes[i]);");
1717-
lines.add(" }");
1718-
lines.add(" Class<?> returnType = methodType.returnType();");
1719-
lines.add(" return returnType == void.class ? FunctionDescriptor.ofVoid(argLayouts) : FunctionDescriptor.of(asLayout(returnType), argLayouts);");
1720-
lines.add(" }");
1721-
lines.add("");
1722-
lines.add(" private static MemoryLayout asLayout(Class<?> type) {");
1723-
lines.add(" if (type == byte.class) {");
1724-
lines.add(" return ValueLayout.JAVA_BYTE;");
1725-
lines.add(" } else if (type == short.class) {");
1726-
lines.add(" return ValueLayout.JAVA_SHORT;");
1727-
lines.add(" } else if (type == int.class) {");
1728-
lines.add(" return ValueLayout.JAVA_INT;");
1729-
lines.add(" } else if (type == long.class) {");
1730-
lines.add(" return ValueLayout.JAVA_LONG;");
1731-
lines.add(" } else if (type == float.class) {");
1732-
lines.add(" return ValueLayout.JAVA_FLOAT;");
1733-
lines.add(" } else if (type == double.class) {");
1734-
lines.add(" return ValueLayout.JAVA_DOUBLE;");
1735-
lines.add(" }");
1736-
lines.add(" throw shouldNotReachHere(\"Unsupported layout carrier: \" + type);");
1737-
lines.add(" }");
1738-
lines.add("");
17391718
lines.add(" private static MemoryLayout asLayout(NativeSimpleType type) {");
17401719
lines.add(" return switch (type) {");
17411720
lines.add(" case VOID -> throw shouldNotReachHere(\"VOID has no layout\");");
@@ -1765,7 +1744,6 @@ private void generateDummyNativeAccessSupport(Element[] origins) throws IOExcept
17651744
lines.add("package " + NATIVE_ACCESS_PACKAGE + ";");
17661745
lines.add("");
17671746
lines.add("import java.lang.invoke.MethodHandle;");
1768-
lines.add("import java.lang.invoke.MethodType;");
17691747
lines.add("");
17701748
lines.add("import " + NativeSimpleType.class.getCanonicalName() + ";");
17711749
lines.add("");
@@ -1791,17 +1769,12 @@ private void generateDummyNativeAccessSupport(Element[] origins) throws IOExcept
17911769
lines.add(" }");
17921770
lines.add("");
17931771
lines.add(" @Override");
1794-
lines.add(" protected MethodHandle createDowncallHandleImpl(MethodType methodType, boolean critical, boolean captureCallState) {");
1795-
lines.add(" throw unsupported();");
1796-
lines.add(" }");
1797-
lines.add("");
1798-
lines.add(" @Override");
1799-
lines.add(" protected Object createCapturedCallStateImpl() {");
1772+
lines.add(" protected MethodHandle createDowncallHandleImpl(boolean critical, boolean captureCallState, NativeSimpleType resType, NativeSimpleType[] argTypes) {");
18001773
lines.add(" throw unsupported();");
18011774
lines.add(" }");
18021775
lines.add("");
18031776
lines.add(" @Override");
1804-
lines.add(" protected Object getCapturedCallStateSegmentImpl(Object state) {");
1777+
lines.add(" protected Object createCapturedCallStateImpl(Object arena) {");
18051778
lines.add(" throw unsupported();");
18061779
lines.add(" }");
18071780
lines.add("");

‎graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/GenerateNativeDowncallsProcessor.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,10 @@ private void generateInvoker(TypeElement invokerElement) throws IOException, Pro
143143
lines.add("");
144144
lines.add("import java.lang.foreign.MemorySegment;");
145145
lines.add("import java.lang.invoke.MethodHandle;");
146-
lines.add("import java.lang.invoke.MethodType;");
147146
lines.add("import java.util.concurrent.atomic.AtomicLongArray;");
148147
lines.add("import java.util.List;");
149148
lines.add("");
149+
lines.add("import com.oracle.graal.python.annotations.NativeSimpleType;");
150150
lines.add("import com.oracle.graal.python.runtime.nativeaccess.NativeAccessSupport;");
151151
lines.add("import com.oracle.graal.python.runtime.nativeaccess.NativeLibrary;");
152152
lines.add("import com.oracle.truffle.api.CompilerDirectives;");

‎graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/NativeDowncallMethodHandleGenerator.java‎

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
*/
4141
package com.oracle.graal.python.processor;
4242

43-
import java.util.ArrayList;
4443
import java.util.List;
4544

4645
import com.oracle.graal.python.annotations.NativeSimpleType;
@@ -60,51 +59,50 @@ static String methodHandleVarName(String signatureName) {
6059
return "NATIVE_METHOD_HANDLE_" + signatureName;
6160
}
6261

63-
static String toClassLiteral(String javaType) {
62+
private static String toNativeSimpleTypeLiteral(String javaType) {
6463
return switch (javaType) {
65-
case "void" -> "void.class";
66-
case "byte" -> "byte.class";
67-
case "short" -> "short.class";
68-
case "int" -> "int.class";
69-
case "long" -> "long.class";
70-
case "float" -> "float.class";
71-
case "double" -> "double.class";
64+
case "void" -> "NativeSimpleType.VOID";
65+
case "byte" -> "NativeSimpleType.SINT8";
66+
case "short" -> "NativeSimpleType.SINT16";
67+
case "int" -> "NativeSimpleType.SINT32";
68+
case "long" -> "NativeSimpleType.SINT64";
69+
case "float" -> "NativeSimpleType.FLOAT";
70+
case "double" -> "NativeSimpleType.DOUBLE";
7271
default -> throw new IllegalArgumentException("Unexpected Java type: " + javaType);
7372
};
7473
}
7574

76-
static String toClassLiteral(NativeSimpleType nativeType) {
75+
private static String toNativeSimpleTypeLiteral(NativeSimpleType nativeType) {
7776
return switch (nativeType) {
78-
case VOID -> "void.class";
79-
case SINT8 -> "byte.class";
80-
case SINT16 -> "short.class";
81-
case SINT32 -> "int.class";
82-
case SINT64, POINTER -> "long.class";
83-
case FLOAT -> "float.class";
84-
case DOUBLE -> "double.class";
77+
case VOID -> "NativeSimpleType.VOID";
78+
case SINT8 -> "NativeSimpleType.SINT8";
79+
case SINT16 -> "NativeSimpleType.SINT16";
80+
case SINT32 -> "NativeSimpleType.SINT32";
81+
case SINT64 -> "NativeSimpleType.SINT64";
82+
case FLOAT -> "NativeSimpleType.FLOAT";
83+
case DOUBLE -> "NativeSimpleType.DOUBLE";
84+
case POINTER -> "NativeSimpleType.POINTER";
8585
};
8686
}
8787

8888
static void emitMethodHandleField(List<String> lines, String fieldName, String returnType, List<String> argTypes) {
89-
List<String> methodTypeArgs = new ArrayList<>();
90-
methodTypeArgs.add("long.class");
89+
StringBuilder createHandle = new StringBuilder("NativeAccessSupport.createDowncallHandle(false, false, ");
90+
createHandle.append(toNativeSimpleTypeLiteral(returnType));
9191
for (String argType : argTypes) {
92-
methodTypeArgs.add(toClassLiteral(argType));
92+
createHandle.append(", ").append(toNativeSimpleTypeLiteral(argType));
9393
}
94-
lines.add(" private static final MethodHandle " + fieldName + " = NativeAccessSupport.createDowncallHandle(" +
95-
"MethodType.methodType(" + toClassLiteral(returnType) + ", " + String.join(", ", methodTypeArgs) + "), false);");
94+
createHandle.append(")");
95+
lines.add(" private static final MethodHandle " + fieldName + " = " + createHandle + ";");
9696
}
9797

9898
static void emitMethodHandleField(List<String> lines, String fieldName, NativeSimpleType returnType, List<NativeSimpleType> argTypes, boolean critical, boolean captureCallState) {
99-
List<String> methodTypeArgs = new ArrayList<>();
100-
methodTypeArgs.add("long.class");
101-
if (captureCallState) {
102-
methodTypeArgs.add("MemorySegment.class");
103-
}
99+
StringBuilder createHandle = new StringBuilder("NativeAccessSupport.createDowncallHandle(");
100+
createHandle.append(critical).append(", ").append(captureCallState).append(", ");
101+
createHandle.append(toNativeSimpleTypeLiteral(returnType));
104102
for (NativeSimpleType argType : argTypes) {
105-
methodTypeArgs.add(toClassLiteral(argType));
103+
createHandle.append(", ").append(toNativeSimpleTypeLiteral(argType));
106104
}
107-
lines.add(" private static final MethodHandle " + fieldName + " = NativeAccessSupport.createDowncallHandle(" +
108-
"MethodType.methodType(" + toClassLiteral(returnType) + ", " + String.join(", ", methodTypeArgs) + "), " + critical + ", " + captureCallState + ");");
105+
createHandle.append(")");
106+
lines.add(" private static final MethodHandle " + fieldName + " = " + createHandle + ";");
109107
}
110108
}

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowReleaseCallback.java‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@
4040
*/
4141
package com.oracle.graal.python.nodes.arrow;
4242

43+
import static com.oracle.graal.python.annotations.NativeSimpleType.POINTER;
44+
import static com.oracle.graal.python.annotations.NativeSimpleType.VOID;
45+
4346
import java.lang.invoke.MethodHandle;
44-
import java.lang.invoke.MethodType;
4547

4648
import com.oracle.graal.python.runtime.nativeaccess.NativeAccessSupport;
4749
import com.oracle.truffle.api.CompilerDirectives;
4850

4951
public final class ArrowReleaseCallback {
50-
private static final MethodHandle HANDLE = NativeAccessSupport.createDowncallHandle(
51-
MethodType.methodType(void.class, long.class, long.class), false);
52+
private static final MethodHandle HANDLE = NativeAccessSupport.createDowncallHandle(false, false, VOID, POINTER);
5253

5354
private ArrowReleaseCallback() {
5455
}

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/nativeaccess/NativeAccessSupport.java‎

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,8 @@ static long lookupDefault(String name) {
104104
return INSTANCE.lookupDefaultImpl(name);
105105
}
106106

107-
static MethodHandle createDowncallHandle(NativeSimpleType resType, NativeSimpleType... argTypes) {
108-
return INSTANCE.createTypedDowncallHandle(resType, argTypes);
109-
}
110-
111-
public static MethodHandle createDowncallHandle(MethodType methodType, boolean critical) {
112-
return INSTANCE.createDowncallHandleImpl(methodType, critical, false);
113-
}
114-
115-
public static MethodHandle createDowncallHandle(MethodType methodType, boolean critical, boolean captureCallState) {
116-
return INSTANCE.createDowncallHandleImpl(methodType, critical, captureCallState);
107+
public static MethodHandle createDowncallHandle(boolean critical, boolean captureCallState, NativeSimpleType resType, NativeSimpleType... argTypes) {
108+
return INSTANCE.createDowncallHandleImpl(critical, captureCallState, resType, argTypes);
117109
}
118110

119111
public static Object createCapturedCallState(Object arena) {
@@ -130,10 +122,6 @@ public static int readCapturedGetLastError(Object capturedCallStatePtr) {
130122
return INSTANCE.readCapturedGetLastErrorImpl(capturedCallStatePtr);
131123
}
132124

133-
static MethodHandle createCapturedDowncallHandle(NativeSimpleType resType, NativeSimpleType... argTypes) {
134-
return INSTANCE.createTypedCapturedDowncallHandle(resType, argTypes);
135-
}
136-
137125
public static boolean isAvailable() {
138126
return INSTANCE.isAvailableImpl();
139127
}
@@ -146,25 +134,6 @@ public static boolean isCurrentThreadVirtual() {
146134
return INSTANCE.isCurrentThreadVirtualImpl();
147135
}
148136

149-
private MethodHandle createTypedDowncallHandle(NativeSimpleType resType, NativeSimpleType... argTypes) {
150-
Class<?>[] parameterTypes = new Class<?>[argTypes.length + 1];
151-
parameterTypes[0] = long.class;
152-
for (int i = 0; i < argTypes.length; i++) {
153-
parameterTypes[i + 1] = asJavaType(argTypes[i]);
154-
}
155-
return createDowncallHandleImpl(MethodType.methodType(asJavaType(resType), parameterTypes), false, false);
156-
}
157-
158-
private MethodHandle createTypedCapturedDowncallHandle(NativeSimpleType resType, NativeSimpleType... argTypes) {
159-
Class<?>[] parameterTypes = new Class<?>[argTypes.length + 2];
160-
parameterTypes[0] = long.class;
161-
parameterTypes[1] = long.class;
162-
for (int i = 0; i < argTypes.length; i++) {
163-
parameterTypes[i + 2] = asJavaType(argTypes[i]);
164-
}
165-
return createDowncallHandleImpl(MethodType.methodType(asJavaType(resType), parameterTypes), false, true);
166-
}
167-
168137
protected abstract Object createArenaImpl();
169138

170139
protected abstract void closeArenaImpl(Object arena);
@@ -173,7 +142,7 @@ private MethodHandle createTypedCapturedDowncallHandle(NativeSimpleType resType,
173142

174143
protected abstract long lookupDefaultImpl(String name);
175144

176-
protected abstract MethodHandle createDowncallHandleImpl(MethodType methodType, boolean critical, boolean captureCallState);
145+
protected abstract MethodHandle createDowncallHandleImpl(boolean critical, boolean captureCallState, NativeSimpleType resType, NativeSimpleType[] argTypes);
177146

178147
protected abstract Object createCapturedCallStateImpl(Object arena);
179148

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/nativeaccess/NativeAccessSupportJdk21.java‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,21 @@ protected long lookupDefaultImpl(String name) {
6666
}
6767

6868
@Override
69-
protected MethodHandle createDowncallHandleImpl(MethodType methodType, boolean critical, boolean captureCallState) {
70-
return unsupportedDowncallHandle(methodType);
69+
protected MethodHandle createDowncallHandleImpl(boolean critical, boolean captureCallState, NativeSimpleType resType, NativeSimpleType[] argTypes) {
70+
return unsupportedDowncallHandle(createMethodType(captureCallState, resType, argTypes));
71+
}
72+
73+
private static MethodType createMethodType(boolean captureCallState, NativeSimpleType resType, NativeSimpleType... argTypes) {
74+
int injectedArgumentCount = captureCallState ? 2 : 1;
75+
Class<?>[] parameterTypes = new Class<?>[argTypes.length + injectedArgumentCount];
76+
parameterTypes[0] = long.class;
77+
if (captureCallState) {
78+
parameterTypes[1] = Object.class;
79+
}
80+
for (int i = 0; i < argTypes.length; i++) {
81+
parameterTypes[i + injectedArgumentCount] = asJavaType(argTypes[i]);
82+
}
83+
return MethodType.methodType(asJavaType(resType), parameterTypes);
7184
}
7285

7386
@Override

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/nativeaccess/NativeContext.java‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public NativeLibrary loadLibrary(String name, int flags) throws NativeLibraryLoa
112112
if (isWindows()) {
113113
int callFlags = sanitizeWindowsLoadLibraryFlags(flags) | WINDOWS_DEFAULT_LOAD_LIBRARY_FLAGS;
114114
Object callStateBuffer = callState.get();
115-
lib = (long) LOAD_LIBRARY_EX_CAPTURED.invokeExact(loadLibraryExPtr, callStateBuffer, nativeName, 0L, callFlags);
115+
lib = (long) LOAD_LIBRARY_EX_CAPTURED.invoke(loadLibraryExPtr, callStateBuffer, nativeName, 0L, callFlags);
116116
} else {
117117
int callFlags = flags;
118118
if ((callFlags & (RTLD_LAZY | RTLD_NOW)) == 0) {
@@ -169,14 +169,14 @@ private static boolean isWindows() {
169169
private static final long RTLD_DEFAULT_LINUX = 0L;
170170
private static final long RTLD_DEFAULT_DARWIN = -2L;
171171

172-
private static final MethodHandle DLOPEN = NativeAccessSupport.createDowncallHandle(SINT64, POINTER, SINT32);
173-
private static final MethodHandle DLCLOSE = NativeAccessSupport.createDowncallHandle(SINT32, SINT64);
174-
private static final MethodHandle DLSYM = NativeAccessSupport.createDowncallHandle(SINT64, SINT64, POINTER);
175-
private static final MethodHandle FREE_LIBRARY = NativeAccessSupport.createDowncallHandle(SINT32, SINT64);
176-
private static final MethodHandle GET_PROC_ADDRESS = NativeAccessSupport.createDowncallHandle(SINT64, SINT64, POINTER);
177-
private static final MethodHandle FORMAT_MESSAGE = NativeAccessSupport.createDowncallHandle(SINT32, SINT32, POINTER, SINT32, SINT32, POINTER, SINT32, POINTER);
178-
private static final MethodHandle DLERROR = NativeAccessSupport.createDowncallHandle(SINT64);
179-
private static final MethodHandle LOAD_LIBRARY_EX_CAPTURED = isWindows() ? NativeAccessSupport.createCapturedDowncallHandle(SINT64, POINTER, POINTER, SINT32) : null;
172+
private static final MethodHandle DLOPEN = NativeAccessSupport.createDowncallHandle(false, false, SINT64, POINTER, SINT32);
173+
private static final MethodHandle DLCLOSE = NativeAccessSupport.createDowncallHandle(false, false, SINT32, SINT64);
174+
private static final MethodHandle DLSYM = NativeAccessSupport.createDowncallHandle(false, false, SINT64, SINT64, POINTER);
175+
private static final MethodHandle FREE_LIBRARY = NativeAccessSupport.createDowncallHandle(false, false, SINT32, SINT64);
176+
private static final MethodHandle GET_PROC_ADDRESS = NativeAccessSupport.createDowncallHandle(false, false, SINT64, SINT64, POINTER);
177+
private static final MethodHandle FORMAT_MESSAGE = NativeAccessSupport.createDowncallHandle(false, false, SINT32, SINT32, POINTER, SINT32, SINT32, POINTER, SINT32, POINTER);
178+
private static final MethodHandle DLERROR = NativeAccessSupport.createDowncallHandle(false, false, SINT64);
179+
private static final MethodHandle LOAD_LIBRARY_EX_CAPTURED = isWindows() ? NativeAccessSupport.createDowncallHandle(false, true, SINT64, POINTER, POINTER, SINT32) : null;
180180

181181
private static long dlopenPtr;
182182
private static long dlclosePtr;

0 commit comments

Comments
 (0)