From 1bcc32f0620d2e99649a6d423284d9496b7b3548 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 10 Jun 2020 20:08:26 +0200 Subject: [PATCH] bpo-39465: Use _PyInterpreterState_GET() (GH-20788) Replace _PyThreadState_GET() with _PyInterpreterState_GET() in: * get_small_int() * gcmodule.c: add also get_gc_state() function * _PyTrash_deposit_object() * _PyTrash_destroy_chain() * warnings_get_state() * Py_GetRecursionLimit() Cleanup listnode.c: add 'parser' variable. --- Include/internal/pycore_interp.h | 14 ++++---- Modules/gcmodule.c | 57 ++++++++++++++------------------ Objects/longobject.c | 4 +-- Objects/object.c | 8 ++--- Parser/listnode.c | 18 +++++----- Python/_warnings.c | 12 +++---- Python/ceval.c | 4 +-- 7 files changed, 55 insertions(+), 62 deletions(-) diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 4f811023f7a..981b73340b7 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -13,7 +13,12 @@ extern "C" { #include "pycore_gc.h" /* struct _gc_runtime_state */ #include "pycore_warnings.h" /* struct _warnings_runtime_state */ -/* ceval state */ +struct _Py_parser_state { + struct { + int level; + int atbol; + } listnode; +}; struct _pending_calls { PyThread_type_lock lock; @@ -209,12 +214,7 @@ struct _is { PyObject *audit_hooks; - struct { - struct { - int level; - int atbol; - } listnode; - } parser; + struct _Py_parser_state parser; #if _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS > 0 /* Small integers are preallocated in this array so that they diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index b3bcc8aa426..444db7b03b4 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -128,6 +128,15 @@ gc_decref(PyGC_Head *g) #define GEN_HEAD(gcstate, n) (&(gcstate)->generations[n].head) + +static GCState * +get_gc_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->gc; +} + + void _PyGC_InitState(GCState *gcstate) { @@ -1465,8 +1474,7 @@ static PyObject * gc_enable_impl(PyObject *module) /*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); gcstate->enabled = 1; Py_RETURN_NONE; } @@ -1481,8 +1489,7 @@ static PyObject * gc_disable_impl(PyObject *module) /*[clinic end generated code: output=97d1030f7aa9d279 input=8c2e5a14e800d83b]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); gcstate->enabled = 0; Py_RETURN_NONE; } @@ -1497,8 +1504,7 @@ static int gc_isenabled_impl(PyObject *module) /*[clinic end generated code: output=1874298331c49130 input=30005e0422373b31]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return gcstate->enabled; } @@ -1563,8 +1569,7 @@ static PyObject * gc_set_debug_impl(PyObject *module, int flags) /*[clinic end generated code: output=7c8366575486b228 input=5e5ce15e84fbed15]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); gcstate->debug = flags; Py_RETURN_NONE; } @@ -1579,8 +1584,7 @@ static int gc_get_debug_impl(PyObject *module) /*[clinic end generated code: output=91242f3506cd1e50 input=91a101e1c3b98366]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return gcstate->debug; } @@ -1593,8 +1597,7 @@ PyDoc_STRVAR(gc_set_thresh__doc__, static PyObject * gc_set_threshold(PyObject *self, PyObject *args) { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &gcstate->generations[0].threshold, &gcstate->generations[1].threshold, @@ -1617,8 +1620,7 @@ static PyObject * gc_get_threshold_impl(PyObject *module) /*[clinic end generated code: output=7902bc9f41ecbbd8 input=286d79918034d6e6]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return Py_BuildValue("(iii)", gcstate->generations[0].threshold, gcstate->generations[1].threshold, @@ -1635,8 +1637,7 @@ static PyObject * gc_get_count_impl(PyObject *module) /*[clinic end generated code: output=354012e67b16398f input=a392794a08251751]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return Py_BuildValue("(iii)", gcstate->generations[0].count, gcstate->generations[1].count, @@ -1679,15 +1680,13 @@ Return the list of objects that directly refer to any of objs."); static PyObject * gc_get_referrers(PyObject *self, PyObject *args) { - PyThreadState *tstate = _PyThreadState_GET(); - int i; PyObject *result = PyList_New(0); if (!result) { return NULL; } - GCState *gcstate = &tstate->interp->gc; - for (i = 0; i < NUM_GENERATIONS; i++) { + GCState *gcstate = get_gc_state(); + for (int i = 0; i < NUM_GENERATIONS; i++) { if (!(gc_referrers_for(args, GEN_HEAD(gcstate, i), result))) { Py_DECREF(result); return NULL; @@ -1806,11 +1805,10 @@ gc_get_stats_impl(PyObject *module) { int i; struct gc_generation_stats stats[NUM_GENERATIONS], *st; - PyThreadState *tstate = _PyThreadState_GET(); /* To get consistent values despite allocations while constructing the result list, we use a snapshot of the running stats. */ - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); for (i = 0; i < NUM_GENERATIONS; i++) { stats[i] = gcstate->generation_stats[i]; } @@ -1901,8 +1899,7 @@ static PyObject * gc_freeze_impl(PyObject *module) /*[clinic end generated code: output=502159d9cdc4c139 input=b602b16ac5febbe5]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); for (int i = 0; i < NUM_GENERATIONS; ++i) { gc_list_merge(GEN_HEAD(gcstate, i), &gcstate->permanent_generation.head); gcstate->generations[i].count = 0; @@ -1922,8 +1919,7 @@ static PyObject * gc_unfreeze_impl(PyObject *module) /*[clinic end generated code: output=1c15f2043b25e169 input=2dd52b170f4cef6c]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); gc_list_merge(&gcstate->permanent_generation.head, GEN_HEAD(gcstate, NUM_GENERATIONS-1)); Py_RETURN_NONE; @@ -1939,8 +1935,7 @@ static Py_ssize_t gc_get_freeze_count_impl(PyObject *module) /*[clinic end generated code: output=61cbd9f43aa032e1 input=45ffbc65cfe2a6ed]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return gc_list_size(&gcstate->permanent_generation.head); } @@ -2006,8 +2001,7 @@ static struct PyModuleDef gcmodule = { PyMODINIT_FUNC PyInit_gc(void) { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); PyObject *m = PyModule_Create(&gcmodule); @@ -2316,8 +2310,7 @@ PyObject_GC_Del(void *op) if (_PyObject_GC_IS_TRACKED(op)) { gc_list_remove(g); } - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); if (gcstate->generations[0].count > 0) { gcstate->generations[0].count--; } diff --git a/Objects/longobject.c b/Objects/longobject.c index ce10c4f6658..dead3e30694 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -41,8 +41,8 @@ static PyObject * get_small_int(sdigit ival) { assert(IS_SMALL_INT(ival)); - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *v = (PyObject*)tstate->interp->small_ints[ival + NSMALLNEGINTS]; + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyObject *v = (PyObject*)interp->small_ints[ival + NSMALLNEGINTS]; Py_INCREF(v); return v; } diff --git a/Objects/object.c b/Objects/object.c index 10cbd1b7c16..0ab5de28499 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2029,8 +2029,8 @@ finally: void _PyTrash_deposit_object(PyObject *op) { - PyThreadState *tstate = _PyThreadState_GET(); - struct _gc_runtime_state *gcstate = &tstate->interp->gc; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _gc_runtime_state *gcstate = &interp->gc; _PyObject_ASSERT(op, _PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); @@ -2057,8 +2057,8 @@ _PyTrash_thread_deposit_object(PyObject *op) void _PyTrash_destroy_chain(void) { - PyThreadState *tstate = _PyThreadState_GET(); - struct _gc_runtime_state *gcstate = &tstate->interp->gc; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _gc_runtime_state *gcstate = &interp->gc; while (gcstate->trash_delete_later) { PyObject *op = gcstate->trash_delete_later; diff --git a/Parser/listnode.c b/Parser/listnode.c index c806b98e48c..41e7a033a1f 100644 --- a/Parser/listnode.c +++ b/Parser/listnode.c @@ -30,8 +30,6 @@ listnode(FILE *fp, node *n) static void list1node(FILE *fp, node *n) { - PyInterpreterState *interp; - if (n == NULL) return; if (ISNONTERMINAL(TYPE(n))) { @@ -40,26 +38,28 @@ list1node(FILE *fp, node *n) list1node(fp, CHILD(n, i)); } else if (ISTERMINAL(TYPE(n))) { - interp = _PyInterpreterState_GET(); + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_parser_state *parser = &interp->parser; switch (TYPE(n)) { case INDENT: - interp->parser.listnode.level++; + parser->listnode.level++; break; case DEDENT: - interp->parser.listnode.level--; + parser->listnode.level--; break; default: - if (interp->parser.listnode.atbol) { + if (parser->listnode.atbol) { int i; - for (i = 0; i < interp->parser.listnode.level; ++i) + for (i = 0; i < parser->listnode.level; ++i) { fprintf(fp, "\t"); - interp->parser.listnode.atbol = 0; + } + parser->listnode.atbol = 0; } if (TYPE(n) == NEWLINE) { if (STR(n) != NULL) fprintf(fp, "%s", STR(n)); fprintf(fp, "\n"); - interp->parser.listnode.atbol = 1; + parser->listnode.atbol = 1; } else fprintf(fp, "%s ", STR(n)); diff --git a/Python/_warnings.c b/Python/_warnings.c index 4d65bb30c8e..86bbfa1c8db 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -32,14 +32,14 @@ _Py_IDENTIFIER(__name__); static WarningsState * warnings_get_state(void) { - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "warnings_get_state: could not identify " - "current interpreter"); + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (interp == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "warnings_get_state: could not identify " + "current interpreter"); return NULL; } - return &tstate->interp->warnings; + return &interp->warnings; } /* Clear the given warnings module state. */ diff --git a/Python/ceval.c b/Python/ceval.c index d1d07793185..9f2cbb06e60 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -788,8 +788,8 @@ _PyEval_FiniState(struct _ceval_state *ceval) int Py_GetRecursionLimit(void) { - PyThreadState *tstate = _PyThreadState_GET(); - return tstate->interp->ceval.recursion_limit; + PyInterpreterState *interp = _PyInterpreterState_GET(); + return interp->ceval.recursion_limit; } void