From 7d8974ff439e06989f4728d36b45b5165c77bbfe Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 16 Dec 2021 15:18:39 -0700 Subject: [PATCH 1/7] Statically initialize PyInterpreterState.id_refcount. --- Include/internal/pycore_runtime_init.h | 1 + Python/pystate.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index fc768ff5d053f7..172a3a4d287b62 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -35,6 +35,7 @@ extern "C" { #define _PyInterpreterState_INIT \ { \ ._static = 1, \ + .id_refcount = -1, \ ._initial_thread = _PyThreadState_INIT, \ } diff --git a/Python/pystate.c b/Python/pystate.c index 50b36218960284..77ec30ef4931b3 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -281,7 +281,6 @@ init_interpreter(PyInterpreterState *interp, assert(id > 0 || (id == 0 && interp == runtime->interpreters.main)); interp->id = id; - interp->id_refcount = -1; assert(runtime->interpreters.head == interp); assert(next != NULL || (interp == runtime->interpreters.main)); From cc42c1f54cc64fb8971982e18e56da4dc27e5523 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 28 Dec 2021 14:09:03 -0700 Subject: [PATCH 2/7] Move Py_DEFAULT_RECURSION_LIMIT to a header file. --- Include/internal/pycore_ceval.h | 5 +++++ Python/ceval.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 20508d4a687475..53d0b5c4549bc1 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -12,9 +12,14 @@ extern "C" { struct pyruntimestate; struct _ceval_runtime_state; +#ifndef Py_DEFAULT_RECURSION_LIMIT +# define Py_DEFAULT_RECURSION_LIMIT 1000 +#endif + #include "pycore_interp.h" // PyInterpreterState.eval_frame #include "pycore_pystate.h" // _PyThreadState_GET() + extern void _Py_FinishPendingCalls(PyThreadState *tstate); extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *); extern void _PyEval_InitState(struct _ceval_state *, PyThread_type_lock); diff --git a/Python/ceval.c b/Python/ceval.c index d33cd4e1edb5dd..eed902fc687918 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -737,10 +737,6 @@ Py_MakePendingCalls(void) /* The interpreter's recursion limit */ -#ifndef Py_DEFAULT_RECURSION_LIMIT -# define Py_DEFAULT_RECURSION_LIMIT 1000 -#endif - void _PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) { From 5cc2c4142b4823f6e8cc06ff291d481e2a6c3dc8 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 16 Dec 2021 15:19:23 -0700 Subject: [PATCH 3/7] Statically initialize PyInterpreterState.ceval.recursion_limit. --- Include/internal/pycore_runtime_init.h | 3 +++ Python/ceval.c | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 172a3a4d287b62..a6c0847daff72b 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -36,6 +36,9 @@ extern "C" { { \ ._static = 1, \ .id_refcount = -1, \ + .ceval = { \ + .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ + }, \ ._initial_thread = _PyThreadState_INIT, \ } diff --git a/Python/ceval.c b/Python/ceval.c index eed902fc687918..70a7750f811902 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -748,8 +748,6 @@ _PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) void _PyEval_InitState(struct _ceval_state *ceval, PyThread_type_lock pending_lock) { - ceval->recursion_limit = Py_DEFAULT_RECURSION_LIMIT; - struct _pending_calls *pending = &ceval->pending; assert(pending->lock == NULL); From e60c80258058b527a08c868e2d4a360d3c61f347 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 16 Dec 2021 15:23:20 -0700 Subject: [PATCH 4/7] Statically initialize PyInterpreterState.gc.enabled. --- Include/internal/pycore_runtime_init.h | 3 +++ Modules/gcmodule.c | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index a6c0847daff72b..29a93e36386291 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -39,6 +39,9 @@ extern "C" { .ceval = { \ .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ }, \ + .gc = { \ + .enabled = 1, /* automatic collection enabled? */ \ + }, \ ._initial_thread = _PyThreadState_INIT, \ } diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index e22f031f574904..14320518e5a8c5 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -139,8 +139,6 @@ get_gc_state(void) void _PyGC_InitState(GCState *gcstate) { - gcstate->enabled = 1; /* automatic collection enabled? */ - #define _GEN_HEAD(n) GEN_HEAD(gcstate, n) struct gc_generation generations[NUM_GENERATIONS] = { /* PyGC_Head, threshold, count */ From 54458c4669443184754a71d7aba1109aa3fd9f2d Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 16 Dec 2021 16:07:42 -0700 Subject: [PATCH 5/7] Statically initialize PyInterpreterState.gc.generations. --- Include/internal/pycore_gc.h | 2 ++ Include/internal/pycore_runtime_init.h | 8 +++++++- Modules/gcmodule.c | 24 +++++++++++------------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index a23dca805491d0..56a23e99707527 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -134,6 +134,7 @@ struct _gc_runtime_state { /* Current call-stack depth of tp_dealloc calls. */ int trash_delete_nesting; + /* Is automatic collection enabled? */ int enabled; int debug; /* linked lists of container objects */ @@ -161,6 +162,7 @@ struct _gc_runtime_state { Py_ssize_t long_lived_pending; }; + extern void _PyGC_InitState(struct _gc_runtime_state *); extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate); diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 29a93e36386291..e3a57463eb50d9 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -40,7 +40,13 @@ extern "C" { .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ }, \ .gc = { \ - .enabled = 1, /* automatic collection enabled? */ \ + .enabled = 1, \ + .generations = { \ + /* .head is set in _PyGC_InitState(). */ \ + { .threshold = 700, }, \ + { .threshold = 10, }, \ + { .threshold = 10, }, \ + }, \ }, \ ._initial_thread = _PyThreadState_INIT, \ } diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 14320518e5a8c5..16f8c2b18e717c 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -139,22 +139,20 @@ get_gc_state(void) void _PyGC_InitState(GCState *gcstate) { -#define _GEN_HEAD(n) GEN_HEAD(gcstate, n) - struct gc_generation generations[NUM_GENERATIONS] = { - /* PyGC_Head, threshold, count */ - {{(uintptr_t)_GEN_HEAD(0), (uintptr_t)_GEN_HEAD(0)}, 700, 0}, - {{(uintptr_t)_GEN_HEAD(1), (uintptr_t)_GEN_HEAD(1)}, 10, 0}, - {{(uintptr_t)_GEN_HEAD(2), (uintptr_t)_GEN_HEAD(2)}, 10, 0}, - }; +#define INIT_HEAD(GEN) \ + do { \ + GEN.head._gc_next = (uintptr_t)&GEN.head; \ + GEN.head._gc_prev = (uintptr_t)&GEN.head; \ + } while (0) + for (int i = 0; i < NUM_GENERATIONS; i++) { - gcstate->generations[i] = generations[i]; + assert(gcstate->generations[i].count == 0); + INIT_HEAD(gcstate->generations[i]); }; gcstate->generation0 = GEN_HEAD(gcstate, 0); - struct gc_generation permanent_generation = { - {(uintptr_t)&gcstate->permanent_generation.head, - (uintptr_t)&gcstate->permanent_generation.head}, 0, 0 - }; - gcstate->permanent_generation = permanent_generation; + INIT_HEAD(gcstate->permanent_generation); + +#undef INIT_HEAD } From c6b7bb4f2aac25021b18de03986f98d1cae2889e Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 16 Dec 2021 16:18:33 -0700 Subject: [PATCH 6/7] Statically initialize PyInterpreterState.dlopen_flags. --- Include/internal/pycore_runtime_init.h | 12 ++++++++++++ Python/pystate.c | 8 -------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index e3a57463eb50d9..ae0203c1779f5b 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -32,10 +32,22 @@ extern "C" { ._main_interpreter = _PyInterpreterState_INIT, \ } +#ifdef HAVE_DLOPEN +# include +# if HAVE_DECL_RTLD_NOW +# define _Py_DLOPEN_FLAGS RTLD_NOW +# else +# define _Py_DLOPEN_FLAGS RTLD_LAZY +# endif +#else +# define _Py_DLOPEN_FLAGS 0 +#endif + #define _PyInterpreterState_INIT \ { \ ._static = 1, \ .id_refcount = -1, \ + .dlopenflags = _Py_DLOPEN_FLAGS, \ .ceval = { \ .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ }, \ diff --git a/Python/pystate.c b/Python/pystate.c index 77ec30ef4931b3..eefa2d3732588c 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -290,14 +290,6 @@ init_interpreter(PyInterpreterState *interp, _PyGC_InitState(&interp->gc); PyConfig_InitPythonConfig(&interp->config); _PyType_InitCache(interp); - interp->eval_frame = NULL; -#ifdef HAVE_DLOPEN -#if HAVE_DECL_RTLD_NOW - interp->dlopenflags = RTLD_NOW; -#else - interp->dlopenflags = RTLD_LAZY; -#endif -#endif interp->_initialized = 1; } From 25ad61f9a358658be05433ddb2b84cb3dc24026f Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 13 Jan 2022 16:47:35 -0700 Subject: [PATCH 7/7] Do not set the dlopenflags field if not available. --- Include/internal/pycore_runtime_init.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index ae0203c1779f5b..e481c9becaed90 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -39,15 +39,17 @@ extern "C" { # else # define _Py_DLOPEN_FLAGS RTLD_LAZY # endif +# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS, #else # define _Py_DLOPEN_FLAGS 0 +# define DLOPENFLAGS_INIT #endif #define _PyInterpreterState_INIT \ { \ ._static = 1, \ .id_refcount = -1, \ - .dlopenflags = _Py_DLOPEN_FLAGS, \ + DLOPENFLAGS_INIT \ .ceval = { \ .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ }, \