@@ -19,6 +19,12 @@ class object "PyObject *" "&PyBaseObject_Type"
19
19
20
20
#include "clinic/typeobject.c.h"
21
21
22
+ /* bpo-40521: Type method cache is shared by all subinterpreters */
23
+ #ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
24
+ # define MCACHE
25
+ #endif
26
+
27
+ #ifdef MCACHE
22
28
/* Support type attribute cache */
23
29
24
30
/* The cache can keep references to the names alive for longer than
@@ -47,6 +53,7 @@ struct method_cache_entry {
47
53
48
54
static struct method_cache_entry method_cache [1 << MCACHE_SIZE_EXP ];
49
55
static unsigned int next_version_tag = 0 ;
56
+ #endif
50
57
51
58
#define MCACHE_STATS 0
52
59
@@ -216,6 +223,7 @@ _PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_d
216
223
unsigned int
217
224
PyType_ClearCache (void )
218
225
{
226
+ #ifdef MCACHE
219
227
Py_ssize_t i ;
220
228
unsigned int cur_version_tag = next_version_tag - 1 ;
221
229
@@ -240,6 +248,9 @@ PyType_ClearCache(void)
240
248
/* mark all version tags as invalid */
241
249
PyType_Modified (& PyBaseObject_Type );
242
250
return cur_version_tag ;
251
+ #else
252
+ return 0 ;
253
+ #endif
243
254
}
244
255
245
256
void
@@ -350,6 +361,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
350
361
Py_TPFLAGS_VALID_VERSION_TAG );
351
362
}
352
363
364
+ #ifdef MCACHE
353
365
static int
354
366
assign_version_tag (PyTypeObject * type )
355
367
{
@@ -396,6 +408,7 @@ assign_version_tag(PyTypeObject *type)
396
408
type -> tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG ;
397
409
return 1 ;
398
410
}
411
+ #endif
399
412
400
413
401
414
static PyMemberDef type_members [] = {
@@ -3232,12 +3245,12 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
3232
3245
{
3233
3246
PyObject * res ;
3234
3247
int error ;
3235
- unsigned int h ;
3236
3248
3249
+ #ifdef MCACHE
3237
3250
if (MCACHE_CACHEABLE_NAME (name ) &&
3238
3251
_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG )) {
3239
3252
/* fast path */
3240
- h = MCACHE_HASH_METHOD (type , name );
3253
+ unsigned int h = MCACHE_HASH_METHOD (type , name );
3241
3254
if (method_cache [h ].version == type -> tp_version_tag &&
3242
3255
method_cache [h ].name == name ) {
3243
3256
#if MCACHE_STATS
@@ -3246,6 +3259,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
3246
3259
return method_cache [h ].value ;
3247
3260
}
3248
3261
}
3262
+ #endif
3249
3263
3250
3264
/* We may end up clearing live exceptions below, so make sure it's ours. */
3251
3265
assert (!PyErr_Occurred ());
@@ -3267,8 +3281,9 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
3267
3281
return NULL ;
3268
3282
}
3269
3283
3284
+ #ifdef MCACHE
3270
3285
if (MCACHE_CACHEABLE_NAME (name ) && assign_version_tag (type )) {
3271
- h = MCACHE_HASH_METHOD (type , name );
3286
+ unsigned int h = MCACHE_HASH_METHOD (type , name );
3272
3287
method_cache [h ].version = type -> tp_version_tag ;
3273
3288
method_cache [h ].value = res ; /* borrowed */
3274
3289
Py_INCREF (name );
@@ -3281,6 +3296,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
3281
3296
#endif
3282
3297
Py_SETREF (method_cache [h ].name , name );
3283
3298
}
3299
+ #endif
3284
3300
return res ;
3285
3301
}
3286
3302
0 commit comments