@@ -159,18 +159,28 @@ managed_static_type_index_clear(PyTypeObject *self)
159159 self -> tp_subclasses = NULL ;
160160}
161161
162- static inline managed_static_type_state *
163- static_builtin_state_get (PyInterpreterState * interp , PyTypeObject * self )
162+ static PyTypeObject *
163+ static_ext_type_lookup (PyInterpreterState * interp , size_t index ,
164+ int64_t * p_interp_count )
164165{
165- return & (interp -> types .builtins .initialized [
166- managed_static_type_index_get (self )]);
167- }
166+ assert (interp -> runtime == & _PyRuntime );
167+ assert (index < _Py_MAX_MANAGED_STATIC_EXT_TYPES );
168168
169- static inline managed_static_type_state *
170- static_ext_type_state_get (PyInterpreterState * interp , PyTypeObject * self )
171- {
172- return & (interp -> types .for_extensions .initialized [
173- managed_static_type_index_get (self )]);
169+ size_t full_index = index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES ;
170+ int64_t interp_count =
171+ _PyRuntime .types .managed_static .types [full_index ].interp_count ;
172+ assert ((interp_count == 0 ) ==
173+ (_PyRuntime .types .managed_static .types [full_index ].type == NULL ));
174+ * p_interp_count = interp_count ;
175+
176+ PyTypeObject * type = interp -> types .for_extensions .initialized [index ].type ;
177+ if (type == NULL ) {
178+ return NULL ;
179+ }
180+ assert (!interp -> types .for_extensions .initialized [index ].isbuiltin );
181+ assert (type == _PyRuntime .types .managed_static .types [full_index ].type );
182+ assert (managed_static_type_index_is_set (type ));
183+ return type ;
174184}
175185
176186static managed_static_type_state *
@@ -202,6 +212,8 @@ static void
202212managed_static_type_state_init (PyInterpreterState * interp , PyTypeObject * self ,
203213 int isbuiltin , int initial )
204214{
215+ assert (interp -> runtime == & _PyRuntime );
216+
205217 size_t index ;
206218 if (initial ) {
207219 assert (!managed_static_type_index_is_set (self ));
@@ -228,6 +240,21 @@ managed_static_type_state_init(PyInterpreterState *interp, PyTypeObject *self,
228240 assert (index < _Py_MAX_MANAGED_STATIC_EXT_TYPES );
229241 }
230242 }
243+ size_t full_index = isbuiltin
244+ ? index
245+ : index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES ;
246+
247+ assert ((initial == 1 ) ==
248+ (_PyRuntime .types .managed_static .types [full_index ].interp_count == 0 ));
249+ _PyRuntime .types .managed_static .types [full_index ].interp_count += 1 ;
250+
251+ if (initial ) {
252+ assert (_PyRuntime .types .managed_static .types [full_index ].type == NULL );
253+ _PyRuntime .types .managed_static .types [full_index ].type = self ;
254+ }
255+ else {
256+ assert (_PyRuntime .types .managed_static .types [full_index ].type == self );
257+ }
231258
232259 managed_static_type_state * state = isbuiltin
233260 ? & (interp -> types .builtins .initialized [index ])
@@ -256,15 +283,28 @@ static void
256283managed_static_type_state_clear (PyInterpreterState * interp , PyTypeObject * self ,
257284 int isbuiltin , int final )
258285{
286+ size_t index = managed_static_type_index_get (self );
287+ size_t full_index = isbuiltin
288+ ? index
289+ : index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES ;
290+
259291 managed_static_type_state * state = isbuiltin
260- ? static_builtin_state_get (interp , self )
261- : static_ext_type_state_get (interp , self );
292+ ? & (interp -> types .builtins .initialized [index ])
293+ : & (interp -> types .for_extensions .initialized [index ]);
294+ assert (state != NULL );
295+
296+ assert (_PyRuntime .types .managed_static .types [full_index ].interp_count > 0 );
297+ assert (_PyRuntime .types .managed_static .types [full_index ].type == state -> type );
262298
263299 assert (state -> type != NULL );
264300 state -> type = NULL ;
265301 assert (state -> tp_weaklist == NULL ); // It was already cleared out.
266302
303+ _PyRuntime .types .managed_static .types [full_index ].interp_count -= 1 ;
267304 if (final ) {
305+ assert (!_PyRuntime .types .managed_static .types [full_index ].interp_count );
306+ _PyRuntime .types .managed_static .types [full_index ].type = NULL ;
307+
268308 managed_static_type_index_clear (self );
269309 }
270310
@@ -840,8 +880,12 @@ _PyTypes_Fini(PyInterpreterState *interp)
840880 struct type_cache * cache = & interp -> types .type_cache ;
841881 type_cache_clear (cache , NULL );
842882
883+ // All the managed static types should have been finalized already.
884+ assert (interp -> types .for_extensions .num_initialized == 0 );
885+ for (size_t i = 0 ; i < _Py_MAX_MANAGED_STATIC_EXT_TYPES ; i ++ ) {
886+ assert (interp -> types .for_extensions .initialized [i ].type == NULL );
887+ }
843888 assert (interp -> types .builtins .num_initialized == 0 );
844- // All the static builtin types should have been finalized already.
845889 for (size_t i = 0 ; i < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES ; i ++ ) {
846890 assert (interp -> types .builtins .initialized [i ].type == NULL );
847891 }
@@ -5834,9 +5878,20 @@ fini_static_type(PyInterpreterState *interp, PyTypeObject *type,
58345878}
58355879
58365880void
5837- _PyStaticType_FiniForExtension (PyInterpreterState * interp , PyTypeObject * type , int final )
5881+ _PyTypes_FiniExtTypes (PyInterpreterState * interp )
58385882{
5839- fini_static_type (interp , type , 0 , final );
5883+ for (size_t i = _Py_MAX_MANAGED_STATIC_EXT_TYPES ; i > 0 ; i -- ) {
5884+ if (interp -> types .for_extensions .num_initialized == 0 ) {
5885+ break ;
5886+ }
5887+ int64_t count = 0 ;
5888+ PyTypeObject * type = static_ext_type_lookup (interp , i - 1 , & count );
5889+ if (type == NULL ) {
5890+ continue ;
5891+ }
5892+ int final = (count == 1 );
5893+ fini_static_type (interp , type , 0 , final );
5894+ }
58405895}
58415896
58425897void
0 commit comments