|
40 | 40 | */
|
41 | 41 | package com.oracle.graal.python.nodes;
|
42 | 42 |
|
| 43 | +import com.oracle.graal.python.PythonLanguage; |
43 | 44 | import com.oracle.graal.python.builtins.objects.cell.PCell;
|
44 | 45 | import com.oracle.graal.python.builtins.objects.function.PArguments;
|
| 46 | +import com.oracle.truffle.api.Assumption; |
45 | 47 | import com.oracle.truffle.api.CompilerDirectives;
|
46 |
| -import com.oracle.truffle.api.TruffleLanguage; |
47 | 48 | import com.oracle.truffle.api.frame.Frame;
|
48 | 49 | import com.oracle.truffle.api.frame.FrameDescriptor;
|
49 | 50 | import com.oracle.truffle.api.frame.FrameSlot;
|
50 | 51 | import com.oracle.truffle.api.frame.VirtualFrame;
|
51 | 52 | import com.oracle.truffle.api.nodes.ExplodeLoop;
|
52 | 53 |
|
53 | 54 | public abstract class PClosureRootNode extends PRootNode {
|
| 55 | + private static final PCell[] NO_CLOSURE = new PCell[0]; |
| 56 | + private final Assumption singleContextAssumption; |
54 | 57 | @CompilerDirectives.CompilationFinal(dimensions = 1) protected final FrameSlot[] freeVarSlots;
|
| 58 | + @CompilerDirectives.CompilationFinal(dimensions = 1) protected PCell[] closure; |
55 | 59 | private final int length;
|
56 | 60 |
|
57 |
| - protected PClosureRootNode(TruffleLanguage<?> language, FrameDescriptor frameDescriptor, FrameSlot[] freeVarSlots) { |
| 61 | + protected PClosureRootNode(PythonLanguage language, FrameDescriptor frameDescriptor, FrameSlot[] freeVarSlots) { |
58 | 62 | super(language, frameDescriptor);
|
| 63 | + this.singleContextAssumption = language.singleContextAssumption; |
59 | 64 | this.freeVarSlots = freeVarSlots;
|
60 | 65 | this.length = freeVarSlots != null ? freeVarSlots.length : 0;
|
61 | 66 | }
|
62 | 67 |
|
63 | 68 | protected void addClosureCellsToLocals(Frame frame) {
|
64 |
| - PCell[] closure = PArguments.getClosure(frame); |
65 |
| - if (closure != null) { |
| 69 | + PCell[] frameClosure = PArguments.getClosure(frame); |
| 70 | + if (frameClosure != null) { |
| 71 | + if (singleContextAssumption.isValid() && closure == null) { |
| 72 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 73 | + closure = frameClosure; |
| 74 | + } else if ((!singleContextAssumption.isValid() && closure != null && closure != NO_CLOSURE) || closure != frameClosure) { |
| 75 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 76 | + closure = NO_CLOSURE; |
| 77 | + } |
66 | 78 | assert freeVarSlots != null : "closure root node: the free var slots cannot be null when the closure is not null";
|
67 |
| - assert closure.length == freeVarSlots.length : "closure root node: the closure must have the same length as the free var slots array"; |
68 |
| - if (freeVarSlots.length < 32) { |
| 79 | + assert frameClosure.length == freeVarSlots.length : "closure root node: the closure must have the same length as the free var slots array"; |
| 80 | + if (closure != null && closure != NO_CLOSURE) { |
69 | 81 | addClosureCellsToLocalsExploded(frame, closure);
|
70 | 82 | } else {
|
71 |
| - addClosureCellsToLocalsLoop(frame, closure); |
| 83 | + if (freeVarSlots.length < 32) { |
| 84 | + addClosureCellsToLocalsExploded(frame, frameClosure); |
| 85 | + } else { |
| 86 | + addClosureCellsToLocalsLoop(frame, frameClosure); |
| 87 | + } |
72 | 88 | }
|
73 | 89 | }
|
74 | 90 | }
|
75 | 91 |
|
76 |
| - protected void addClosureCellsToLocalsLoop(Frame frame, PCell[] closure) { |
| 92 | + protected void addClosureCellsToLocalsLoop(Frame frame, PCell[] frameClosure) { |
77 | 93 | for (int i = 0; i < length; i++) {
|
78 |
| - frame.setObject(freeVarSlots[i], closure[i]); |
| 94 | + frame.setObject(freeVarSlots[i], frameClosure[i]); |
79 | 95 | }
|
80 | 96 | }
|
81 | 97 |
|
82 | 98 | @ExplodeLoop
|
83 |
| - protected void addClosureCellsToLocalsExploded(Frame frame, PCell[] closure) { |
| 99 | + protected void addClosureCellsToLocalsExploded(Frame frame, PCell[] frameClosure) { |
84 | 100 | for (int i = 0; i < length; i++) {
|
85 |
| - frame.setObject(freeVarSlots[i], closure[i]); |
| 101 | + frame.setObject(freeVarSlots[i], frameClosure[i]); |
86 | 102 | }
|
87 | 103 | }
|
88 | 104 |
|
|
0 commit comments