@@ -159,18 +159,28 @@ managed_static_type_index_clear(PyTypeObject *self)
159
159
self -> tp_subclasses = NULL ;
160
160
}
161
161
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 )
164
165
{
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 );
168
168
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 ;
174
184
}
175
185
176
186
static managed_static_type_state *
@@ -202,6 +212,8 @@ static void
202
212
managed_static_type_state_init (PyInterpreterState * interp , PyTypeObject * self ,
203
213
int isbuiltin , int initial )
204
214
{
215
+ assert (interp -> runtime == & _PyRuntime );
216
+
205
217
size_t index ;
206
218
if (initial ) {
207
219
assert (!managed_static_type_index_is_set (self ));
@@ -228,6 +240,21 @@ managed_static_type_state_init(PyInterpreterState *interp, PyTypeObject *self,
228
240
assert (index < _Py_MAX_MANAGED_STATIC_EXT_TYPES );
229
241
}
230
242
}
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
+ }
231
258
232
259
managed_static_type_state * state = isbuiltin
233
260
? & (interp -> types .builtins .initialized [index ])
@@ -256,15 +283,28 @@ static void
256
283
managed_static_type_state_clear (PyInterpreterState * interp , PyTypeObject * self ,
257
284
int isbuiltin , int final )
258
285
{
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
+
259
291
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 );
262
298
263
299
assert (state -> type != NULL );
264
300
state -> type = NULL ;
265
301
assert (state -> tp_weaklist == NULL ); // It was already cleared out.
266
302
303
+ _PyRuntime .types .managed_static .types [full_index ].interp_count -= 1 ;
267
304
if (final ) {
305
+ assert (!_PyRuntime .types .managed_static .types [full_index ].interp_count );
306
+ _PyRuntime .types .managed_static .types [full_index ].type = NULL ;
307
+
268
308
managed_static_type_index_clear (self );
269
309
}
270
310
@@ -840,8 +880,12 @@ _PyTypes_Fini(PyInterpreterState *interp)
840
880
struct type_cache * cache = & interp -> types .type_cache ;
841
881
type_cache_clear (cache , NULL );
842
882
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
+ }
843
888
assert (interp -> types .builtins .num_initialized == 0 );
844
- // All the static builtin types should have been finalized already.
845
889
for (size_t i = 0 ; i < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES ; i ++ ) {
846
890
assert (interp -> types .builtins .initialized [i ].type == NULL );
847
891
}
@@ -5674,9 +5718,20 @@ fini_static_type(PyInterpreterState *interp, PyTypeObject *type,
5674
5718
}
5675
5719
5676
5720
void
5677
- _PyStaticType_FiniForExtension (PyInterpreterState * interp , PyTypeObject * type , int final )
5721
+ _PyTypes_FiniExtTypes (PyInterpreterState * interp )
5678
5722
{
5679
- fini_static_type (interp , type , 0 , final );
5723
+ for (size_t i = _Py_MAX_MANAGED_STATIC_EXT_TYPES ; i > 0 ; i -- ) {
5724
+ if (interp -> types .for_extensions .num_initialized == 0 ) {
5725
+ break ;
5726
+ }
5727
+ int64_t count = 0 ;
5728
+ PyTypeObject * type = static_ext_type_lookup (interp , i - 1 , & count );
5729
+ if (type == NULL ) {
5730
+ continue ;
5731
+ }
5732
+ int final = (count == 1 );
5733
+ fini_static_type (interp , type , 0 , final );
5734
+ }
5680
5735
}
5681
5736
5682
5737
void
0 commit comments