Skip to content

Commit 2d5a1c2

Browse files
authored
gh-106140: Reorder some fields to facilitate out-of-process inspection (#106143)
Signed-off-by: Pablo Galindo <[email protected]>
1 parent bb578a0 commit 2d5a1c2

File tree

2 files changed

+52
-41
lines changed

2 files changed

+52
-41
lines changed

Include/internal/pycore_interp.h

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,22 @@ struct _Py_long_state {
4848
*/
4949
struct _is {
5050

51-
struct _ceval_state ceval;
5251
PyInterpreterState *next;
5352

53+
int64_t id;
54+
int64_t id_refcount;
55+
int requires_idref;
56+
PyThread_type_lock id_mutex;
57+
58+
/* Has been initialized to a safe state.
59+
60+
In order to be effective, this must be set to 0 during or right
61+
after allocation. */
62+
int _initialized;
63+
int finalizing;
64+
5465
uint64_t monitoring_version;
5566
uint64_t last_restart_version;
56-
5767
struct pythreads {
5868
uint64_t next_unique_id;
5969
/* The linked list of threads, newest first. */
@@ -72,36 +82,40 @@ struct _is {
7282
Get runtime from tstate: tstate->interp->runtime. */
7383
struct pyruntimestate *runtime;
7484

75-
int64_t id;
76-
int64_t id_refcount;
77-
int requires_idref;
78-
PyThread_type_lock id_mutex;
79-
80-
/* Has been initialized to a safe state.
81-
82-
In order to be effective, this must be set to 0 during or right
83-
after allocation. */
84-
int _initialized;
85-
int finalizing;
86-
8785
/* Set by Py_EndInterpreter().
8886
8987
Use _PyInterpreterState_GetFinalizing()
9088
and _PyInterpreterState_SetFinalizing()
9189
to access it, don't access it directly. */
9290
_Py_atomic_address _finalizing;
9391

94-
struct _obmalloc_state obmalloc;
95-
9692
struct _gc_runtime_state gc;
9793

98-
struct _import_state imports;
94+
/* The following fields are here to avoid allocation during init.
95+
The data is exposed through PyInterpreterState pointer fields.
96+
These fields should not be accessed directly outside of init.
97+
98+
All other PyInterpreterState pointer fields are populated when
99+
needed and default to NULL.
100+
101+
For now there are some exceptions to that rule, which require
102+
allocation during init. These will be addressed on a case-by-case
103+
basis. Also see _PyRuntimeState regarding the various mutex fields.
104+
*/
105+
106+
/* The per-interpreter GIL, which might not be used. */
107+
struct _gil_runtime_state _gil;
99108

100109
// Dictionary of the sys module
101110
PyObject *sysdict;
102111
// Dictionary of the builtins module
103112
PyObject *builtins;
104113

114+
/* ---------- IMPORTANT ---------------------------
115+
The fields above this line are declared as early as
116+
possible to facilitate out-of-process observability
117+
tools. */
118+
105119
PyObject *codec_search_path;
106120
PyObject *codec_search_cache;
107121
PyObject *codec_error_registry;
@@ -133,6 +147,12 @@ struct _is {
133147
struct _warnings_runtime_state warnings;
134148
struct atexit_state atexit;
135149

150+
struct _ceval_state ceval;
151+
152+
struct _obmalloc_state obmalloc;
153+
154+
struct _import_state imports;
155+
136156
PyObject *audit_hooks;
137157
PyType_WatchCallback type_watchers[TYPE_MAX_WATCHERS];
138158
PyCode_WatchCallback code_watchers[CODE_MAX_WATCHERS];
@@ -175,22 +195,7 @@ struct _is {
175195
struct _Py_interp_cached_objects cached_objects;
176196
struct _Py_interp_static_objects static_objects;
177197

178-
/* The following fields are here to avoid allocation during init.
179-
The data is exposed through PyInterpreterState pointer fields.
180-
These fields should not be accessed directly outside of init.
181-
182-
All other PyInterpreterState pointer fields are populated when
183-
needed and default to NULL.
184-
185-
For now there are some exceptions to that rule, which require
186-
allocation during init. These will be addressed on a case-by-case
187-
basis. Also see _PyRuntimeState regarding the various mutex fields.
188-
*/
189-
190-
/* The per-interpreter GIL, which might not be used. */
191-
struct _gil_runtime_state _gil;
192-
193-
/* the initial PyInterpreterState.threads.head */
198+
/* the initial PyInterpreterState.threads.head */
194199
PyThreadState _initial_thread;
195200
};
196201

Include/internal/pycore_runtime.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,6 @@ typedef struct pyruntimestate {
8484
to access it, don't access it directly. */
8585
_Py_atomic_address _finalizing;
8686

87-
struct _pymem_allocators allocators;
88-
struct _obmalloc_global_state obmalloc;
89-
struct pyhash_runtime_state pyhash_state;
90-
struct _time_runtime_state time;
91-
struct _pythread_runtime_state threads;
92-
struct _signals_runtime_state signals;
93-
9487
struct pyinterpreters {
9588
PyThread_type_lock mutex;
9689
/* The linked list of interpreters, newest first. */
@@ -109,13 +102,26 @@ typedef struct pyruntimestate {
109102
using a Python int. */
110103
int64_t next_id;
111104
} interpreters;
105+
106+
unsigned long main_thread;
107+
108+
/* ---------- IMPORTANT ---------------------------
109+
The fields above this line are declared as early as
110+
possible to facilitate out-of-process observability
111+
tools. */
112+
112113
// XXX Remove this field once we have a tp_* slot.
113114
struct _xidregistry {
114115
PyThread_type_lock mutex;
115116
struct _xidregitem *head;
116117
} xidregistry;
117118

118-
unsigned long main_thread;
119+
struct _pymem_allocators allocators;
120+
struct _obmalloc_global_state obmalloc;
121+
struct pyhash_runtime_state pyhash_state;
122+
struct _time_runtime_state time;
123+
struct _pythread_runtime_state threads;
124+
struct _signals_runtime_state signals;
119125

120126
/* Used for the thread state bound to the current thread. */
121127
Py_tss_t autoTSSkey;

0 commit comments

Comments
 (0)