diff --git a/Include/internal/pycore_global_objects.h b/Include/internal/pycore_global_objects.h
index 82e89db7b1b75070e428e4d925e0a4c9e6509640..3561f686a0de5c1f2077d3cbc493196c90cdd3c1 100644
--- a/Include/internal/pycore_global_objects.h
+++ b/Include/internal/pycore_global_objects.h
@@ -49,6 +49,24 @@ struct _Py_global_objects {
     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
 }
diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h
index 7bf31841ff5dad481e8c6a3d4ec28bfdfff0b37c..59001dc950925b29b0299dae560742ee59506814 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -24,8 +24,9 @@ _PyStaticObject_CheckRefcnt(PyObject *obj) {
 /* The following is auto-generated by Tools/build/generate_global_objects.py. */
 #ifdef Py_DEBUG
 static inline void
-_PyStaticObjects_CheckRefcnt(void) {
-    /* generated (see pycore_runtime_init_generated.h) */
+_PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
+    /* 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 + -4]);
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -3]);
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 068b0a700af5361c6ea58d069da5f40f6325f2b6..976e16a3742bda45f8c32b54db5169f6bad41ee5 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -20,6 +20,7 @@ extern "C" {
 #include "pycore_genobject.h"     // struct _Py_async_gen_state
 #include "pycore_gc.h"            // struct _gc_runtime_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_typeobject.h"    // struct type_cache
 #include "pycore_unicodeobject.h" // struct _Py_unicode_state
@@ -207,6 +208,9 @@ struct _is {
     struct callable_cache callable_cache;
     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 data is exposed through PyInterpreterState pointer fields.
        These fields should not be accessed directly outside of init.
diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h
index 4e8dd7b8a0fb5a66d9a66f9c4227dd3191951fb8..41a7730490abe9659e8ef06eead34c6bc7af1a18 100644
--- a/Include/internal/pycore_runtime_init.h
+++ b/Include/internal/pycore_runtime_init.h
@@ -77,6 +77,11 @@ extern "C" {
                 { .threshold = 10, }, \
             }, \
         }, \
+        .static_objects = { \
+            .singletons = { \
+                ._not_used = 1, \
+            }, \
+        }, \
         ._initial_thread = _PyThreadState_INIT, \
     }
 
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 13519762fa87bfb445b4ee628d09d115debc6882..3991089b38c4514e5bb9e7670283150fdd752259 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1744,7 +1744,7 @@ finalize_interp_types(PyInterpreterState *interp)
     _PyUnicode_Fini(interp);
     _PyFloat_Fini(interp);
 #ifdef Py_DEBUG
-    _PyStaticObjects_CheckRefcnt();
+    _PyStaticObjects_CheckRefcnt(interp);
 #endif
 }
 
diff --git a/Tools/build/generate_global_objects.py b/Tools/build/generate_global_objects.py
index 815045c27c18920856c919db922422e33eaa921f..b4243273ff4f6ce94657d2aae2df5f4cf088a0ce 100644
--- a/Tools/build/generate_global_objects.py
+++ b/Tools/build/generate_global_objects.py
@@ -383,8 +383,10 @@ def generate_global_object_finalizers(generated_immortal_objects):
         printer.write(START)
         printer.write('#ifdef Py_DEBUG')
         printer.write("static inline void")
-        with printer.block("_PyStaticObjects_CheckRefcnt(void)"):
-            printer.write('/* generated (see pycore_runtime_init_generated.h) */')
+        with printer.block(
+                "_PyStaticObjects_CheckRefcnt(PyInterpreterState *interp)"):
+            printer.write('/* generated runtime-global */')
+            printer.write('// (see pycore_runtime_init_generated.h)')
             for ref in generated_immortal_objects:
                 printer.write(f'_PyStaticObject_CheckRefcnt({ref});')
             printer.write('/* non-generated */')