aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-12-26 01:45:43 +0100
committerGitHub <noreply@github.com>2020-12-26 01:45:43 +0100
commit41010184880151d6ae02a226dbacc796e5c90d11 (patch)
tree5d87ed2b4392de3d7063b59f03d955b04f8b0eec /Include
parentAdd convolve() to the itertools recipes (GH-23928) (diff)
downloadcpython-41010184880151d6ae02a226dbacc796e5c90d11.tar.gz
cpython-41010184880151d6ae02a226dbacc796e5c90d11.tar.bz2
cpython-41010184880151d6ae02a226dbacc796e5c90d11.zip
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.
Diffstat (limited to 'Include')
-rw-r--r--Include/internal/pycore_interp.h22
-rw-r--r--Include/internal/pycore_object.h3
-rw-r--r--Include/internal/pycore_pylifecycle.h2
3 files changed, 26 insertions, 1 deletions
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 8c618025452..339c2c4c61f 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -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);
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index edd0031c3ef..3975765a46c 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -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().
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index d1c23c81791..c9e6947ae6c 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -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);