]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-106140: Reorder some fields to facilitate out-of-process inspection (#106143)
authorPablo Galindo Salgado <Pablogsal@gmail.com>
Tue, 27 Jun 2023 15:26:53 +0000 (16:26 +0100)
committerGitHub <noreply@github.com>
Tue, 27 Jun 2023 15:26:53 +0000 (16:26 +0100)
Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
Include/internal/pycore_interp.h
Include/internal/pycore_runtime.h

index a4177f379acc681660947b6abe6bc08d23c056a4..8d0bb7672690a863dde41cc3b76f886baf1060e9 100644 (file)
@@ -48,12 +48,22 @@ struct _Py_long_state {
    */
 struct _is {
 
-    struct _ceval_state ceval;
     PyInterpreterState *next;
 
+    int64_t id;
+    int64_t id_refcount;
+    int requires_idref;
+    PyThread_type_lock id_mutex;
+
+    /* Has been initialized to a safe state.
+
+       In order to be effective, this must be set to 0 during or right
+       after allocation. */
+    int _initialized;
+    int finalizing;
+
     uint64_t monitoring_version;
     uint64_t last_restart_version;
-
     struct pythreads {
         uint64_t next_unique_id;
         /* The linked list of threads, newest first. */
@@ -72,18 +82,6 @@ struct _is {
        Get runtime from tstate: tstate->interp->runtime. */
     struct pyruntimestate *runtime;
 
-    int64_t id;
-    int64_t id_refcount;
-    int requires_idref;
-    PyThread_type_lock id_mutex;
-
-    /* Has been initialized to a safe state.
-
-       In order to be effective, this must be set to 0 during or right
-       after allocation. */
-    int _initialized;
-    int finalizing;
-
     /* Set by Py_EndInterpreter().
 
        Use _PyInterpreterState_GetFinalizing()
@@ -91,17 +89,33 @@ struct _is {
        to access it, don't access it directly. */
     _Py_atomic_address _finalizing;
 
-    struct _obmalloc_state obmalloc;
-
     struct _gc_runtime_state gc;
 
-    struct _import_state imports;
+    /* The following fields are here to avoid allocation during init.
+       The data is exposed through PyInterpreterState pointer fields.
+       These fields should not be accessed directly outside of init.
+
+       All other PyInterpreterState pointer fields are populated when
+       needed and default to NULL.
+
+       For now there are some exceptions to that rule, which require
+       allocation during init.  These will be addressed on a case-by-case
+       basis.  Also see _PyRuntimeState regarding the various mutex fields.
+       */
+
+    /* The per-interpreter GIL, which might not be used. */
+    struct _gil_runtime_state _gil;
 
     // Dictionary of the sys module
     PyObject *sysdict;
     // Dictionary of the builtins module
     PyObject *builtins;
 
+     /* ---------- IMPORTANT ---------------------------
+     The fields above this line are declared as early as
+     possible to facilitate out-of-process observability
+     tools. */
+
     PyObject *codec_search_path;
     PyObject *codec_search_cache;
     PyObject *codec_error_registry;
@@ -133,6 +147,12 @@ struct _is {
     struct _warnings_runtime_state warnings;
     struct atexit_state atexit;
 
+    struct _ceval_state ceval;
+
+    struct _obmalloc_state obmalloc;
+
+    struct _import_state imports;
+
     PyObject *audit_hooks;
     PyType_WatchCallback type_watchers[TYPE_MAX_WATCHERS];
     PyCode_WatchCallback code_watchers[CODE_MAX_WATCHERS];
@@ -175,22 +195,7 @@ struct _is {
     struct _Py_interp_cached_objects cached_objects;
     struct _Py_interp_static_objects static_objects;
 
-    /* The following fields are here to avoid allocation during init.
-       The data is exposed through PyInterpreterState pointer fields.
-       These fields should not be accessed directly outside of init.
-
-       All other PyInterpreterState pointer fields are populated when
-       needed and default to NULL.
-
-       For now there are some exceptions to that rule, which require
-       allocation during init.  These will be addressed on a case-by-case
-       basis.  Also see _PyRuntimeState regarding the various mutex fields.
-       */
-
-    /* The per-interpreter GIL, which might not be used. */
-    struct _gil_runtime_state _gil;
-
-    /* the initial PyInterpreterState.threads.head */
+   /* the initial PyInterpreterState.threads.head */
     PyThreadState _initial_thread;
 };
 
index 8f51e2def69fc908c3c59761969e473451ae6296..5ed97e9715b2b0b8e817233a66f3ab34b1438731 100644 (file)
@@ -84,13 +84,6 @@ typedef struct pyruntimestate {
        to access it, don't access it directly. */
     _Py_atomic_address _finalizing;
 
-    struct _pymem_allocators allocators;
-    struct _obmalloc_global_state obmalloc;
-    struct pyhash_runtime_state pyhash_state;
-    struct _time_runtime_state time;
-    struct _pythread_runtime_state threads;
-    struct _signals_runtime_state signals;
-
     struct pyinterpreters {
         PyThread_type_lock mutex;
         /* The linked list of interpreters, newest first. */
@@ -109,13 +102,26 @@ typedef struct pyruntimestate {
            using a Python int. */
         int64_t next_id;
     } interpreters;
+
+    unsigned long main_thread;
+
+    /* ---------- IMPORTANT ---------------------------
+     The fields above this line are declared as early as
+     possible to facilitate out-of-process observability
+     tools. */
+
     // XXX Remove this field once we have a tp_* slot.
     struct _xidregistry {
         PyThread_type_lock mutex;
         struct _xidregitem *head;
     } xidregistry;
 
-    unsigned long main_thread;
+    struct _pymem_allocators allocators;
+    struct _obmalloc_global_state obmalloc;
+    struct pyhash_runtime_state pyhash_state;
+    struct _time_runtime_state time;
+    struct _pythread_runtime_state threads;
+    struct _signals_runtime_state signals;
 
     /* Used for the thread state bound to the current thread. */
     Py_tss_t autoTSSkey;