|
49 | 49 | import com.oracle.graal.python.builtins.objects.ints.IntBuiltins; |
50 | 50 | import com.oracle.graal.python.builtins.objects.ints.PInt; |
51 | 51 | import com.oracle.graal.python.builtins.objects.tuple.PTuple; |
| 52 | +import com.oracle.graal.python.builtins.objects.type.TpSlots; |
| 53 | +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; |
| 54 | +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext; |
52 | 55 | import com.oracle.graal.python.lib.IteratorExhausted; |
53 | 56 | import com.oracle.graal.python.lib.PyBoolCheckNode; |
54 | 57 | import com.oracle.graal.python.lib.PyFloatAsDoubleNode; |
@@ -869,24 +872,38 @@ protected ArgumentClinicProvider getArgumentClinic() { |
869 | 872 | @Builtin(name = "fsum", minNumOfPositionalArgs = 1) |
870 | 873 | @GenerateNodeFactory |
871 | 874 | public abstract static class FsumNode extends PythonUnaryBuiltinNode { |
| 875 | + |
| 876 | + /** |
| 877 | + * Note: this specialization uses an inlined version of {@link PyIterNextNode} with the |
| 878 | + * tp_iternext slot moved out of the loop. |
| 879 | + */ |
872 | 880 | @Specialization |
873 | 881 | static double doIt(VirtualFrame frame, Object iterable, |
874 | 882 | @Bind Node inliningTarget, |
875 | 883 | @Cached PyObjectGetIter getIter, |
876 | | - @Cached PyIterNextNode nextNode, |
| 884 | + @Cached GetClassNode nextNodeGetClassNode, |
| 885 | + @Cached TpSlots.GetCachedTpSlotsNode nextNodeGetSlots, |
| 886 | + @Cached TpSlotIterNext.CallSlotTpIterNextNode nextNodeCallNext, |
| 887 | + @Cached IsBuiltinObjectProfile nextNodeStopIterationProfile, |
877 | 888 | @Cached PyFloatAsDoubleNode asDoubleNode, |
878 | 889 | @Cached PRaiseNode raiseNode) { |
879 | 890 | Object iterator = getIter.execute(frame, inliningTarget, iterable); |
880 | 891 |
|
| 892 | + TpSlot tpIternext = nextNodeGetSlots.execute(inliningTarget, nextNodeGetClassNode.execute(inliningTarget, iterator)).tp_iternext(); |
| 893 | + assert tpIternext != null; |
| 894 | + |
881 | 895 | var acc = new XSum.SmallAccumulator(); |
882 | 896 | int nbrIter = 0; |
883 | 897 | while (true) { |
884 | 898 | try { |
885 | | - Object next = nextNode.execute(frame, inliningTarget, iterator); |
| 899 | + Object next = nextNodeCallNext.execute(frame, inliningTarget, tpIternext, iterator); |
886 | 900 | nbrIter++; |
887 | 901 | acc.add(asDoubleNode.execute(frame, inliningTarget, next)); |
888 | 902 | } catch (IteratorExhausted e) { |
889 | 903 | break; |
| 904 | + } catch (PException e) { |
| 905 | + e.expectStopIteration(inliningTarget, nextNodeStopIterationProfile); |
| 906 | + break; |
890 | 907 | } finally { |
891 | 908 | LoopNode.reportLoopCount(inliningTarget, nbrIter); |
892 | 909 | } |
|
0 commit comments