bpo-39984: Add PyInterpreterState.ceval (GH-19047)
subinterpreters: Move _PyRuntimeState.ceval.tracing_possible to PyInterpreterState.ceval.tracing_possible: each interpreter now has its own variable. Changes: * Add _ceval_state structure. * Add PyInterpreterState.ceval field. * _PyEval_EvalFrameDefault(): add ceval2 variable (struct _ceval_state*). * Rename _PyEval_Initialize() to _PyEval_InitRuntimeState(). * Add _PyEval_InitState(). * Don't export internal _Py_FinishPendingCalls() and _PyEval_FiniThreads() functions anymore.
This commit is contained in:
parent
514c469719
commit
dab8423d22
|
@ -15,9 +15,10 @@ struct _frame;
|
||||||
|
|
||||||
#include "pycore_pystate.h" /* PyInterpreterState.eval_frame */
|
#include "pycore_pystate.h" /* PyInterpreterState.eval_frame */
|
||||||
|
|
||||||
PyAPI_FUNC(void) _Py_FinishPendingCalls(PyThreadState *tstate);
|
extern void _Py_FinishPendingCalls(PyThreadState *tstate);
|
||||||
PyAPI_FUNC(void) _PyEval_Initialize(struct _ceval_runtime_state *);
|
extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *);
|
||||||
PyAPI_FUNC(void) _PyEval_FiniThreads(
|
extern void _PyEval_InitState(struct _ceval_state *);
|
||||||
|
extern void _PyEval_FiniThreads(
|
||||||
struct _ceval_runtime_state *ceval);
|
struct _ceval_runtime_state *ceval);
|
||||||
PyAPI_FUNC(void) _PyEval_SignalReceived(
|
PyAPI_FUNC(void) _PyEval_SignalReceived(
|
||||||
struct _ceval_runtime_state *ceval);
|
struct _ceval_runtime_state *ceval);
|
||||||
|
|
|
@ -35,12 +35,6 @@ struct _pending_calls {
|
||||||
|
|
||||||
struct _ceval_runtime_state {
|
struct _ceval_runtime_state {
|
||||||
int recursion_limit;
|
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
|
/* This single variable consolidates all requests to break out of
|
||||||
the fast path in the eval loop. */
|
the fast path in the eval loop. */
|
||||||
_Py_atomic_int eval_breaker;
|
_Py_atomic_int eval_breaker;
|
||||||
|
@ -52,6 +46,15 @@ struct _ceval_runtime_state {
|
||||||
struct _gil_runtime_state gil;
|
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 */
|
/* interpreter state */
|
||||||
|
|
||||||
#define _PY_NSMALLPOSINTS 257
|
#define _PY_NSMALLPOSINTS 257
|
||||||
|
@ -75,6 +78,7 @@ struct _is {
|
||||||
|
|
||||||
int finalizing;
|
int finalizing;
|
||||||
|
|
||||||
|
struct _ceval_state ceval;
|
||||||
struct _gc_runtime_state gc;
|
struct _gc_runtime_state gc;
|
||||||
|
|
||||||
PyObject *modules;
|
PyObject *modules;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
subinterpreters: Move ``_PyRuntimeState.ceval.tracing_possible`` to
|
||||||
|
``PyInterpreterState.ceval.tracing_possible``: each interpreter now has its own
|
||||||
|
variable.
|
|
@ -638,11 +638,17 @@ Py_MakePendingCalls(void)
|
||||||
int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
|
int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
|
||||||
|
|
||||||
void
|
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;
|
_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
|
int
|
||||||
|
@ -657,7 +663,7 @@ Py_SetRecursionLimit(int new_limit)
|
||||||
{
|
{
|
||||||
struct _ceval_runtime_state *ceval = &_PyRuntime.ceval;
|
struct _ceval_runtime_state *ceval = &_PyRuntime.ceval;
|
||||||
ceval->recursion_limit = new_limit;
|
ceval->recursion_limit = new_limit;
|
||||||
_Py_CheckRecursionLimit = ceval->recursion_limit;
|
_Py_CheckRecursionLimit = new_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
|
/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
|
||||||
|
@ -753,6 +759,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
|
||||||
PyObject *retval = NULL; /* Return value */
|
PyObject *retval = NULL; /* Return value */
|
||||||
_PyRuntimeState * const runtime = &_PyRuntime;
|
_PyRuntimeState * const runtime = &_PyRuntime;
|
||||||
struct _ceval_runtime_state * const ceval = &runtime->ceval;
|
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;
|
_Py_atomic_int * const eval_breaker = &ceval->eval_breaker;
|
||||||
PyCodeObject *co;
|
PyCodeObject *co;
|
||||||
|
|
||||||
|
@ -841,7 +848,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
|
||||||
#ifdef LLTRACE
|
#ifdef LLTRACE
|
||||||
#define FAST_DISPATCH() \
|
#define FAST_DISPATCH() \
|
||||||
{ \
|
{ \
|
||||||
if (!lltrace && !_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \
|
if (!lltrace && !_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \
|
||||||
f->f_lasti = INSTR_OFFSET(); \
|
f->f_lasti = INSTR_OFFSET(); \
|
||||||
NEXTOPARG(); \
|
NEXTOPARG(); \
|
||||||
goto *opcode_targets[opcode]; \
|
goto *opcode_targets[opcode]; \
|
||||||
|
@ -851,7 +858,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
|
||||||
#else
|
#else
|
||||||
#define FAST_DISPATCH() \
|
#define FAST_DISPATCH() \
|
||||||
{ \
|
{ \
|
||||||
if (!_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \
|
if (!_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \
|
||||||
f->f_lasti = INSTR_OFFSET(); \
|
f->f_lasti = INSTR_OFFSET(); \
|
||||||
NEXTOPARG(); \
|
NEXTOPARG(); \
|
||||||
goto *opcode_targets[opcode]; \
|
goto *opcode_targets[opcode]; \
|
||||||
|
@ -1268,7 +1275,7 @@ main_loop:
|
||||||
|
|
||||||
/* line-by-line tracing support */
|
/* line-by-line tracing support */
|
||||||
|
|
||||||
if (_Py_TracingPossible(ceval) &&
|
if (_Py_TracingPossible(ceval2) &&
|
||||||
tstate->c_tracefunc != NULL && !tstate->tracing) {
|
tstate->c_tracefunc != NULL && !tstate->tracing) {
|
||||||
int err;
|
int err;
|
||||||
/* see maybe_call_line_trace
|
/* see maybe_call_line_trace
|
||||||
|
@ -3647,7 +3654,7 @@ exception_unwind:
|
||||||
PUSH(val);
|
PUSH(val);
|
||||||
PUSH(exc);
|
PUSH(exc);
|
||||||
JUMPTO(handler);
|
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_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);
|
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
|
/* Make sure that we trace line after exception if we are in a new execution
|
||||||
|
@ -4639,7 +4646,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval;
|
struct _ceval_state *ceval = &tstate->interp->ceval;
|
||||||
PyObject *traceobj = tstate->c_traceobj;
|
PyObject *traceobj = tstate->c_traceobj;
|
||||||
ceval->tracing_possible += (func != NULL) - (tstate->c_tracefunc != NULL);
|
ceval->tracing_possible += (func != NULL) - (tstate->c_tracefunc != NULL);
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
|
||||||
runtime->open_code_userdata = open_code_userdata;
|
runtime->open_code_userdata = open_code_userdata;
|
||||||
runtime->audit_hook_head = audit_hook_head;
|
runtime->audit_hook_head = audit_hook_head;
|
||||||
|
|
||||||
_PyEval_Initialize(&runtime->ceval);
|
_PyEval_InitRuntimeState(&runtime->ceval);
|
||||||
|
|
||||||
PyPreConfig_InitPythonConfig(&runtime->preconfig);
|
PyPreConfig_InitPythonConfig(&runtime->preconfig);
|
||||||
|
|
||||||
|
@ -213,6 +213,7 @@ PyInterpreterState_New(void)
|
||||||
_PyRuntimeState *runtime = &_PyRuntime;
|
_PyRuntimeState *runtime = &_PyRuntime;
|
||||||
interp->runtime = runtime;
|
interp->runtime = runtime;
|
||||||
|
|
||||||
|
_PyEval_InitState(&interp->ceval);
|
||||||
_PyGC_InitState(&interp->gc);
|
_PyGC_InitState(&interp->gc);
|
||||||
PyConfig_InitPythonConfig(&interp->config);
|
PyConfig_InitPythonConfig(&interp->config);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue