bpo-43441: Fix _PyType_ClearCache() for subinterpreters (GH-24822)

_PyType_ClearCache() now only resets next_version_tag in the main interpreter.

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
junyixie 2021-03-13 21:38:36 +08:00 committed by GitHub
parent 5bd1059184
commit 75048c8a38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 5 deletions

View File

@ -39,6 +39,7 @@ class object "PyObject *" "&PyBaseObject_Type"
PyUnicode_IS_READY(name) && \ PyUnicode_IS_READY(name) && \
(PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE) (PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE)
// bpo-42745: next_version_tag remains shared by all interpreters because of static types
// Used to set PyTypeObject.tp_version_tag // Used to set PyTypeObject.tp_version_tag
static unsigned int next_version_tag = 0; static unsigned int next_version_tag = 0;
@ -252,8 +253,9 @@ _PyType_InitCache(PyInterpreterState *interp)
static unsigned int static unsigned int
_PyType_ClearCache(struct type_cache *cache) _PyType_ClearCache(PyInterpreterState *interp)
{ {
struct type_cache *cache = &interp->type_cache;
#if MCACHE_STATS #if MCACHE_STATS
size_t total = cache->hits + cache->collisions + cache->misses; size_t total = cache->hits + cache->collisions + cache->misses;
fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n", fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n",
@ -267,7 +269,10 @@ _PyType_ClearCache(struct type_cache *cache)
#endif #endif
unsigned int cur_version_tag = next_version_tag - 1; unsigned int cur_version_tag = next_version_tag - 1;
if (_Py_IsMainInterpreter(interp)) {
next_version_tag = 0; next_version_tag = 0;
}
type_cache_clear(cache, 0); type_cache_clear(cache, 0);
return cur_version_tag; return cur_version_tag;
@ -277,15 +282,15 @@ _PyType_ClearCache(struct type_cache *cache)
unsigned int unsigned int
PyType_ClearCache(void) PyType_ClearCache(void)
{ {
struct type_cache *cache = get_type_cache(); PyInterpreterState *interp = _PyInterpreterState_GET();
return _PyType_ClearCache(cache); return _PyType_ClearCache(interp);
} }
void void
_PyType_Fini(PyInterpreterState *interp) _PyType_Fini(PyInterpreterState *interp)
{ {
_PyType_ClearCache(&interp->type_cache); _PyType_ClearCache(interp);
if (_Py_IsMainInterpreter(interp)) { if (_Py_IsMainInterpreter(interp)) {
clear_slotdefs(); clear_slotdefs();
} }