gh-81057: Add PyInterpreterState.static_objects (gh-99397)

As we consolidate global variables, we find some objects that are almost suitable to add to _PyRuntimeState.global_objects, but have some small/sneaky bit of per-interpreter state (e.g. a weakref list). We're adding PyInterpreterState.static_objects so we can move such objects there. (We'll removed the _not_used field once we've added others.)

https://github.com/python/cpython/issues/81057
This commit is contained in:
Eric Snow 2022-11-11 14:24:18 -07:00 committed by GitHub
parent dd36b71fa6
commit f531b6879b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 5 deletions

View File

@ -49,6 +49,24 @@ struct _Py_global_objects {
PyObject *interned; PyObject *interned;
}; };
#define _Py_INTERP_CACHED_OBJECT(interp, NAME) \
(interp)->cached_objects.NAME
struct _Py_interp_cached_objects {
int _not_set;
};
#define _Py_INTERP_STATIC_OBJECT(interp, NAME) \
(interp)->static_objects.NAME
#define _Py_INTERP_SINGLETON(interp, NAME) \
_Py_INTERP_STATIC_OBJECT(interp, singletons.NAME)
struct _Py_interp_static_objects {
struct {
int _not_used;
} singletons;
};
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -24,8 +24,9 @@ _PyStaticObject_CheckRefcnt(PyObject *obj) {
/* The following is auto-generated by Tools/build/generate_global_objects.py. */ /* The following is auto-generated by Tools/build/generate_global_objects.py. */
#ifdef Py_DEBUG #ifdef Py_DEBUG
static inline void static inline void
_PyStaticObjects_CheckRefcnt(void) { _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
/* generated (see pycore_runtime_init_generated.h) */ /* generated runtime-global */
// (see pycore_runtime_init_generated.h)
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -5]); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -5]);
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -4]); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -4]);
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -3]); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -3]);

View File

@ -20,6 +20,7 @@ extern "C" {
#include "pycore_genobject.h" // struct _Py_async_gen_state #include "pycore_genobject.h" // struct _Py_async_gen_state
#include "pycore_gc.h" // struct _gc_runtime_state #include "pycore_gc.h" // struct _gc_runtime_state
#include "pycore_list.h" // struct _Py_list_state #include "pycore_list.h" // struct _Py_list_state
#include "pycore_global_objects.h" // struct _Py_interp_static_objects
#include "pycore_tuple.h" // struct _Py_tuple_state #include "pycore_tuple.h" // struct _Py_tuple_state
#include "pycore_typeobject.h" // struct type_cache #include "pycore_typeobject.h" // struct type_cache
#include "pycore_unicodeobject.h" // struct _Py_unicode_state #include "pycore_unicodeobject.h" // struct _Py_unicode_state
@ -207,6 +208,9 @@ struct _is {
struct callable_cache callable_cache; struct callable_cache callable_cache;
PyCodeObject *interpreter_trampoline; PyCodeObject *interpreter_trampoline;
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 following fields are here to avoid allocation during init.
The data is exposed through PyInterpreterState pointer fields. The data is exposed through PyInterpreterState pointer fields.
These fields should not be accessed directly outside of init. These fields should not be accessed directly outside of init.

View File

@ -77,6 +77,11 @@ extern "C" {
{ .threshold = 10, }, \ { .threshold = 10, }, \
}, \ }, \
}, \ }, \
.static_objects = { \
.singletons = { \
._not_used = 1, \
}, \
}, \
._initial_thread = _PyThreadState_INIT, \ ._initial_thread = _PyThreadState_INIT, \
} }

View File

@ -1744,7 +1744,7 @@ finalize_interp_types(PyInterpreterState *interp)
_PyUnicode_Fini(interp); _PyUnicode_Fini(interp);
_PyFloat_Fini(interp); _PyFloat_Fini(interp);
#ifdef Py_DEBUG #ifdef Py_DEBUG
_PyStaticObjects_CheckRefcnt(); _PyStaticObjects_CheckRefcnt(interp);
#endif #endif
} }

View File

@ -383,8 +383,10 @@ def generate_global_object_finalizers(generated_immortal_objects):
printer.write(START) printer.write(START)
printer.write('#ifdef Py_DEBUG') printer.write('#ifdef Py_DEBUG')
printer.write("static inline void") printer.write("static inline void")
with printer.block("_PyStaticObjects_CheckRefcnt(void)"): with printer.block(
printer.write('/* generated (see pycore_runtime_init_generated.h) */') "_PyStaticObjects_CheckRefcnt(PyInterpreterState *interp)"):
printer.write('/* generated runtime-global */')
printer.write('// (see pycore_runtime_init_generated.h)')
for ref in generated_immortal_objects: for ref in generated_immortal_objects:
printer.write(f'_PyStaticObject_CheckRefcnt({ref});') printer.write(f'_PyStaticObject_CheckRefcnt({ref});')
printer.write('/* non-generated */') printer.write('/* non-generated */')