summaryrefslogtreecommitdiffstats
path: root/Objects/typeobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r--Objects/typeobject.c64
1 files changed, 23 insertions, 41 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 2c3b395..a96f993 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -327,18 +327,6 @@ static unsigned int
_PyType_ClearCache(PyInterpreterState *interp)
{
struct type_cache *cache = &interp->types.type_cache;
-#if MCACHE_STATS
- size_t total = cache->hits + cache->collisions + cache->misses;
- fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n",
- cache->hits, (int) (100.0 * cache->hits / total));
- fprintf(stderr, "-- Method cache true misses = %zd (%d%%)\n",
- cache->misses, (int) (100.0 * cache->misses / total));
- fprintf(stderr, "-- Method cache collisions = %zd (%d%%)\n",
- cache->collisions, (int) (100.0 * cache->collisions / total));
- fprintf(stderr, "-- Method cache size = %zd KiB\n",
- sizeof(cache->hashtable) / 1024);
-#endif
-
// Set to None, rather than NULL, so _PyType_Lookup() can
// use Py_SETREF() rather than using slower Py_XSETREF().
type_cache_clear(cache, Py_None);
@@ -4148,6 +4136,24 @@ done:
return res;
}
+/* Check if the "readied" PyUnicode name
+ is a double-underscore special name. */
+static int
+is_dunder_name(PyObject *name)
+{
+ Py_ssize_t length = PyUnicode_GET_LENGTH(name);
+ int kind = PyUnicode_KIND(name);
+ /* Special names contain at least "__x__" and are always ASCII. */
+ if (length > 4 && kind == PyUnicode_1BYTE_KIND) {
+ const Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name);
+ return (
+ ((characters[length-2] == '_') && (characters[length-1] == '_')) &&
+ ((characters[0] == '_') && (characters[1] == '_'))
+ );
+ }
+ return 0;
+}
+
/* Internal API to look for a name through the MRO.
This returns a borrowed reference, and doesn't set an exception! */
PyObject *
@@ -4161,12 +4167,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
struct type_cache_entry *entry = &cache->hashtable[h];
if (entry->version == type->tp_version_tag &&
entry->name == name) {
-#if MCACHE_STATS
- cache->hits++;
-#endif
assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG));
+ OBJECT_STAT_INC_COND(type_cache_hits, !is_dunder_name(name));
+ OBJECT_STAT_INC_COND(type_cache_dunder_hits, is_dunder_name(name));
return entry->value;
}
+ OBJECT_STAT_INC_COND(type_cache_misses, !is_dunder_name(name));
+ OBJECT_STAT_INC_COND(type_cache_dunder_misses, is_dunder_name(name));
/* We may end up clearing live exceptions below, so make sure it's ours. */
assert(!PyErr_Occurred());
@@ -4194,14 +4201,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
entry->version = type->tp_version_tag;
entry->value = res; /* borrowed */
assert(_PyASCIIObject_CAST(name)->hash != -1);
-#if MCACHE_STATS
- if (entry->name != Py_None && entry->name != name) {
- cache->collisions++;
- }
- else {
- cache->misses++;
- }
-#endif
+ OBJECT_STAT_INC_COND(type_cache_collisions, entry->name != Py_None && entry->name != name);
assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG));
Py_SETREF(entry->name, Py_NewRef(name));
}
@@ -4218,24 +4218,6 @@ _PyType_LookupId(PyTypeObject *type, _Py_Identifier *name)
return _PyType_Lookup(type, oname);
}
-/* Check if the "readied" PyUnicode name
- is a double-underscore special name. */
-static int
-is_dunder_name(PyObject *name)
-{
- Py_ssize_t length = PyUnicode_GET_LENGTH(name);
- int kind = PyUnicode_KIND(name);
- /* Special names contain at least "__x__" and are always ASCII. */
- if (length > 4 && kind == PyUnicode_1BYTE_KIND) {
- const Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name);
- return (
- ((characters[length-2] == '_') && (characters[length-1] == '_')) &&
- ((characters[0] == '_') && (characters[1] == '_'))
- );
- }
- return 0;
-}
-
/* This is similar to PyObject_GenericGetAttr(),
but uses _PyType_Lookup() instead of just looking in type->tp_dict. */
static PyObject *