@@ -327,18 +327,6 @@ static unsigned int
327
327
_PyType_ClearCache (PyInterpreterState * interp )
328
328
{
329
329
struct type_cache * cache = & interp -> types .type_cache ;
330
- #if MCACHE_STATS
331
- size_t total = cache -> hits + cache -> collisions + cache -> misses ;
332
- fprintf (stderr , "-- Method cache hits = %zd (%d%%)\n" ,
333
- cache -> hits , (int ) (100.0 * cache -> hits / total ));
334
- fprintf (stderr , "-- Method cache true misses = %zd (%d%%)\n" ,
335
- cache -> misses , (int ) (100.0 * cache -> misses / total ));
336
- fprintf (stderr , "-- Method cache collisions = %zd (%d%%)\n" ,
337
- cache -> collisions , (int ) (100.0 * cache -> collisions / total ));
338
- fprintf (stderr , "-- Method cache size = %zd KiB\n" ,
339
- sizeof (cache -> hashtable ) / 1024 );
340
- #endif
341
-
342
330
// Set to None, rather than NULL, so _PyType_Lookup() can
343
331
// use Py_SETREF() rather than using slower Py_XSETREF().
344
332
type_cache_clear (cache , Py_None );
@@ -4148,6 +4136,24 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error)
4148
4136
return res ;
4149
4137
}
4150
4138
4139
+ /* Check if the "readied" PyUnicode name
4140
+ is a double-underscore special name. */
4141
+ static int
4142
+ is_dunder_name (PyObject * name )
4143
+ {
4144
+ Py_ssize_t length = PyUnicode_GET_LENGTH (name );
4145
+ int kind = PyUnicode_KIND (name );
4146
+ /* Special names contain at least "__x__" and are always ASCII. */
4147
+ if (length > 4 && kind == PyUnicode_1BYTE_KIND ) {
4148
+ const Py_UCS1 * characters = PyUnicode_1BYTE_DATA (name );
4149
+ return (
4150
+ ((characters [length - 2 ] == '_' ) && (characters [length - 1 ] == '_' )) &&
4151
+ ((characters [0 ] == '_' ) && (characters [1 ] == '_' ))
4152
+ );
4153
+ }
4154
+ return 0 ;
4155
+ }
4156
+
4151
4157
/* Internal API to look for a name through the MRO.
4152
4158
This returns a borrowed reference, and doesn't set an exception! */
4153
4159
PyObject *
@@ -4161,12 +4167,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
4161
4167
struct type_cache_entry * entry = & cache -> hashtable [h ];
4162
4168
if (entry -> version == type -> tp_version_tag &&
4163
4169
entry -> name == name ) {
4164
- #if MCACHE_STATS
4165
- cache -> hits ++ ;
4166
- #endif
4167
4170
assert (_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
4171
+ OBJECT_STAT_INC_COND (type_cache_hits , !is_dunder_name (name ));
4172
+ OBJECT_STAT_INC_COND (type_cache_dunder_hits , is_dunder_name (name ));
4168
4173
return entry -> value ;
4169
4174
}
4175
+ OBJECT_STAT_INC_COND (type_cache_misses , !is_dunder_name (name ));
4176
+ OBJECT_STAT_INC_COND (type_cache_dunder_misses , is_dunder_name (name ));
4170
4177
4171
4178
/* We may end up clearing live exceptions below, so make sure it's ours. */
4172
4179
assert (!PyErr_Occurred ());
@@ -4194,14 +4201,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
4194
4201
entry -> version = type -> tp_version_tag ;
4195
4202
entry -> value = res ; /* borrowed */
4196
4203
assert (_PyASCIIObject_CAST (name )-> hash != -1 );
4197
- #if MCACHE_STATS
4198
- if (entry -> name != Py_None && entry -> name != name ) {
4199
- cache -> collisions ++ ;
4200
- }
4201
- else {
4202
- cache -> misses ++ ;
4203
- }
4204
- #endif
4204
+ OBJECT_STAT_INC_COND (type_cache_collisions , entry -> name != Py_None && entry -> name != name );
4205
4205
assert (_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
4206
4206
Py_SETREF (entry -> name , Py_NewRef (name ));
4207
4207
}
@@ -4218,24 +4218,6 @@ _PyType_LookupId(PyTypeObject *type, _Py_Identifier *name)
4218
4218
return _PyType_Lookup (type , oname );
4219
4219
}
4220
4220
4221
- /* Check if the "readied" PyUnicode name
4222
- is a double-underscore special name. */
4223
- static int
4224
- is_dunder_name (PyObject * name )
4225
- {
4226
- Py_ssize_t length = PyUnicode_GET_LENGTH (name );
4227
- int kind = PyUnicode_KIND (name );
4228
- /* Special names contain at least "__x__" and are always ASCII. */
4229
- if (length > 4 && kind == PyUnicode_1BYTE_KIND ) {
4230
- const Py_UCS1 * characters = PyUnicode_1BYTE_DATA (name );
4231
- return (
4232
- ((characters [length - 2 ] == '_' ) && (characters [length - 1 ] == '_' )) &&
4233
- ((characters [0 ] == '_' ) && (characters [1 ] == '_' ))
4234
- );
4235
- }
4236
- return 0 ;
4237
- }
4238
-
4239
4221
/* This is similar to PyObject_GenericGetAttr(),
4240
4222
but uses _PyType_Lookup() instead of just looking in type->tp_dict. */
4241
4223
static PyObject *
0 commit comments