|
47 | 47 | import com.oracle.graal.python.nodes.PRootNode;
|
48 | 48 | import com.oracle.graal.python.nodes.frame.MaterializeFrameNode;
|
49 | 49 | import com.oracle.graal.python.nodes.frame.MaterializeFrameNodeGen;
|
| 50 | +import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode; |
50 | 51 | import com.oracle.graal.python.nodes.util.ExceptionStateNodes.GetCaughtExceptionNode;
|
51 | 52 | import com.oracle.graal.python.runtime.exception.PException;
|
52 | 53 | import com.oracle.truffle.api.CompilerDirectives;
|
| 54 | +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; |
53 | 55 | import com.oracle.truffle.api.RootCallTarget;
|
54 |
| -import com.oracle.truffle.api.Truffle; |
55 | 56 | import com.oracle.truffle.api.frame.Frame;
|
56 | 57 | import com.oracle.truffle.api.frame.FrameInstance;
|
57 | 58 | import com.oracle.truffle.api.frame.VirtualFrame;
|
@@ -127,6 +128,8 @@ public static final class CalleeContext extends Node {
|
127 | 128 |
|
128 | 129 | @Child private MaterializeFrameNode materializeNode;
|
129 | 130 |
|
| 131 | + @CompilationFinal private boolean firstRequest = true; |
| 132 | + |
130 | 133 | /**
|
131 | 134 | * Wrap the execution of a Python callee called from a Python frame.
|
132 | 135 | */
|
@@ -154,34 +157,31 @@ public void exit(VirtualFrame frame, PRootNode node) {
|
154 | 157 | if (info.isEscaped()) {
|
155 | 158 | // This assumption acts as our branch profile here
|
156 | 159 | PFrame.Reference callerInfo = PArguments.getCallerFrameInfo(frame);
|
157 |
| - if (!node.needsCallerFrame()) { |
158 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
159 |
| - node.setNeedsCallerFrame(); |
160 |
| - if (callerInfo == null) { |
161 |
| - // we didn't request the caller frame reference. now we need |
162 |
| - // it. |
| 160 | + if (callerInfo == null) { |
| 161 | + if (firstRequest) { |
| 162 | + // we didn't request the caller frame reference. now we need it. |
163 | 163 | CompilerDirectives.transferToInterpreterAndInvalidate();
|
164 |
| - FrameInstance callerFrameInstance = Truffle.getRuntime().getCallerFrame(); |
165 |
| - if (callerFrameInstance != null) { |
166 |
| - Frame callerFrame = callerFrameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY); |
167 |
| - if (PArguments.isPythonFrame(callerFrame)) { |
168 |
| - callerInfo = PArguments.getCurrentFrameInfo(callerFrame); |
169 |
| - } else { |
170 |
| - // TODO: frames: an assertion should be that this is one of our |
171 |
| - // entry point call nodes |
172 |
| - callerInfo = PFrame.Reference.EMPTY; |
173 |
| - } |
| 164 | + firstRequest = false; |
| 165 | + |
| 166 | + // n.b. We need to use 'ReadCallerFrameNode.getCallerFrame' instead of |
| 167 | + // 'Truffle.getRuntime().getCallerFrame()' because we still need to filter |
| 168 | + // internal frames. |
| 169 | + Frame callerFrame = ReadCallerFrameNode.getCallerFrame(info, FrameInstance.FrameAccess.READ_ONLY, true, 0); |
| 170 | + if (PArguments.isPythonFrame(callerFrame)) { |
| 171 | + callerInfo = PArguments.getCurrentFrameInfo(callerFrame); |
174 | 172 | } else {
|
| 173 | + // TODO: frames: an assertion should be that this is one of our |
| 174 | + // entry point call nodes |
175 | 175 | callerInfo = PFrame.Reference.EMPTY;
|
176 | 176 | }
|
177 |
| - } |
178 |
| - } else { |
179 |
| - // caller info was requested, it must be here if there is |
180 |
| - // any. If it isn't, we're in a top-frame. |
181 |
| - if (callerInfo == null) { |
| 177 | + } else { |
| 178 | + // caller info was requested, it must be here if there is |
| 179 | + // any. If it isn't, we're in a top-frame. |
| 180 | + assert node.needsCallerFrame(); |
182 | 181 | callerInfo = PFrame.Reference.EMPTY;
|
183 | 182 | }
|
184 | 183 | }
|
| 184 | + |
185 | 185 | // force the frame so that it can be accessed later
|
186 | 186 | node.getExitedEscapedWithoutFrameProfile().enter();
|
187 | 187 | ensureMaterializeNode().execute(frame, node, false, true);
|
|
0 commit comments