bpo-42745: Make the type cache per-interpreter (GH-23947)

Make the type attribute lookup cache per-interpreter.

Add private _PyType_InitCache() function, called by PyInterpreterState_New().

Continue to share next_version_tag between interpreters, since static
types are still shared by interpreters.

Remove MCACHE macro: the cache is no longer disabled if the
EXPERIMENTAL_ISOLATED_SUBINTERPRETERS macro is defined.
This commit is contained in:
Victor Stinner 2020-12-26 01:45:43 +01:00 committed by GitHub
parent 77fde8dc16
commit 4101018488
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 90 deletions

View file

@ -180,6 +180,27 @@ struct atexit_state {
};
// Type attribute lookup cache: speed up attribute and method lookups,
// see _PyType_Lookup().
struct type_cache_entry {
unsigned int version; // initialized from type->tp_version_tag
PyObject *name; // reference to exactly a str or None
PyObject *value; // borrowed reference or NULL
};
#define MCACHE_SIZE_EXP 12
#define MCACHE_STATS 0
struct type_cache {
struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
#if MCACHE_STATS
size_t hits;
size_t misses;
size_t collisions;
#endif
};
/* interpreter state */
#define _PY_NSMALLPOSINTS 257
@ -284,6 +305,7 @@ struct _is {
struct _Py_exc_state exc_state;
struct ast_state ast;
struct type_cache type_cache;
};
extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);

View file

@ -27,6 +27,9 @@ _PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
return ((type->tp_flags & feature) != 0);
}
extern void _PyType_InitCache(PyInterpreterState *interp);
/* Inline functions trading binary compatibility for speed:
_PyObject_Init() is the fast version of PyObject_Init(), and
_PyObject_InitVar() is the fast version of PyObject_InitVar().

View file

@ -76,7 +76,7 @@ extern void _PyExc_Fini(PyThreadState *tstate);
extern void _PyImport_Fini(void);
extern void _PyImport_Fini2(void);
extern void _PyGC_Fini(PyThreadState *tstate);
extern void _PyType_Fini(void);
extern void _PyType_Fini(PyThreadState *tstate);
extern void _Py_HashRandomization_Fini(void);
extern void _PyUnicode_Fini(PyThreadState *tstate);
extern void _PyUnicode_ClearInterned(PyThreadState *tstate);