Skip to content

Commit 760ba50

Browse files
committed
Introduce GetThreadStateNode
1 parent 94c8951 commit 760ba50

File tree

2 files changed

+130
-18
lines changed

2 files changed

+130
-18
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode;
5454
import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode.FrameSelector;
5555
import com.oracle.graal.python.nodes.util.ExceptionStateNodes.GetCaughtExceptionNode;
56+
import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
5657
import com.oracle.graal.python.runtime.exception.PException;
5758
import com.oracle.truffle.api.CompilerAsserts;
5859
import com.oracle.truffle.api.CompilerDirectives;
@@ -351,23 +352,33 @@ public abstract static class IndirectCallContext {
351352
* </p>
352353
*/
353354
public static Object enter(VirtualFrame frame, PythonContext context, IndirectCallNode callNode) {
354-
if (frame == null || context == null || callNode == null) {
355+
if (context != null) {
356+
return enter(frame, context.getThreadState(), callNode);
357+
}
358+
return null;
359+
}
360+
361+
/**
362+
* @see #enter(VirtualFrame, PythonContext, IndirectCallNode)
363+
*/
364+
public static Object enter(VirtualFrame frame, PythonThreadState pythonThreadState, IndirectCallNode callNode) {
365+
if (frame == null || callNode == null) {
355366
return null;
356367
}
357368
PFrame.Reference info = null;
358369
if (callNode.calleeNeedsCallerFrame()) {
359-
PFrame.Reference prev = context.popTopFrameInfo();
370+
PFrame.Reference prev = pythonThreadState.popTopFrameInfo();
360371
assert prev == null : "trying to call from Python to a foreign function, but we didn't clear the topframeref. " +
361372
"This indicates that a call into Python code happened without a proper enter through ForeignToPythonCallContext";
362373
info = PArguments.getCurrentFrameInfo(frame);
363374
info.setCallNode((Node) callNode);
364-
context.setTopFrameInfo(info);
375+
pythonThreadState.setTopFrameInfo(info);
365376
}
366377
PException curExc = null;
367378
if (callNode.calleeNeedsExceptionState()) {
368379
PException exceptionState = PArguments.getException(frame);
369-
curExc = context.getCaughtException();
370-
context.setCaughtException(exceptionState);
380+
curExc = pythonThreadState.getCaughtException();
381+
pythonThreadState.setCaughtException(exceptionState);
371382
}
372383

373384
if (curExc == null && info == null) {
@@ -381,15 +392,24 @@ public static Object enter(VirtualFrame frame, PythonContext context, IndirectCa
381392
* Cleanup after a call without frame. For more details, see {@link #enter}.
382393
*/
383394
public static void exit(VirtualFrame frame, PythonContext context, Object savedState) {
384-
if (frame == null || context == null || savedState == null) {
395+
if (context != null) {
396+
exit(frame, context.getThreadState(), savedState);
397+
}
398+
}
399+
400+
/**
401+
* @see #exit(VirtualFrame, PythonContext, Object)
402+
*/
403+
public static void exit(VirtualFrame frame, PythonThreadState pythonThreadState, Object savedState) {
404+
if (frame == null || savedState == null) {
385405
return;
386406
}
387407
IndirectCallState state = (IndirectCallState) savedState;
388408
if (state.info != null) {
389-
context.popTopFrameInfo();
409+
pythonThreadState.popTopFrameInfo();
390410
}
391411
if (state.curExc != null) {
392-
context.setCaughtException(state.curExc);
412+
pythonThreadState.setCaughtException(state.curExc);
393413
}
394414
}
395415
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java

Lines changed: 102 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,13 @@
106106
import com.oracle.truffle.api.TruffleLanguage;
107107
import com.oracle.truffle.api.TruffleLanguage.Env;
108108
import com.oracle.truffle.api.TruffleLogger;
109-
import com.oracle.truffle.api.instrumentation.AllocationReporter;
110109
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;
111116
import com.oracle.truffle.api.interop.ExceptionType;
112117
import com.oracle.truffle.api.interop.InteropLibrary;
113118
import com.oracle.truffle.api.interop.UnsupportedMessageException;
@@ -202,6 +207,20 @@ public void setCaughtException(PException caughtException) {
202207
this.caughtException = caughtException;
203208
}
204209

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+
205224
public PDict getDict() {
206225
return dict;
207226
}
@@ -246,6 +265,77 @@ private static final class AtExitHook {
246265
}
247266
}
248267

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+
249339
static final String PREFIX = "/";
250340
static final String LIB_PYTHON_3 = "/lib-python/3";
251341
static final String LIB_GRAALPYTHON = "/lib-graalpython";
@@ -504,10 +594,7 @@ public void setTopFrameInfo(PFrame.Reference topframeref) {
504594
}
505595

506596
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();
511598
}
512599

513600
public PFrame.Reference peekTopFrameInfo() {
@@ -1266,15 +1353,20 @@ public Thread[] getThreads() {
12661353
public PythonThreadState getThreadState() {
12671354
PythonThreadState curThreadState = threadState.get();
12681355
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();
12741357
}
12751358
return curThreadState;
12761359
}
12771360

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+
12781370
private void applyToAllThreadStates(Consumer<PythonThreadState> action) {
12791371
if (language.singleThreadedAssumption.isValid()) {
12801372
action.accept(threadState.get());

0 commit comments

Comments
 (0)