|
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