Skip to content

Commit 83226de

Browse files
committed
[GR-46044] Optimize CreateArgumentsNode and make relevant helper nodes inlinable.
PullRequest: graalpython/2763
2 parents b0c6b0f + abb384e commit 83226de

32 files changed

+499
-351
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2469,7 +2469,7 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
24692469
Object winner = calculateMetaclass(frame, inliningTarget, metaclass, bases, getClassNode, isTypeNode, lookupMroEntriesNode, getObjectArrayNode);
24702470
if (winner != metaclass) {
24712471
Object newFunc = getNewFuncNode.execute(winner);
2472-
if (newFunc instanceof PBuiltinMethod && (((PBuiltinMethod) newFunc).getFunction().getFunctionRootNode().getCallTarget() == getRootNode().getCallTarget())) {
2472+
if (newFunc instanceof PBuiltinMethod && (((PBuiltinMethod) newFunc).getBuiltinFunction().getFunctionRootNode().getCallTarget() == getRootNode().getCallTarget())) {
24732473
metaclass = winner;
24742474
// the new metaclass has the same __new__ function as we are in, continue
24752475
} else {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextAbstractBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ static int set(PBuiltinFunction obj, TruffleString value,
918918
@Specialization
919919
static int set(PBuiltinMethod obj, TruffleString value,
920920
@Shared("write") @Cached WriteAttributeToDynamicObjectNode write) {
921-
set(obj.getFunction(), value, write);
921+
set(obj.getBuiltinFunction(), value, write);
922922
return 1;
923923
}
924924

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCEvalBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ static Object doGeneric(PCode code, Object globals, Object locals,
173173
// prepare Python frame arguments
174174
Object[] userArguments = unwrapArray(argumentArrayPtr, ptrLib, elementToJavaNode);
175175
Signature signature = getSignatureNode.execute(inliningTarget, code);
176-
Object[] pArguments = createAndCheckArgumentsNode.execute(code, userArguments, keywords, signature, null, null, defaults, kwdefaults, false);
176+
Object[] pArguments = createAndCheckArgumentsNode.execute(inliningTarget, code, userArguments, keywords, signature, null, null, defaults, kwdefaults, false);
177177

178178
// set custom locals
179179
if (!(locals instanceof PNone)) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ static int get(Object object) {
646646
if (object instanceof PBuiltinFunction) {
647647
return ((PBuiltinFunction) object).getFlags();
648648
} else if (object instanceof PBuiltinMethod) {
649-
return ((PBuiltinMethod) object).getFunction().getFlags();
649+
return ((PBuiltinMethod) object).getBuiltinFunction().getFlags();
650650
}
651651
return 0;
652652
}
@@ -686,7 +686,7 @@ static Object getMethFromBuiltinFunction(PBuiltinFunction object) {
686686

687687
@Specialization
688688
static Object getMethFromBuiltinMethod(PBuiltinMethod object) {
689-
return getMethFromBuiltinFunction(object.getFunction());
689+
return getMethFromBuiltinFunction(object.getBuiltinFunction());
690690
}
691691

692692
@Fallback

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1176,9 +1176,10 @@ static Object doFCode(PFrame object, @SuppressWarnings("unused") PythonNativeWra
11761176

11771177
@Specialization(guards = "eq(FUNC_CODE, key)")
11781178
static Object doPFunctionCode(PFunction object, @SuppressWarnings("unused") PythonNativeWrapper nativeWrapper, @SuppressWarnings("unused") String key,
1179+
@Bind("this") Node inliningTarget,
11791180
@Cached GetFunctionCodeNode getFunctionCodeNode,
11801181
@Shared("toSulongNode") @Cached ToSulongNode toSulongNode) {
1181-
return toSulongNode.execute(getFunctionCodeNode.execute(object));
1182+
return toSulongNode.execute(getFunctionCodeNode.execute(inliningTarget, object));
11821183
}
11831184

11841185
@Specialization(guards = "eq(FUNC_GLOBALS, key)")

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ static Object getDoc(PythonObject object, @SuppressWarnings("unused") String key
197197
@Specialization(guards = {"eq(J_ML_METH, key)"})
198198
static Object getMethFromBuiltinMethod(PBuiltinMethod object, String key,
199199
@Shared("toSulongNode") @Cached ToSulongNode toSulongNode) {
200-
return getMethFromBuiltinFunction(object.getFunction(), key, toSulongNode);
200+
return getMethFromBuiltinFunction(object.getBuiltinFunction(), key, toSulongNode);
201201
}
202202

203203
@Specialization(guards = {"eq(J_ML_METH, key)"})
@@ -246,7 +246,7 @@ static int getFlags(PythonObject object, @SuppressWarnings("unused") String key)
246246
if (object instanceof PBuiltinFunction) {
247247
return ((PBuiltinFunction) object).getFlags();
248248
} else if (object instanceof PBuiltinMethod) {
249-
return ((PBuiltinMethod) object).getFunction().getFlags();
249+
return ((PBuiltinMethod) object).getBuiltinFunction().getFlags();
250250
}
251251
return 0;
252252
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@
4242

4343
import java.util.Arrays;
4444

45-
import com.oracle.graal.python.builtins.objects.code.CodeNodesFactory.GetCodeRootNodeGen;
4645
import org.graalvm.polyglot.io.ByteSequence;
4746

4847
import com.oracle.graal.python.PythonLanguage;
4948
import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins;
5049
import com.oracle.graal.python.builtins.objects.code.CodeNodesFactory.GetCodeCallTargetNodeGen;
50+
import com.oracle.graal.python.builtins.objects.code.CodeNodesFactory.GetCodeRootNodeGen;
5151
import com.oracle.graal.python.builtins.objects.function.Signature;
5252
import com.oracle.graal.python.compiler.CodeUnit;
5353
import com.oracle.graal.python.nodes.IndirectCallNode;
@@ -63,6 +63,8 @@
6363
import com.oracle.graal.python.util.Supplier;
6464
import com.oracle.truffle.api.Assumption;
6565
import com.oracle.truffle.api.CallTarget;
66+
import com.oracle.truffle.api.CompilerAsserts;
67+
import com.oracle.truffle.api.CompilerDirectives;
6668
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
6769
import com.oracle.truffle.api.RootCallTarget;
6870
import com.oracle.truffle.api.Truffle;
@@ -76,6 +78,7 @@
7678
import com.oracle.truffle.api.frame.VirtualFrame;
7779
import com.oracle.truffle.api.nodes.Node;
7880
import com.oracle.truffle.api.nodes.RootNode;
81+
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
7982
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
8083
import com.oracle.truffle.api.source.Source;
8184
import com.oracle.truffle.api.strings.TruffleString;
@@ -223,18 +226,26 @@ static RootCallTarget doGeneric(Node node, PCode code,
223226
public abstract static class GetCodeSignatureNode extends PNodeWithContext {
224227
public abstract Signature execute(Node node, PCode code);
225228

226-
@SuppressWarnings("unused")
227-
@Specialization(guards = {"isSingleContext()", "cachedCode == code"}, limit = "2")
228-
protected static Signature doCached(Node node, PCode code,
229+
@Specialization(guards = {"cachedCode == code", "isSingleContext(inliningTarget)"}, limit = "2")
230+
static Signature doCached(Node inliningTarget, @SuppressWarnings("unused") PCode code,
229231
@Cached("code") PCode cachedCode,
230-
@Cached("code.initializeCallTarget()") RootCallTarget ct,
231-
@Cached("code.initializeSignature(ct)") Signature signature) {
232-
return signature;
232+
@Cached InlinedBranchProfile firstExecution) {
233+
return getInSingleContextMode(inliningTarget, cachedCode, firstExecution);
234+
}
235+
236+
public static Signature getInSingleContextMode(Node inliningTarget, PCode code, InlinedBranchProfile firstExecution) {
237+
assert isSingleContext(inliningTarget);
238+
CompilerAsserts.partialEvaluationConstant(code);
239+
if (!firstExecution.wasEntered(inliningTarget)) {
240+
firstExecution.enter(inliningTarget);
241+
CompilerDirectives.transferToInterpreter();
242+
code.initializeSignature(code.initializeCallTarget());
243+
}
244+
return code.signature;
233245
}
234246

235247
@Specialization(replaces = "doCached")
236-
protected static Signature doCode(Node node, PCode code,
237-
@Bind("this") Node inliningTarget,
248+
static Signature getGeneric(Node inliningTarget, PCode code,
238249
@Cached InlinedConditionProfile signatureProfile,
239250
@Cached InlinedConditionProfile ctProfile) {
240251
Signature signature = code.signature;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
7474
import com.oracle.truffle.api.dsl.Bind;
7575
import com.oracle.truffle.api.dsl.Cached;
76+
import com.oracle.truffle.api.dsl.Cached.Shared;
7677
import com.oracle.truffle.api.dsl.Fallback;
7778
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
7879
import com.oracle.truffle.api.dsl.NodeFactory;
@@ -94,16 +95,17 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
9495
@Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
9596
@GenerateNodeFactory
9697
public abstract static class CallNode extends PythonBuiltinNode {
97-
@Child private CallDispatchNode dispatch = CallDispatchNode.create();
98-
@Child private CreateArgumentsNode createArgs = CreateArgumentsNode.create();
99-
10098
@Specialization
101-
protected Object doIt(VirtualFrame frame, PFunction self, Object[] arguments, PKeyword[] keywords) {
99+
protected Object doIt(VirtualFrame frame, PFunction self, Object[] arguments, PKeyword[] keywords,
100+
@Shared @Cached CreateArgumentsNode createArgs,
101+
@Shared @Cached CallDispatchNode dispatch) {
102102
return dispatch.executeCall(frame, self, createArgs.execute(self, arguments, keywords));
103103
}
104104

105105
@Specialization
106-
protected Object doIt(VirtualFrame frame, PBuiltinFunction self, Object[] arguments, PKeyword[] keywords) {
106+
protected Object doIt(VirtualFrame frame, PBuiltinFunction self, Object[] arguments, PKeyword[] keywords,
107+
@Shared @Cached CreateArgumentsNode createArgs,
108+
@Shared @Cached CallDispatchNode dispatch) {
107109
return dispatch.executeCall(frame, self, createArgs.execute(self, arguments, keywords));
108110
}
109111
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@
6666
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
6767
import com.oracle.graal.python.nodes.ErrorMessages;
6868
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionCodeNode;
69-
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionDefaultsNode;
70-
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionKeywordDefaultsNode;
7169
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
7270
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
7371
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
@@ -167,9 +165,8 @@ static Object setQualname(PFunction self, Object value,
167165
@GenerateNodeFactory
168166
public abstract static class GetDefaultsNode extends PythonBinaryBuiltinNode {
169167
@Specialization(guards = "isNoValue(defaults)")
170-
Object defaults(PFunction self, @SuppressWarnings("unused") PNone defaults,
171-
@Cached GetFunctionDefaultsNode getFunctionDefaultsNode) {
172-
Object[] argDefaults = getFunctionDefaultsNode.execute(self);
168+
Object defaults(PFunction self, @SuppressWarnings("unused") PNone defaults) {
169+
Object[] argDefaults = self.getDefaults();
173170
assert argDefaults != null;
174171
return (argDefaults.length == 0) ? PNone.NONE : factory().createTuple(argDefaults);
175172
}
@@ -205,9 +202,8 @@ Object setDefaults(Object self, Object defaults) {
205202
@GenerateNodeFactory
206203
public abstract static class GetKeywordDefaultsNode extends PythonBinaryBuiltinNode {
207204
@Specialization(guards = "isNoValue(arg)")
208-
Object get(PFunction self, @SuppressWarnings("unused") PNone arg,
209-
@Cached GetFunctionKeywordDefaultsNode getFunctionKeywordDefaultsNode) {
210-
PKeyword[] kwdefaults = getFunctionKeywordDefaultsNode.execute(self);
205+
Object get(PFunction self, @SuppressWarnings("unused") PNone arg) {
206+
PKeyword[] kwdefaults = self.getKwDefaults();
211207
return (kwdefaults.length > 0) ? factory().createDict(kwdefaults) : PNone.NONE;
212208
}
213209

@@ -275,8 +271,9 @@ Object doGeneric(Object object) {
275271
public abstract static class GetCodeNode extends PythonBinaryBuiltinNode {
276272
@Specialization(guards = {"isNoValue(none)"})
277273
static Object getCodeU(PFunction self, @SuppressWarnings("unused") PNone none,
274+
@Bind("this") Node inliningTarget,
278275
@Cached GetFunctionCodeNode getFunctionCodeNode) {
279-
return getFunctionCodeNode.execute(self);
276+
return getFunctionCodeNode.execute(inliningTarget, self);
280277
}
281278

282279
@SuppressWarnings("unused")

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.oracle.graal.python.util.PythonUtils;
3838
import com.oracle.truffle.api.Assumption;
3939
import com.oracle.truffle.api.CompilerAsserts;
40+
import com.oracle.truffle.api.CompilerDirectives;
4041
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
4142
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4243
import com.oracle.truffle.api.Truffle;
@@ -62,9 +63,12 @@ public final class PFunction extends PythonObject {
6263
private final PythonObject globals;
6364
@CompilationFinal private boolean isBuiltin;
6465
@CompilationFinal(dimensions = 1) private final PCell[] closure;
65-
@CompilationFinal private PCode code;
66-
@CompilationFinal(dimensions = 1) private Object[] defaultValues;
67-
@CompilationFinal(dimensions = 1) private PKeyword[] kwDefaultValues;
66+
@CompilationFinal private PCode finalCode;
67+
private PCode code;
68+
@CompilationFinal(dimensions = 1) private Object[] finalDefaultValues;
69+
private Object[] defaultValues;
70+
@CompilationFinal(dimensions = 1) private PKeyword[] finalKwDefaultValues;
71+
private PKeyword[] kwDefaultValues;
6872

6973
public PFunction(PythonLanguage lang, TruffleString name, TruffleString qualname, PCode code, PythonObject globals, PCell[] closure) {
7074
this(lang, name, qualname, code, globals, PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS, closure);
@@ -83,10 +87,10 @@ public PFunction(PythonLanguage lang, TruffleString name, TruffleString qualname
8387
this.name = name;
8488
this.qualname = qualname;
8589
assert code != null;
86-
this.code = code;
90+
this.code = this.finalCode = code;
8791
this.globals = globals;
88-
this.defaultValues = defaultValues == null ? PythonUtils.EMPTY_OBJECT_ARRAY : defaultValues;
89-
this.kwDefaultValues = kwDefaultValues == null ? PKeyword.EMPTY_KEYWORDS : kwDefaultValues;
92+
this.defaultValues = this.finalDefaultValues = defaultValues == null ? PythonUtils.EMPTY_OBJECT_ARRAY : defaultValues;
93+
this.kwDefaultValues = this.finalKwDefaultValues = kwDefaultValues == null ? PKeyword.EMPTY_KEYWORDS : kwDefaultValues;
9094
this.closure = closure;
9195
this.codeStableAssumption = codeStableAssumption;
9296
this.defaultsStableAssumption = defaultsStableAssumption;
@@ -148,33 +152,51 @@ public final String toString() {
148152
}
149153

150154
public PCode getCode() {
155+
if (CompilerDirectives.inCompiledCode() && CompilerDirectives.isPartialEvaluationConstant(this)) {
156+
if (getCodeStableAssumption().isValid()) {
157+
return finalCode;
158+
}
159+
}
151160
return code;
152161
}
153162

154163
@TruffleBoundary
155164
public void setCode(PCode code) {
156165
codeStableAssumption.invalidate("code changed for function " + getName());
157166
assert code != null : "code cannot be null";
167+
this.finalCode = null;
158168
this.code = code;
159169
}
160170

161171
public Object[] getDefaults() {
172+
if (CompilerDirectives.inCompiledCode() && CompilerDirectives.isPartialEvaluationConstant(this)) {
173+
if (defaultsStableAssumption.isValid()) {
174+
return finalDefaultValues;
175+
}
176+
}
162177
return defaultValues;
163178
}
164179

165180
@TruffleBoundary
166181
public void setDefaults(Object[] defaults) {
167182
this.defaultsStableAssumption.invalidate("defaults changed for function " + getName());
183+
this.finalDefaultValues = null; // avoid leak, and make code that wrongly uses it crash
168184
this.defaultValues = defaults;
169185
}
170186

171187
public PKeyword[] getKwDefaults() {
188+
if (CompilerDirectives.inCompiledCode() && CompilerDirectives.isPartialEvaluationConstant(this)) {
189+
if (defaultsStableAssumption.isValid()) {
190+
return finalKwDefaultValues;
191+
}
192+
}
172193
return kwDefaultValues;
173194
}
174195

175196
@TruffleBoundary
176197
public void setKwDefaults(PKeyword[] defaults) {
177198
this.defaultsStableAssumption.invalidate("kw defaults changed for function " + getName());
199+
this.finalDefaultValues = null; // avoid leak, and make code that wrongly uses it crash
178200
this.kwDefaultValues = defaults;
179201
}
180202

0 commit comments

Comments
 (0)