|
106 | 106 | import com.oracle.truffle.api.TruffleLanguage;
|
107 | 107 | import com.oracle.truffle.api.TruffleLanguage.Env;
|
108 | 108 | import com.oracle.truffle.api.TruffleLogger;
|
109 |
| -import com.oracle.truffle.api.instrumentation.AllocationReporter; |
110 | 109 | import com.oracle.truffle.api.TruffleSafepoint;
|
| 110 | +import com.oracle.truffle.api.dsl.Bind; |
| 111 | +import com.oracle.truffle.api.dsl.Cached.Shared; |
| 112 | +import com.oracle.truffle.api.dsl.CachedContext; |
| 113 | +import com.oracle.truffle.api.dsl.GenerateUncached; |
| 114 | +import com.oracle.truffle.api.dsl.Specialization; |
| 115 | +import com.oracle.truffle.api.instrumentation.AllocationReporter; |
111 | 116 | import com.oracle.truffle.api.interop.ExceptionType;
|
112 | 117 | import com.oracle.truffle.api.interop.InteropLibrary;
|
113 | 118 | import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
@@ -202,6 +207,20 @@ public void setCaughtException(PException caughtException) {
|
202 | 207 | this.caughtException = caughtException;
|
203 | 208 | }
|
204 | 209 |
|
| 210 | + public void setTopFrameInfo(PFrame.Reference topframeref) { |
| 211 | + this.topframeref = topframeref; |
| 212 | + } |
| 213 | + |
| 214 | + public PFrame.Reference popTopFrameInfo() { |
| 215 | + PFrame.Reference ref = topframeref; |
| 216 | + topframeref = null; |
| 217 | + return ref; |
| 218 | + } |
| 219 | + |
| 220 | + public PFrame.Reference peekTopFrameInfo() { |
| 221 | + return topframeref; |
| 222 | + } |
| 223 | + |
205 | 224 | public PDict getDict() {
|
206 | 225 | return dict;
|
207 | 226 | }
|
@@ -246,6 +265,77 @@ private static final class AtExitHook {
|
246 | 265 | }
|
247 | 266 | }
|
248 | 267 |
|
| 268 | + @GenerateUncached |
| 269 | + public abstract static class GetThreadStateNode extends Node { |
| 270 | + |
| 271 | + public abstract PythonThreadState execute(PythonContext context); |
| 272 | + |
| 273 | + public final PythonThreadState execute() { |
| 274 | + return execute(null); |
| 275 | + } |
| 276 | + |
| 277 | + public final PException getCaughtException(PythonContext context) { |
| 278 | + return execute(context).caughtException; |
| 279 | + } |
| 280 | + |
| 281 | + public final PException getCaughtException() { |
| 282 | + return execute(null).caughtException; |
| 283 | + } |
| 284 | + |
| 285 | + public final void setTopFrameInfo(PythonContext context, PFrame.Reference topframeref) { |
| 286 | + execute(context).topframeref = topframeref; |
| 287 | + } |
| 288 | + |
| 289 | + public final void setTopFrameInfo(PFrame.Reference topframeref) { |
| 290 | + execute(null).topframeref = topframeref; |
| 291 | + } |
| 292 | + |
| 293 | + public final PFrame.Reference getTopFrameInfo(PythonContext context) { |
| 294 | + return execute(context).topframeref; |
| 295 | + } |
| 296 | + |
| 297 | + public final PFrame.Reference getTopFrameInfo() { |
| 298 | + return execute(null).topframeref; |
| 299 | + } |
| 300 | + |
| 301 | + @Specialization(guards = {"noContext == null", "!curThreadState.isShuttingDown()"}) |
| 302 | + @SuppressWarnings("unused") |
| 303 | + static PythonThreadState doNoShutdown(PythonContext noContext, |
| 304 | + @Shared("context") @CachedContext(PythonLanguage.class) PythonContext context, |
| 305 | + @Bind("getThreadState(context)") PythonThreadState curThreadState) { |
| 306 | + return curThreadState; |
| 307 | + } |
| 308 | + |
| 309 | + @Specialization(guards = {"noContext == null"}, replaces = "doNoShutdown") |
| 310 | + static PythonThreadState doGeneric(@SuppressWarnings("unused") PythonContext noContext, |
| 311 | + @Shared("context") @CachedContext(PythonLanguage.class) PythonContext context) { |
| 312 | + PythonThreadState curThreadState = context.threadState.get(context.env.getContext()); |
| 313 | + if (curThreadState.isShuttingDown()) { |
| 314 | + context.killThread(); |
| 315 | + } |
| 316 | + return curThreadState; |
| 317 | + } |
| 318 | + |
| 319 | + @Specialization(guards = "!curThreadState.isShuttingDown()") |
| 320 | + static PythonThreadState doNoShutdownWithContext(@SuppressWarnings("unused") PythonContext context, |
| 321 | + @Bind("getThreadState(context)") PythonThreadState curThreadState) { |
| 322 | + return curThreadState; |
| 323 | + } |
| 324 | + |
| 325 | + @Specialization(replaces = "doNoShutdownWithContext") |
| 326 | + static PythonThreadState doGenericWithContext(PythonContext context) { |
| 327 | + PythonThreadState curThreadState = context.threadState.get(context.env.getContext()); |
| 328 | + if (curThreadState.isShuttingDown()) { |
| 329 | + context.killThread(); |
| 330 | + } |
| 331 | + return curThreadState; |
| 332 | + } |
| 333 | + |
| 334 | + static PythonThreadState getThreadState(PythonContext context) { |
| 335 | + return context.threadState.get(context.env.getContext()); |
| 336 | + } |
| 337 | + } |
| 338 | + |
249 | 339 | static final String PREFIX = "/";
|
250 | 340 | static final String LIB_PYTHON_3 = "/lib-python/3";
|
251 | 341 | static final String LIB_GRAALPYTHON = "/lib-graalpython";
|
@@ -504,10 +594,7 @@ public void setTopFrameInfo(PFrame.Reference topframeref) {
|
504 | 594 | }
|
505 | 595 |
|
506 | 596 | public PFrame.Reference popTopFrameInfo() {
|
507 |
| - PythonThreadState ts = getThreadState(); |
508 |
| - PFrame.Reference ref = ts.topframeref; |
509 |
| - ts.topframeref = null; |
510 |
| - return ref; |
| 597 | + return getThreadState().popTopFrameInfo(); |
511 | 598 | }
|
512 | 599 |
|
513 | 600 | public PFrame.Reference peekTopFrameInfo() {
|
@@ -1266,15 +1353,20 @@ public Thread[] getThreads() {
|
1266 | 1353 | public PythonThreadState getThreadState() {
|
1267 | 1354 | PythonThreadState curThreadState = threadState.get();
|
1268 | 1355 | if (CompilerDirectives.injectBranchProbability(CompilerDirectives.SLOWPATH_PROBABILITY, curThreadState.isShuttingDown())) {
|
1269 |
| - // we're shutting down, just release and die |
1270 |
| - if (ownsGil()) { |
1271 |
| - releaseGil(); |
1272 |
| - } |
1273 |
| - throw new PythonThreadKillException(); |
| 1356 | + killThread(); |
1274 | 1357 | }
|
1275 | 1358 | return curThreadState;
|
1276 | 1359 | }
|
1277 | 1360 |
|
| 1361 | + private void killThread() { |
| 1362 | + // we're shutting down, just release and die |
| 1363 | + CompilerDirectives.transferToInterpreter(); |
| 1364 | + if (ownsGil()) { |
| 1365 | + releaseGil(); |
| 1366 | + } |
| 1367 | + throw new PythonThreadKillException(); |
| 1368 | + } |
| 1369 | + |
1278 | 1370 | private void applyToAllThreadStates(Consumer<PythonThreadState> action) {
|
1279 | 1371 | if (language.singleThreadedAssumption.isValid()) {
|
1280 | 1372 | action.accept(threadState.get());
|
|
0 commit comments