diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index ba6636d7f8cfc4..46555218bc5eaa 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -38,7 +38,7 @@ static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, filename, lineno, "_PyObject_GC_TRACK"); PyThreadState *tstate = _PyThreadState_GET(); - PyGC_Head *generation0 = tstate->interp->gc.generation0; + PyGC_Head *generation0 = tstate->interp->runtime->gc.generation0; PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); _PyGCHead_SET_NEXT(last, gc); _PyGCHead_SET_PREV(gc, last); diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index a4e972068348c6..97d8fd99904a77 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -144,7 +144,7 @@ struct _gc_runtime_state { Py_ssize_t long_lived_pending; }; -PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); +PyAPI_FUNC(void) _PyGC_InitializeRuntime(struct _gc_runtime_state *); /* Set the memory allocator of the specified domain to the default. diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index aa2103f07c795b..12d6ce0e1cb2c7 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -74,8 +74,6 @@ struct _is { int finalizing; - struct _gc_runtime_state gc; - PyObject *modules; PyObject *modules_by_index; PyObject *sysdict; @@ -132,7 +130,9 @@ struct _is { struct _warnings_runtime_state warnings; PyObject *audit_hooks; - +/* + * See bpo-36876: miscellaneous ad hoc statics have been moved here. + */ struct { struct { int level; @@ -239,6 +239,7 @@ typedef struct pyruntimestate { void (*exitfuncs[NEXITFUNCS])(void); int nexitfuncs; + struct _gc_runtime_state gc; struct _ceval_runtime_state ceval; struct _gilstate_runtime_state gilstate; diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-20-12-01-37.bpo-36854.Zga_md.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-20-12-01-37.bpo-36854.Zga_md.rst deleted file mode 100644 index 2b4d5b3bc85908..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-11-20-12-01-37.bpo-36854.Zga_md.rst +++ /dev/null @@ -1,3 +0,0 @@ -The garbage collector state becomes per interpreter -(``PyInterpreterState.gc``), rather than being global -(``_PyRuntimeState.gc``). diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 64afe831c84c51..c2e8971eba85f1 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -133,7 +133,7 @@ static PyObject *gc_str = NULL; #define GEN_HEAD(gcstate, n) (&(gcstate)->generations[n].head) void -_PyGC_InitState(GCState *gcstate) +_PyGC_InitializeRuntime(GCState *gcstate) { gcstate->enabled = 1; /* automatic collection enabled? */ @@ -159,7 +159,7 @@ _PyGC_InitState(GCState *gcstate) PyStatus _PyGC_Init(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; if (gcstate->garbage == NULL) { gcstate->garbage = PyList_New(0); if (gcstate->garbage == NULL) { @@ -1156,7 +1156,7 @@ collect(PyThreadState *tstate, int generation, PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ PyGC_Head *gc; _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; if (gcstate->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); @@ -1321,7 +1321,7 @@ invoke_gc_callback(PyThreadState *tstate, const char *phase, assert(!_PyErr_Occurred(tstate)); /* we may get called very early */ - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; if (gcstate->callbacks == NULL) { return; } @@ -1373,7 +1373,7 @@ collect_with_callback(PyThreadState *tstate, int generation) static Py_ssize_t collect_generations(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and * generations younger than it will be collected. */ @@ -1407,7 +1407,7 @@ gc_enable_impl(PyObject *module) /*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; gcstate->enabled = 1; Py_RETURN_NONE; } @@ -1423,7 +1423,7 @@ gc_disable_impl(PyObject *module) /*[clinic end generated code: output=97d1030f7aa9d279 input=8c2e5a14e800d83b]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; gcstate->enabled = 0; Py_RETURN_NONE; } @@ -1439,7 +1439,7 @@ gc_isenabled_impl(PyObject *module) /*[clinic end generated code: output=1874298331c49130 input=30005e0422373b31]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; return gcstate->enabled; } @@ -1468,7 +1468,7 @@ gc_collect_impl(PyObject *module, int generation) return -1; } - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; Py_ssize_t n; if (gcstate->collecting) { /* already collecting, don't do anything */ @@ -1505,7 +1505,7 @@ 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 = &tstate->interp->runtime->gc; gcstate->debug = flags; Py_RETURN_NONE; } @@ -1521,7 +1521,7 @@ 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 = &tstate->interp->runtime->gc; return gcstate->debug; } @@ -1535,7 +1535,7 @@ static PyObject * gc_set_threshold(PyObject *self, PyObject *args) { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &gcstate->generations[0].threshold, &gcstate->generations[1].threshold, @@ -1559,7 +1559,7 @@ 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 = &tstate->interp->runtime->gc; return Py_BuildValue("(iii)", gcstate->generations[0].threshold, gcstate->generations[1].threshold, @@ -1577,7 +1577,7 @@ 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 = &tstate->interp->runtime->gc; return Py_BuildValue("(iii)", gcstate->generations[0].count, gcstate->generations[1].count, @@ -1627,7 +1627,7 @@ gc_get_referrers(PyObject *self, PyObject *args) return NULL; } - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; for (i = 0; i < NUM_GENERATIONS; i++) { if (!(gc_referrers_for(args, GEN_HEAD(gcstate, i), result))) { Py_DECREF(result); @@ -1692,7 +1692,7 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) PyThreadState *tstate = _PyThreadState_GET(); int i; PyObject* result; - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; result = PyList_New(0); if (result == NULL) { @@ -1751,7 +1751,7 @@ gc_get_stats_impl(PyObject *module) /* 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 = &tstate->interp->runtime->gc; for (i = 0; i < NUM_GENERATIONS; i++) { stats[i] = gcstate->generation_stats[i]; } @@ -1824,7 +1824,7 @@ gc_freeze_impl(PyObject *module) /*[clinic end generated code: output=502159d9cdc4c139 input=b602b16ac5febbe5]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; for (int i = 0; i < NUM_GENERATIONS; ++i) { gc_list_merge(GEN_HEAD(gcstate, i), &gcstate->permanent_generation.head); gcstate->generations[i].count = 0; @@ -1845,7 +1845,7 @@ gc_unfreeze_impl(PyObject *module) /*[clinic end generated code: output=1c15f2043b25e169 input=2dd52b170f4cef6c]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; gc_list_merge(&gcstate->permanent_generation.head, GEN_HEAD(gcstate, NUM_GENERATIONS-1)); Py_RETURN_NONE; @@ -1862,7 +1862,7 @@ 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 = &tstate->interp->runtime->gc; return gc_list_size(&gcstate->permanent_generation.head); } @@ -1926,38 +1926,34 @@ static struct PyModuleDef gcmodule = { PyMODINIT_FUNC PyInit_gc(void) { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + PyObject *m; - PyObject *m = PyModule_Create(&gcmodule); + m = PyModule_Create(&gcmodule); if (m == NULL) { return NULL; } + GCState *gcstate = &_PyRuntime.gc; if (gcstate->garbage == NULL) { gcstate->garbage = PyList_New(0); - if (gcstate->garbage == NULL) { + if (gcstate->garbage == NULL) return NULL; - } } Py_INCREF(gcstate->garbage); - if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) { + if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) return NULL; - } if (gcstate->callbacks == NULL) { gcstate->callbacks = PyList_New(0); - if (gcstate->callbacks == NULL) { + if (gcstate->callbacks == NULL) return NULL; - } } Py_INCREF(gcstate->callbacks); - if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) { + if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) return NULL; - } -#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) { return NULL; } +#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL ADD_INT(DEBUG_STATS); ADD_INT(DEBUG_COLLECTABLE); ADD_INT(DEBUG_UNCOLLECTABLE); @@ -1972,7 +1968,7 @@ Py_ssize_t PyGC_Collect(void) { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; if (!gcstate->enabled) { return 0; @@ -2007,7 +2003,7 @@ _PyGC_CollectNoFail(void) PyThreadState *tstate = _PyThreadState_GET(); assert(!_PyErr_Occurred(tstate)); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; Py_ssize_t n; /* Ideally, this function is only called on interpreter shutdown, @@ -2030,7 +2026,7 @@ _PyGC_CollectNoFail(void) void _PyGC_DumpShutdownStats(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; if (!(gcstate->debug & DEBUG_SAVEALL) && gcstate->garbage != NULL && PyList_GET_SIZE(gcstate->garbage) > 0) { const char *message; @@ -2067,7 +2063,7 @@ _PyGC_DumpShutdownStats(PyThreadState *tstate) void _PyGC_Fini(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; Py_CLEAR(gcstate->garbage); Py_CLEAR(gcstate->callbacks); } @@ -2132,7 +2128,7 @@ static PyObject * _PyObject_GC_Alloc(int use_calloc, size_t basicsize) { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { return _PyErr_NoMemory(tstate); } @@ -2231,7 +2227,7 @@ PyObject_GC_Del(void *op) gc_list_remove(g); } PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &tstate->interp->runtime->gc; if (gcstate->generations[0].count > 0) { gcstate->generations[0].count--; } diff --git a/Objects/object.c b/Objects/object.c index 6fc114621c1d1d..3e612825c27775 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2131,14 +2131,11 @@ Py_ReprLeave(PyObject *obj) void _PyTrash_deposit_object(PyObject *op) { - PyThreadState *tstate = _PyThreadState_GET(); - struct _gc_runtime_state *gcstate = &tstate->interp->gc; - _PyObject_ASSERT(op, PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); _PyObject_ASSERT(op, op->ob_refcnt == 0); - _PyGCHead_SET_PREV(_Py_AS_GC(op), gcstate->trash_delete_later); - gcstate->trash_delete_later = op; + _PyGCHead_SET_PREV(_Py_AS_GC(op), _PyRuntime.gc.trash_delete_later); + _PyRuntime.gc.trash_delete_later = op; } /* The equivalent API, using per-thread state recursion info */ @@ -2159,14 +2156,11 @@ _PyTrash_thread_deposit_object(PyObject *op) void _PyTrash_destroy_chain(void) { - PyThreadState *tstate = _PyThreadState_GET(); - struct _gc_runtime_state *gcstate = &tstate->interp->gc; - - while (gcstate->trash_delete_later) { - PyObject *op = gcstate->trash_delete_later; + while (_PyRuntime.gc.trash_delete_later) { + PyObject *op = _PyRuntime.gc.trash_delete_later; destructor dealloc = Py_TYPE(op)->tp_dealloc; - gcstate->trash_delete_later = + _PyRuntime.gc.trash_delete_later = (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op)); /* Call the deallocator directly. This used to try to @@ -2176,9 +2170,9 @@ _PyTrash_destroy_chain(void) * up distorting allocation statistics. */ _PyObject_ASSERT(op, op->ob_refcnt == 0); - ++gcstate->trash_delete_nesting; + ++_PyRuntime.gc.trash_delete_nesting; (*dealloc)(op); - --gcstate->trash_delete_nesting; + --_PyRuntime.gc.trash_delete_nesting; } } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index cce4783bc12c31..d132f82b213c1f 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1274,9 +1274,8 @@ finalize_interp_clear(PyThreadState *tstate) PyGrammar_RemoveAccelerators(&_PyParser_Grammar); _PyExc_Fini(); + _PyGC_Fini(tstate); } - - _PyGC_Fini(tstate); } diff --git a/Python/pystate.c b/Python/pystate.c index d792380de46498..dc2523bb304cf4 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -58,6 +58,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) runtime->open_code_userdata = open_code_userdata; runtime->audit_hook_head = audit_hook_head; + _PyGC_InitializeRuntime(&runtime->gc); _PyEval_Initialize(&runtime->ceval); PyPreConfig_InitPythonConfig(&runtime->preconfig); @@ -213,7 +214,6 @@ PyInterpreterState_New(void) _PyRuntimeState *runtime = &_PyRuntime; interp->runtime = runtime; - _PyGC_InitState(&interp->gc); PyConfig_InitPythonConfig(&interp->config); interp->eval_frame = _PyEval_EvalFrameDefault; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy