Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-39984: Add PyInterpreterState.ceval #19047

Merged
merged 1 commit into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ struct _frame;

#include "pycore_pystate.h" /* PyInterpreterState.eval_frame */

PyAPI_FUNC(void) _Py_FinishPendingCalls(PyThreadState *tstate);
PyAPI_FUNC(void) _PyEval_Initialize(struct _ceval_runtime_state *);
PyAPI_FUNC(void) _PyEval_FiniThreads(
extern void _Py_FinishPendingCalls(PyThreadState *tstate);
extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *);
extern void _PyEval_InitState(struct _ceval_state *);
extern void _PyEval_FiniThreads(
struct _ceval_runtime_state *ceval);
PyAPI_FUNC(void) _PyEval_SignalReceived(
struct _ceval_runtime_state *ceval);
Expand Down
16 changes: 10 additions & 6 deletions Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ struct _pending_calls {

struct _ceval_runtime_state {
int recursion_limit;
/* Records whether tracing is on for any thread. Counts the number
of threads for which tstate->c_tracefunc is non-NULL, so if the
value is 0, we know we don't have to check this thread's
c_tracefunc. This speeds up the if statement in
PyEval_EvalFrameEx() after fast_next_opcode. */
int tracing_possible;
/* This single variable consolidates all requests to break out of
the fast path in the eval loop. */
_Py_atomic_int eval_breaker;
Expand All @@ -52,6 +46,15 @@ struct _ceval_runtime_state {
struct _gil_runtime_state gil;
};

struct _ceval_state {
/* Records whether tracing is on for any thread. Counts the number
of threads for which tstate->c_tracefunc is non-NULL, so if the
value is 0, we know we don't have to check this thread's
c_tracefunc. This speeds up the if statement in
_PyEval_EvalFrameDefault() after fast_next_opcode. */
int tracing_possible;
};

/* interpreter state */

#define _PY_NSMALLPOSINTS 257
Expand All @@ -75,6 +78,7 @@ struct _is {

int finalizing;

struct _ceval_state ceval;
struct _gc_runtime_state gc;

PyObject *modules;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
subinterpreters: Move ``_PyRuntimeState.ceval.tracing_possible`` to
``PyInterpreterState.ceval.tracing_possible``: each interpreter now has its own
variable.
25 changes: 16 additions & 9 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,11 +638,17 @@ Py_MakePendingCalls(void)
int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;

void
_PyEval_Initialize(struct _ceval_runtime_state *state)
_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval)
{
state->recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
ceval->recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
_Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
_gil_initialize(&state->gil);
_gil_initialize(&ceval->gil);
}

void
_PyEval_InitState(struct _ceval_state *ceval)
{
/* PyInterpreterState_New() initializes ceval to zero */
}

int
Expand All @@ -657,7 +663,7 @@ Py_SetRecursionLimit(int new_limit)
{
struct _ceval_runtime_state *ceval = &_PyRuntime.ceval;
ceval->recursion_limit = new_limit;
_Py_CheckRecursionLimit = ceval->recursion_limit;
_Py_CheckRecursionLimit = new_limit;
}

/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
Expand Down Expand Up @@ -753,6 +759,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
PyObject *retval = NULL; /* Return value */
_PyRuntimeState * const runtime = &_PyRuntime;
struct _ceval_runtime_state * const ceval = &runtime->ceval;
struct _ceval_state * const ceval2 = &tstate->interp->ceval;
_Py_atomic_int * const eval_breaker = &ceval->eval_breaker;
PyCodeObject *co;

Expand Down Expand Up @@ -841,7 +848,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
#ifdef LLTRACE
#define FAST_DISPATCH() \
{ \
if (!lltrace && !_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \
if (!lltrace && !_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \
f->f_lasti = INSTR_OFFSET(); \
NEXTOPARG(); \
goto *opcode_targets[opcode]; \
Expand All @@ -851,7 +858,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
#else
#define FAST_DISPATCH() \
{ \
if (!_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \
if (!_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \
f->f_lasti = INSTR_OFFSET(); \
NEXTOPARG(); \
goto *opcode_targets[opcode]; \
Expand Down Expand Up @@ -1268,7 +1275,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)

/* line-by-line tracing support */

if (_Py_TracingPossible(ceval) &&
if (_Py_TracingPossible(ceval2) &&
tstate->c_tracefunc != NULL && !tstate->tracing) {
int err;
/* see maybe_call_line_trace
Expand Down Expand Up @@ -3647,7 +3654,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
PUSH(val);
PUSH(exc);
JUMPTO(handler);
if (_Py_TracingPossible(ceval)) {
if (_Py_TracingPossible(ceval2)) {
int needs_new_execution_window = (f->f_lasti < instr_lb || f->f_lasti >= instr_ub);
int needs_line_update = (f->f_lasti == instr_lb || f->f_lasti < instr_prev);
/* Make sure that we trace line after exception if we are in a new execution
Expand Down Expand Up @@ -4639,7 +4646,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
return -1;
}

struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval;
struct _ceval_state *ceval = &tstate->interp->ceval;
PyObject *traceobj = tstate->c_traceobj;
ceval->tracing_possible += (func != NULL) - (tstate->c_tracefunc != NULL);

Expand Down
3 changes: 2 additions & 1 deletion Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
runtime->open_code_userdata = open_code_userdata;
runtime->audit_hook_head = audit_hook_head;

_PyEval_Initialize(&runtime->ceval);
_PyEval_InitRuntimeState(&runtime->ceval);

PyPreConfig_InitPythonConfig(&runtime->preconfig);

Expand Down Expand Up @@ -213,6 +213,7 @@ PyInterpreterState_New(void)
_PyRuntimeState *runtime = &_PyRuntime;
interp->runtime = runtime;

_PyEval_InitState(&interp->ceval);
_PyGC_InitState(&interp->gc);
PyConfig_InitPythonConfig(&interp->config);

Expand Down