Skip to content

Commit fb566c7

Browse files
committed
[GR-11049] More efficient execution of generators.
PullRequest: graalpython/136
2 parents 528d1af + e724a4c commit fb566c7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+862
-841
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_generator-if-and-loop.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,22 @@ def foo(arg):
4040

4141
assert foo([1,2,3,4]) == [1,2,3,4]
4242
assert foo("hello") == ["h", "e", "l", "l", "o"]
43+
44+
def gen_effect(n):
45+
if effect(n) == 5:
46+
yield 1
47+
yield 2
48+
else:
49+
yield 3
50+
yield 4
51+
52+
effect_count = 0
53+
def effect(n):
54+
global effect_count
55+
effect_count += 1
56+
return n
57+
58+
def test_sideeffect():
59+
l = list(gen_effect(5))
60+
assert l == [1,2]
61+
assert effect_count == 1

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
import com.oracle.graal.python.nodes.datamodel.IsSequenceNode;
141141
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
142142
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
143+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
143144
import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
144145
import com.oracle.graal.python.nodes.object.GetClassNode;
145146
import com.oracle.graal.python.nodes.subscript.SliceLiteralNode;
@@ -809,29 +810,29 @@ public Object createInt(PythonClass cls, Object obj, PNone keywordArg,
809810
@Builtin(name = BOOL, minNumOfArguments = 1, maxNumOfArguments = 2, constructsClass = Boolean.class, base = PInt.class)
810811
@GenerateNodeFactory
811812
@SuppressWarnings("unused")
812-
public abstract static class BoolNode extends PythonBuiltinNode {
813+
public abstract static class BoolNode extends PythonBinaryBuiltinNode {
813814
@Specialization
814-
public boolean bool(Object cls, boolean arg) {
815+
public boolean boolB(Object cls, boolean arg) {
815816
return arg;
816817
}
817818

818819
@Specialization
819-
public boolean bool(Object cls, int arg) {
820+
public boolean boolI(Object cls, int arg) {
820821
return arg != 0;
821822
}
822823

823824
@Specialization
824-
public boolean bool(Object cls, double arg) {
825+
public boolean boolD(Object cls, double arg) {
825826
return arg != 0.0;
826827
}
827828

828829
@Specialization
829-
public boolean bool(Object cls, String arg) {
830+
public boolean boolS(Object cls, String arg) {
830831
return !arg.isEmpty();
831832
}
832833

833834
@Specialization
834-
public boolean bool(Object cls, PNone arg) {
835+
public boolean boolN(Object cls, PNone arg) {
835836
return false;
836837
}
837838

@@ -850,7 +851,7 @@ public boolean bool(Object cls, Object obj,
850851
// list([iterable])
851852
@Builtin(name = LIST, minNumOfArguments = 1, maxNumOfArguments = 2, constructsClass = PList.class)
852853
@GenerateNodeFactory
853-
public abstract static class ListNode extends PythonBuiltinNode {
854+
public abstract static class ListNode extends PythonBinaryBuiltinNode {
854855

855856
@Specialization
856857
protected PList constructList(PythonClass cls, Object value,
@@ -1129,7 +1130,7 @@ private ConditionProfile getIsPStringProfile() {
11291130
// tuple([iterable])
11301131
@Builtin(name = TUPLE, minNumOfArguments = 1, maxNumOfArguments = 2, constructsClass = PTuple.class)
11311132
@GenerateNodeFactory
1132-
public abstract static class TupleNode extends PythonBuiltinNode {
1133+
public abstract static class TupleNode extends PythonBinaryBuiltinNode {
11331134

11341135
@Specialization
11351136
protected PTuple constructTuple(PythonClass cls, Object value,

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,7 @@ public static void setControlData(Object[] arguments, GeneratorControlData gener
217217
generatorFrame.getArguments()[INDEX_GENERATOR_FRAME] = generatorArguments;
218218
}
219219

220-
public static GeneratorControlData getControlData(Frame frame) {
221-
Frame generatorFrame = getGeneratorFrame(frame);
220+
public static GeneratorControlData getControlDataFromGeneratorFrame(Frame generatorFrame) {
222221
return (GeneratorControlData) generatorFrame.getArguments()[INDEX_GENERATOR_FRAME];
223222
}
224223

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,15 @@
4747
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4848
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
4949
import com.oracle.graal.python.runtime.exception.PException;
50+
import com.oracle.truffle.api.CallTarget;
51+
import com.oracle.truffle.api.RootCallTarget;
52+
import com.oracle.truffle.api.Truffle;
5053
import com.oracle.truffle.api.dsl.Cached;
5154
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5255
import com.oracle.truffle.api.dsl.NodeFactory;
5356
import com.oracle.truffle.api.dsl.Specialization;
57+
import com.oracle.truffle.api.nodes.DirectCallNode;
58+
import com.oracle.truffle.api.nodes.IndirectCallNode;
5459
import com.oracle.truffle.api.profiles.ConditionProfile;
5560

5661
@CoreFunctions(extendClasses = PGenerator.class)
@@ -85,13 +90,41 @@ public abstract static class NextNode extends PythonUnaryBuiltinNode {
8590

8691
private final ConditionProfile errorProfile = ConditionProfile.createBinaryProfile();
8792

88-
@Specialization
89-
public Object next(PGenerator self) {
93+
protected static DirectCallNode createDirectCall(CallTarget target) {
94+
return Truffle.getRuntime().createDirectCallNode(target);
95+
}
96+
97+
protected static IndirectCallNode createIndirectCall() {
98+
return Truffle.getRuntime().createIndirectCallNode();
99+
}
100+
101+
protected static boolean sameCallTarget(RootCallTarget target1, CallTarget target2) {
102+
return target1 == target2;
103+
}
104+
105+
@Specialization(guards = "sameCallTarget(self.getCallTarget(), call.getCallTarget())", limit = "getCallSiteInlineCacheMaxDepth()")
106+
public Object nextCached(PGenerator self,
107+
@Cached("createDirectCall(self.getCallTarget())") DirectCallNode call) {
108+
if (self.isFinished()) {
109+
throw raise(StopIteration);
110+
}
111+
try {
112+
return call.call(self.getArguments());
113+
} catch (PException e) {
114+
e.expectStopIteration(getCore(), errorProfile);
115+
self.markAsFinished();
116+
throw raise(StopIteration);
117+
}
118+
}
119+
120+
@Specialization(replaces = "nextCached")
121+
public Object next(PGenerator self,
122+
@Cached("createIndirectCall()") IndirectCallNode call) {
90123
if (self.isFinished()) {
91124
throw raise(StopIteration);
92125
}
93126
try {
94-
return self.getCallTarget().call(self.getArguments());
127+
return call.call(self.getCallTarget(), self.getArguments());
95128
} catch (PException e) {
96129
e.expectStopIteration(getCore(), errorProfile);
97130
self.markAsFinished();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/NodeFactory.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import com.oracle.graal.python.nodes.function.ClassBodyRootNode;
7676
import com.oracle.graal.python.nodes.function.FunctionRootNode;
7777
import com.oracle.graal.python.nodes.generator.DictConcatNode;
78-
import com.oracle.graal.python.nodes.generator.ListAppendNode;
7978
import com.oracle.graal.python.nodes.generator.YieldNode;
8079
import com.oracle.graal.python.nodes.generator.YieldResumeNode;
8180
import com.oracle.graal.python.nodes.literal.BooleanLiteralNode;
@@ -281,11 +280,6 @@ public PNode createSetLiteral(Set<PNode> values) {
281280
return new SetLiteralNode(convertedValues);
282281
}
283282

284-
public PNode createListAppend(FrameSlot frameSlot, PNode right) {
285-
PNode readList = createReadLocal(frameSlot);
286-
return ListAppendNode.create(readList, right);
287-
}
288-
289283
public PNode createUnaryOperation(String string, PNode operand) {
290284
switch (string) {
291285
case "+":
@@ -523,10 +517,6 @@ public PNode createDictionaryConcat(PNode... dictNodes) {
523517
return DictConcatNode.create(dictNodes);
524518
}
525519

526-
public PNode createListAppend(PNode leftNode, PNode rightNode) {
527-
return ListAppendNode.create(leftNode, rightNode);
528-
}
529-
530520
public PNode callBuiltin(String string, PNode argument) {
531521
return PythonCallNode.create(getBuiltin(string), new PNode[]{argument}, new PNode[0], EmptyNode.create(), EmptyNode.create());
532522
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/DeleteAttributeNode.java

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

43+
import com.oracle.graal.python.builtins.objects.type.PythonClass;
4344
import com.oracle.graal.python.nodes.PNode;
44-
import com.oracle.graal.python.nodes.argument.CreateArgumentsNode;
45-
import com.oracle.graal.python.nodes.call.CallDispatchNode;
45+
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
4646
import com.oracle.graal.python.nodes.object.GetClassNode;
4747
import com.oracle.truffle.api.dsl.Cached;
4848
import com.oracle.truffle.api.dsl.NodeChild;
4949
import com.oracle.truffle.api.dsl.NodeChildren;
5050
import com.oracle.truffle.api.dsl.Specialization;
5151
import com.oracle.truffle.api.profiles.ValueProfile;
5252

53-
import com.oracle.graal.python.builtins.objects.function.PKeyword;
54-
import com.oracle.graal.python.builtins.objects.type.PythonClass;
55-
5653
@NodeChildren({@NodeChild(value = "object", type = PNode.class), @NodeChild(value = "key", type = PNode.class)})
5754
public abstract class DeleteAttributeNode extends PNode {
5855
public static DeleteAttributeNode create() {
@@ -70,10 +67,9 @@ protected Object doIt(Object object, Object key,
7067
@Cached("createIdentityProfile()") ValueProfile setattributeProfile,
7168
@Cached("create()") GetClassNode getClassNode,
7269
@Cached("create(__DELATTR__)") LookupAttributeInMRONode lookupDelAttr,
73-
@Cached("create()") CallDispatchNode dispatchSetattribute,
74-
@Cached("create()") CreateArgumentsNode createArgs) {
70+
@Cached("create()") CallBinaryMethodNode dispatchSetattribute) {
7571
PythonClass type = getClassNode.execute(object);
7672
Object descr = setattributeProfile.profile(lookupDelAttr.execute(type));
77-
return dispatchSetattribute.executeCall(descr, createArgs.execute(object, key), new PKeyword[0]);
73+
return dispatchSetattribute.executeObject(descr, object, key);
7874
}
7975
}

0 commit comments

Comments
 (0)