Skip to content

Commit 618064f

Browse files
committed
use java array in itertools.product internal pool
1 parent 4a5784e commit 618064f

File tree

3 files changed

+49
-52
lines changed

3 files changed

+49
-52
lines changed

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

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@
7979
import com.oracle.graal.python.lib.PyObjectTypeCheck;
8080
import com.oracle.graal.python.nodes.ErrorMessages;
8181
import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes.ToArrayNode;
82-
import com.oracle.graal.python.lib.PyObjectSizeNode;
83-
import com.oracle.graal.python.nodes.builtins.ListNodes.FastConstructListNode;
8482
import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode;
8583
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
8684
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -93,7 +91,6 @@
9391
import com.oracle.graal.python.nodes.util.CannotCastException;
9492
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
9593
import com.oracle.graal.python.runtime.exception.PException;
96-
import com.oracle.graal.python.runtime.sequence.PSequence;
9794
import com.oracle.graal.python.util.PythonUtils;
9895
import com.oracle.truffle.api.dsl.Cached;
9996
import com.oracle.truffle.api.dsl.Fallback;
@@ -663,46 +660,43 @@ public abstract static class ProductNode extends PythonBuiltinNode {
663660

664661
@Specialization(guards = "isTypeNode.execute(cls)")
665662
Object constructNoneRepeat(VirtualFrame frame, Object cls, Object[] iterables, @SuppressWarnings("unused") PNone repeat,
666-
@Cached PyObjectSizeNode sizeNode,
667-
@Cached FastConstructListNode listNode,
663+
@Cached ToArrayNode toArrayNode,
668664
@SuppressWarnings("unused") @Cached IsTypeNode isTypeNode) {
669665
PProduct self = factory().createProduct(cls);
670-
constructOneRepeat(frame, self, iterables, listNode, sizeNode);
666+
constructOneRepeat(frame, self, iterables, toArrayNode);
671667
return self;
672668
}
673669

674670
@Specialization(guards = {"isTypeNode.execute(cls)", "repeat == 1"})
675671
Object constructOneRepeat(VirtualFrame frame, Object cls, Object[] iterables, @SuppressWarnings("unused") int repeat,
676-
@Cached PyObjectSizeNode sizeNode,
677-
@Cached FastConstructListNode listNode,
672+
@Cached ToArrayNode toArrayNode,
678673
@SuppressWarnings("unused") @Cached IsTypeNode isTypeNode) {
679674
PProduct self = factory().createProduct(cls);
680-
constructOneRepeat(frame, self, iterables, listNode, sizeNode);
675+
constructOneRepeat(frame, self, iterables, toArrayNode);
681676
return self;
682677
}
683678

684679
@Specialization(guards = {"isTypeNode.execute(cls)", "repeat > 1"})
685680
Object construct(VirtualFrame frame, Object cls, Object[] iterables, int repeat,
686-
@Cached PyObjectSizeNode sizeNode,
687-
@Cached FastConstructListNode listNode,
681+
@Cached ToArrayNode toArrayNode,
688682
@Cached LoopConditionProfile loopProfile,
689683
@SuppressWarnings("unused") @Cached IsTypeNode isTypeNode) {
690-
PSequence[] lists = wrapIterables(frame, iterables, listNode);
691-
PSequence[] gears = new PSequence[lists.length * repeat];
684+
Object[][] lists = unpackIterables(frame, iterables, toArrayNode);
685+
Object[][] gears = new Object[lists.length * repeat][];
692686
loopProfile.profileCounted(repeat);
693687
for (int i = 0; loopProfile.inject(i < repeat); i++) {
694688
PythonUtils.arraycopy(lists, 0, gears, i * lists.length, lists.length);
695689
}
696690
PProduct self = factory().createProduct(cls);
697-
construct(frame, self, gears, sizeNode);
691+
construct(self, gears);
698692
return self;
699693
}
700694

701695
@Specialization(guards = {"isTypeNode.execute(cls)", "repeat == 0"})
702696
Object constructNoRepeat(Object cls, @SuppressWarnings("unused") Object[] iterables, @SuppressWarnings("unused") int repeat,
703697
@SuppressWarnings("unused") @Cached IsTypeNode isTypeNode) {
704698
PProduct self = factory().createProduct(cls);
705-
self.setGears(new PSequence[0]);
699+
self.setGears(new Object[0][]);
706700
self.setIndices(new int[0]);
707701
self.setLst(null);
708702
self.setStopped(false);
@@ -716,16 +710,15 @@ Object constructNeg(Object cls, Object[] iterables, int repeat,
716710
throw raise(TypeError, ARG_CANNOT_BE_NEGATIVE, "repeat");
717711
}
718712

719-
private static void constructOneRepeat(VirtualFrame frame, PProduct self, Object[] iterables, FastConstructListNode listNode, PyObjectSizeNode sizeNode) {
720-
PSequence[] gears = wrapIterables(frame, iterables, listNode);
721-
construct(frame, self, gears, sizeNode);
713+
private static void constructOneRepeat(VirtualFrame frame, PProduct self, Object[] iterables, ToArrayNode toArrayNode) {
714+
Object[][] gears = unpackIterables(frame, iterables, toArrayNode);
715+
construct(self, gears);
722716
}
723717

724-
private static void construct(VirtualFrame frame, PProduct self, PSequence[] gears, PyObjectSizeNode sizeNode) {
718+
private static void construct(PProduct self, Object[][] gears) {
725719
self.setGears(gears);
726720
for (int i = 0; i < gears.length; i++) {
727-
// XXX could be generator
728-
if (sizeNode.execute(frame, gears[i]) == 0) {
721+
if (gears[i].length == 0) {
729722
self.setIndices(null);
730723
self.setLst(null);
731724
self.setStopped(true);
@@ -737,10 +730,10 @@ private static void construct(VirtualFrame frame, PProduct self, PSequence[] gea
737730
self.setStopped(false);
738731
}
739732

740-
private static PSequence[] wrapIterables(VirtualFrame frame, Object[] iterables, FastConstructListNode listNode) {
741-
PSequence[] lists = new PSequence[iterables.length];
733+
private static Object[][] unpackIterables(VirtualFrame frame, Object[] iterables, ToArrayNode toArrayNode) {
734+
Object[][] lists = new Object[iterables.length][];
742735
for (int i = 0; i < lists.length; i++) {
743-
lists[i] = listNode.execute(frame, iterables[i]);
736+
lists[i] = toArrayNode.execute(frame, iterables[i]);
744737
}
745738
return lists;
746739
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PProduct.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import com.oracle.truffle.api.object.Shape;
4545

4646
public final class PProduct extends PythonBuiltinObject {
47-
private Object[] gears;
47+
private Object[][] gears;
4848
private Object[] lst;
4949
private int[] indices;
5050
private boolean stopped;
@@ -53,11 +53,11 @@ public PProduct(Object cls, Shape instanceShape) {
5353
super(cls, instanceShape);
5454
}
5555

56-
public Object[] getGears() {
56+
public Object[][] getGears() {
5757
return gears;
5858
}
5959

60-
public void setGears(Object[] gears) {
60+
public void setGears(Object[][] gears) {
6161
this.gears = gears;
6262
}
6363

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ProductBuiltins.java

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@
5353
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5454
import com.oracle.graal.python.builtins.PythonBuiltins;
5555
import com.oracle.graal.python.builtins.objects.PNone;
56+
import com.oracle.graal.python.builtins.objects.list.PList;
5657
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
5758
import com.oracle.graal.python.lib.PyObjectGetItem;
58-
import com.oracle.graal.python.lib.PyObjectSizeNode;
5959
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6060
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
6161
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
@@ -92,40 +92,37 @@ static Object iter(PProduct self) {
9292
public abstract static class NextNode extends PythonUnaryBuiltinNode {
9393

9494
@Specialization(guards = {"!self.isStopped()", "!hasLst(self)"})
95-
Object next(VirtualFrame frame, PProduct self,
96-
@Cached PyObjectGetItem getItemNode,
95+
Object next(PProduct self,
9796
@Cached LoopConditionProfile loopProfile) {
9897
Object[] lst = new Object[self.getGears().length];
9998
loopProfile.profileCounted(lst.length);
10099
for (int i = 0; loopProfile.inject(i < lst.length); i++) {
101-
lst[i] = getItemNode.execute(frame, self.getGears()[i], 0);
100+
lst[i] = self.getGears()[i][0];
102101
}
103102
self.setLst(lst);
104103
return factory().createTuple(lst);
105104
}
106105

107106
@Specialization(guards = {"!self.isStopped()", "hasLst(self)"})
108-
Object next(VirtualFrame frame, PProduct self,
109-
@Cached PyObjectGetItem getItemNode,
110-
@Cached PyObjectSizeNode sizeNode,
107+
Object next(PProduct self,
111108
@Cached ConditionProfile gearsProfile,
112109
@Cached ConditionProfile indexProfile,
113110
@Cached BranchProfile wasStoppedProfile,
114111
@Cached LoopConditionProfile loopProfile,
115112
@Cached BranchProfile doneProfile) {
116113

117-
Object[] gears = self.getGears();
114+
Object[][] gears = self.getGears();
118115
int x = gears.length - 1;
119116
if (gearsProfile.profile(x >= 0)) {
120-
Object gear = gears[x];
117+
Object[] gear = gears[x];
121118
int[] indices = self.getIndices();
122119
int index = indices[x] + 1;
123-
if (indexProfile.profile(index < sizeNode.execute(frame, gear))) {
120+
if (indexProfile.profile(index < gear.length)) {
124121
// no carry: done
125-
self.getLst()[x] = getItemNode.execute(frame, gear, index);
122+
self.getLst()[x] = gear[index];
126123
indices[x] = index;
127124
} else {
128-
rotatePreviousGear(frame, self, getItemNode, sizeNode, loopProfile, doneProfile);
125+
rotatePreviousGear(self, loopProfile, doneProfile);
129126
}
130127
} else {
131128
self.setStopped(true);
@@ -148,26 +145,26 @@ Object nextStopped(PProduct self) {
148145
throw raise(StopIteration);
149146
}
150147

151-
private static void rotatePreviousGear(VirtualFrame frame, PProduct self, PyObjectGetItem getItemNode, PyObjectSizeNode sizeNode, LoopConditionProfile loopProfile, BranchProfile doneProfile) {
148+
private static void rotatePreviousGear(PProduct self, LoopConditionProfile loopProfile, BranchProfile doneProfile) {
152149
Object[] lst = self.getLst();
153-
Object[] gears = self.getGears();
150+
Object[][] gears = self.getGears();
154151
int x = gears.length - 1;
155-
lst[x] = getItemNode.execute(frame, gears[x], 0);
152+
lst[x] = gears[x][0];
156153
int[] indices = self.getIndices();
157154
indices[x] = 0;
158155
x = x - 1;
159156
// the outer loop runs as long as a we have a carry
160157
while (loopProfile.profile(x >= 0)) {
161-
Object gear = gears[x];
158+
Object[] gear = gears[x];
162159
int index = indices[x] + 1;
163-
if (index < sizeNode.execute(frame, gear)) {
160+
if (index < gear.length) {
164161
// no carry: done
165162
doneProfile.enter();
166-
lst[x] = getItemNode.execute(frame, gear, index);
163+
lst[x] = gear[index];
167164
indices[x] = index;
168165
return;
169166
}
170-
lst[x] = getItemNode.execute(frame, gear, 0);
167+
lst[x] = gear[0];
171168
indices[x] = 0;
172169
x = x - 1;
173170
}
@@ -187,19 +184,27 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
187184
Object reduce(PProduct self,
188185
@Cached GetClassNode getClassNode) {
189186
Object type = getClassNode.execute(self);
190-
PTuple gearTuples = factory().createTuple(self.getGears());
187+
PTuple gearTuples = createGearTuple(self);
191188
return factory().createTuple(new Object[]{type, gearTuples});
192189
}
193190

194191
@Specialization(guards = {"!self.isStopped()", "hasLst(self)"})
195192
Object reduceLst(PProduct self,
196193
@Cached GetClassNode getClassNode) {
197194
Object type = getClassNode.execute(self);
198-
PTuple gearTuples = factory().createTuple(self.getGears());
195+
PTuple gearTuples = createGearTuple(self);
199196
PTuple indicesTuple = factory().createTuple(PythonUtils.arrayCopyOf(self.getIndices(), self.getIndices().length));
200197
return factory().createTuple(new Object[]{type, gearTuples, indicesTuple});
201198
}
202199

200+
private PTuple createGearTuple(PProduct self) {
201+
PList[] lists = new PList[self.getGears().length];
202+
for (int i = 0; i < lists.length; i++) {
203+
lists[i] = factory().createList(self.getGears()[i]);
204+
}
205+
return factory().createTuple(lists);
206+
}
207+
203208
@Specialization(guards = "self.isStopped()")
204209
Object reduceStopped(PProduct self,
205210
@Cached GetClassNode getClassNode) {
@@ -218,18 +223,17 @@ protected static boolean hasLst(PProduct self) {
218223
public abstract static class SetStateNode extends PythonBinaryBuiltinNode {
219224
@Specialization
220225
static Object setState(VirtualFrame frame, PProduct self, Object state,
221-
@Cached PyObjectSizeNode sizeNode,
222226
@Cached PyObjectGetItem getItemNode,
223227
@Cached LoopConditionProfile loopProfile,
224228
@Cached BranchProfile stoppedProfile,
225229
@Cached ConditionProfile indexProfile) {
226-
Object[] gears = self.getGears();
230+
Object[][] gears = self.getGears();
227231
Object[] lst = new Object[gears.length];
228232
int[] indices = self.getIndices();
229233
loopProfile.profileCounted(gears.length);
230234
for (int i = 0; loopProfile.inject(i < gears.length); i++) {
231235
int index = (int) getItemNode.execute(frame, state, i);
232-
int gearSize = sizeNode.execute(frame, gears[i]);
236+
int gearSize = gears[i].length;
233237
if (indices == null || gearSize == 0) {
234238
stoppedProfile.enter();
235239
self.setStopped(true);
@@ -241,7 +245,7 @@ static Object setState(VirtualFrame frame, PProduct self, Object state,
241245
index = gearSize - 1;
242246
}
243247
indices[i] = index;
244-
lst[i] = getItemNode.execute(frame, gears[i], index);
248+
lst[i] = gears[i][index];
245249
}
246250
self.setLst(lst);
247251
return PNone.NONE;

0 commit comments

Comments
 (0)