Skip to content

Commit 322f962

Browse files
bpo-45953: Statically initialize all the non-object PyInterpreterState fields we can. (gh-30589)
https://bugs.python.org/issue45953
1 parent 324908b commit 322f962

File tree

5 files changed

+40
-26
lines changed

5 files changed

+40
-26
lines changed

Include/internal/pycore_gc.h

+2
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ struct _gc_runtime_state {
134134
/* Current call-stack depth of tp_dealloc calls. */
135135
int trash_delete_nesting;
136136

137+
/* Is automatic collection enabled? */
137138
int enabled;
138139
int debug;
139140
/* linked lists of container objects */
@@ -161,6 +162,7 @@ struct _gc_runtime_state {
161162
Py_ssize_t long_lived_pending;
162163
};
163164

165+
164166
extern void _PyGC_InitState(struct _gc_runtime_state *);
165167

166168
extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);

Include/internal/pycore_runtime_init.h

+27
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,36 @@ extern "C" {
3232
._main_interpreter = _PyInterpreterState_INIT, \
3333
}
3434

35+
#ifdef HAVE_DLOPEN
36+
# include <dlfcn.h>
37+
# if HAVE_DECL_RTLD_NOW
38+
# define _Py_DLOPEN_FLAGS RTLD_NOW
39+
# else
40+
# define _Py_DLOPEN_FLAGS RTLD_LAZY
41+
# endif
42+
# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS,
43+
#else
44+
# define _Py_DLOPEN_FLAGS 0
45+
# define DLOPENFLAGS_INIT
46+
#endif
47+
3548
#define _PyInterpreterState_INIT \
3649
{ \
3750
._static = 1, \
51+
.id_refcount = -1, \
52+
DLOPENFLAGS_INIT \
53+
.ceval = { \
54+
.recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \
55+
}, \
56+
.gc = { \
57+
.enabled = 1, \
58+
.generations = { \
59+
/* .head is set in _PyGC_InitState(). */ \
60+
{ .threshold = 700, }, \
61+
{ .threshold = 10, }, \
62+
{ .threshold = 10, }, \
63+
}, \
64+
}, \
3865
._initial_thread = _PyThreadState_INIT, \
3966
}
4067

Modules/gcmodule.c

+11-15
Original file line numberDiff line numberDiff line change
@@ -139,24 +139,20 @@ get_gc_state(void)
139139
void
140140
_PyGC_InitState(GCState *gcstate)
141141
{
142-
gcstate->enabled = 1; /* automatic collection enabled? */
143-
144-
#define _GEN_HEAD(n) GEN_HEAD(gcstate, n)
145-
struct gc_generation generations[NUM_GENERATIONS] = {
146-
/* PyGC_Head, threshold, count */
147-
{{(uintptr_t)_GEN_HEAD(0), (uintptr_t)_GEN_HEAD(0)}, 700, 0},
148-
{{(uintptr_t)_GEN_HEAD(1), (uintptr_t)_GEN_HEAD(1)}, 10, 0},
149-
{{(uintptr_t)_GEN_HEAD(2), (uintptr_t)_GEN_HEAD(2)}, 10, 0},
150-
};
142+
#define INIT_HEAD(GEN) \
143+
do { \
144+
GEN.head._gc_next = (uintptr_t)&GEN.head; \
145+
GEN.head._gc_prev = (uintptr_t)&GEN.head; \
146+
} while (0)
147+
151148
for (int i = 0; i < NUM_GENERATIONS; i++) {
152-
gcstate->generations[i] = generations[i];
149+
assert(gcstate->generations[i].count == 0);
150+
INIT_HEAD(gcstate->generations[i]);
153151
};
154152
gcstate->generation0 = GEN_HEAD(gcstate, 0);
155-
struct gc_generation permanent_generation = {
156-
{(uintptr_t)&gcstate->permanent_generation.head,
157-
(uintptr_t)&gcstate->permanent_generation.head}, 0, 0
158-
};
159-
gcstate->permanent_generation = permanent_generation;
153+
INIT_HEAD(gcstate->permanent_generation);
154+
155+
#undef INIT_HEAD
160156
}
161157

162158

Python/ceval.c

-2
Original file line numberDiff line numberDiff line change
@@ -748,8 +748,6 @@ _PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval)
748748
void
749749
_PyEval_InitState(struct _ceval_state *ceval, PyThread_type_lock pending_lock)
750750
{
751-
ceval->recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
752-
753751
struct _pending_calls *pending = &ceval->pending;
754752
assert(pending->lock == NULL);
755753

Python/pystate.c

-9
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ init_interpreter(PyInterpreterState *interp,
281281

282282
assert(id > 0 || (id == 0 && interp == runtime->interpreters.main));
283283
interp->id = id;
284-
interp->id_refcount = -1;
285284

286285
assert(runtime->interpreters.head == interp);
287286
assert(next != NULL || (interp == runtime->interpreters.main));
@@ -291,14 +290,6 @@ init_interpreter(PyInterpreterState *interp,
291290
_PyGC_InitState(&interp->gc);
292291
PyConfig_InitPythonConfig(&interp->config);
293292
_PyType_InitCache(interp);
294-
interp->eval_frame = NULL;
295-
#ifdef HAVE_DLOPEN
296-
#if HAVE_DECL_RTLD_NOW
297-
interp->dlopenflags = RTLD_NOW;
298-
#else
299-
interp->dlopenflags = RTLD_LAZY;
300-
#endif
301-
#endif
302293

303294
interp->_initialized = 1;
304295
}

0 commit comments

Comments
 (0)