Skip to content

Commit fee3d99

Browse files
committed
Keep NFI source objects if expecte to be used repeatedly
1 parent c5c5da6 commit fee3d99

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
157157
import com.oracle.graal.python.runtime.PythonContext;
158158
import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
159+
import com.oracle.graal.python.runtime.PythonOptions;
159160
import com.oracle.graal.python.runtime.exception.PException;
160161
import com.oracle.graal.python.runtime.exception.PythonErrorType;
161162
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
@@ -1598,6 +1599,10 @@ abstract static class MultiPhaseExtensionModuleInitNode extends Node {
15981599
@GenerateUncached
15991600
@GenerateInline(false) // footprint reduction 68 -> 49
16001601
public abstract static class CreateModuleNode extends MultiPhaseExtensionModuleInitNode {
1602+
private static final String NFI_CREATE_NAME = "create";
1603+
private static final String NFI_CREATE_SRC = "(POINTER,POINTER):POINTER";
1604+
private static final Source NFI_LIBFFI_CREATE = Source.newBuilder(J_NFI_LANGUAGE, NFI_CREATE_SRC, NFI_CREATE_NAME).build();
1605+
private static final Source NFI_PANAMA_CREATE = Source.newBuilder(J_NFI_LANGUAGE, "with panama " + NFI_CREATE_SRC, NFI_CREATE_NAME).build();
16011606

16021607
public abstract Object execute(CApiContext capiContext, ModuleSpec moduleSpec, Object moduleDef, Object library);
16031608

@@ -1672,13 +1677,15 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m
16721677
Object[] cArguments = new Object[]{PythonToNativeNode.executeUncached(moduleSpec.originalModuleSpec), moduleDef};
16731678
try {
16741679
Object result;
1680+
PythonContext context = capiContext.getContext();
16751681
if (!interopLib.isExecutable(createFunction)) {
1676-
Object signature = capiContext.getContext().getEnv().parseInternal(Source.newBuilder(J_NFI_LANGUAGE, "(POINTER,POINTER):POINTER", "exec").build()).call();
1682+
boolean panama = context.getOption(PythonOptions.UsePanama);
1683+
Object signature = context.getEnv().parseInternal(panama ? NFI_PANAMA_CREATE : NFI_LIBFFI_CREATE).call();
16771684
result = interopLib.execute(SignatureLibrary.getUncached().bind(signature, createFunction), cArguments);
16781685
} else {
16791686
result = interopLib.execute(createFunction, cArguments);
16801687
}
1681-
CheckFunctionResultNode.checkFunctionResult(inliningTarget, mName, interopLib.isNull(result), true, PythonLanguage.get(raiseNode), capiContext.getContext(), errOccurredProfile,
1688+
CheckFunctionResultNode.checkFunctionResult(inliningTarget, mName, interopLib.isNull(result), true, PythonLanguage.get(raiseNode), context, errOccurredProfile,
16821689
ErrorMessages.CREATION_FAILD_WITHOUT_EXCEPTION, ErrorMessages.CREATION_RAISED_EXCEPTION);
16831690
module = toJavaNode.execute(result);
16841691
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
@@ -1733,6 +1740,9 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m
17331740
@GenerateUncached
17341741
@GenerateInline(false) // footprint reduction 60 -> 42
17351742
public abstract static class ExecModuleNode extends MultiPhaseExtensionModuleInitNode {
1743+
private static final String NFI_EXEC_SRC = "(POINTER):SINT32";
1744+
private static final Source NFI_LIBFFI_EXEC = Source.newBuilder(J_NFI_LANGUAGE, NFI_EXEC_SRC, "exec").build();
1745+
private static final Source NFI_PANAMA_EXEC = Source.newBuilder(J_NFI_LANGUAGE, "with panama " + NFI_EXEC_SRC, "exec").build();
17361746

17371747
public abstract int execute(CApiContext capiContext, PythonModule module, Object moduleDef);
17381748

@@ -1781,8 +1791,10 @@ static int doGeneric(CApiContext capiContext, PythonModule module, Object module
17811791
break;
17821792
case SLOT_PY_MOD_EXEC:
17831793
Object execFunction = readPointerNode.readStructArrayElement(slotDefinitions, i, PyModuleDef_Slot__value);
1794+
PythonContext context = capiContext.getContext();
17841795
if (!U.isExecutable(execFunction)) {
1785-
Object signature = capiContext.getContext().getEnv().parseInternal(Source.newBuilder(J_NFI_LANGUAGE, "(POINTER):SINT32", "exec").build()).call();
1796+
boolean panama = context.getOption(PythonOptions.UsePanama);
1797+
Object signature = context.getEnv().parseInternal(panama ? NFI_PANAMA_EXEC : NFI_LIBFFI_EXEC).call();
17861798
execFunction = SignatureLibrary.getUncached().bind(signature, execFunction);
17871799
}
17881800
Object result = interopLib.execute(execFunction, PythonToNativeNode.executeUncached(module));
@@ -1794,7 +1806,7 @@ static int doGeneric(CApiContext capiContext, PythonModule module, Object module
17941806
* and won't ignore this if no error is set. This is then the same
17951807
* behaviour if we would have a pointer return type and got 'NULL'.
17961808
*/
1797-
CheckFunctionResultNode.checkFunctionResult(inliningTarget, mName, iResult != 0, true, PythonLanguage.get(raiseNode), capiContext.getContext(),
1809+
CheckFunctionResultNode.checkFunctionResult(inliningTarget, mName, iResult != 0, true, PythonLanguage.get(raiseNode), context,
17981810
InlinedConditionProfile.getUncached(), ErrorMessages.EXECUTION_FAILED_WITHOUT_EXCEPTION, ErrorMessages.EXECUTION_RAISED_EXCEPTION);
17991811
break;
18001812
default:

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import java.io.IOException;
5555
import java.nio.file.LinkOption;
5656

57+
import org.graalvm.collections.Pair;
5758
import org.graalvm.shadowed.com.ibm.icu.impl.Punycode;
5859
import org.graalvm.shadowed.com.ibm.icu.text.StringPrepParseException;
5960

@@ -424,7 +425,9 @@ public static Object ensureExecutable(final Object callable, NativeCExtSymbol si
424425
boolean panama = PythonOptions.UsePanama.getValue(env.getOptions());
425426

426427
assert sig.getSignature() != null && !sig.getSignature().isEmpty();
427-
Object nfiSignature = env.parseInternal(Source.newBuilder("nfi", (panama ? "with panama " : "") + sig.getSignature(), sig.getName()).build()).call();
428+
String src = (panama ? "with panama " : "") + sig.getSignature();
429+
Source nfiSource = pythonContext.getLanguage().getOrCreateSource(CExtContext::buildNFISource, Pair.create(src, sig.getName()));
430+
Object nfiSignature = env.parseInternal(nfiSource).call();
428431

429432
/*
430433
* Since we mix native and LLVM execution, it happens that 'callable' is an LLVM pointer
@@ -448,4 +451,9 @@ public static Object ensureExecutable(final Object callable, NativeCExtSymbol si
448451
// nothing to do
449452
return callable;
450453
}
454+
455+
private static Source buildNFISource(Object key) {
456+
Pair<?, ?> srcAndName = (Pair<?, ?>) key;
457+
return Source.newBuilder(J_NFI_LANGUAGE, (String) srcAndName.getLeft(), (String) srcAndName.getRight()).build();
458+
}
451459
}

0 commit comments

Comments
 (0)