Skip to content

Commit a853294

Browse files
Do not iterate slotdefs_cache just check dups count
1 parent 79a165d commit a853294

File tree

1 file changed

+16
-75
lines changed

1 file changed

+16
-75
lines changed

Objects/typeobject.c

Lines changed: 16 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -11005,91 +11005,32 @@ slotptr(PyTypeObject *type, int ioffset)
1100511005
return (void **)ptr;
1100611006
}
1100711007

11008-
static int
11009-
fill_type_slots_cache_from_slotdefs_cache(PyInterpreterState *interp,
11010-
PyObject *name)
11011-
{
11012-
#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs)
11013-
11014-
PyObject *cache = _Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache);
11015-
if (cache) {
11016-
11017-
PyObject* bytes = PyDict_GetItemWithError(cache, name);
11018-
if (PyErr_Occurred()) {
11019-
PyErr_Clear();
11020-
return -1;
11021-
}
11022-
11023-
if (bytes != NULL) {
11024-
assert(PyBytes_CheckExact(bytes));
11025-
11026-
uint8_t *data = (uint8_t *)PyBytes_AS_STRING(bytes);
11027-
uint8_t n = data[0];
11028-
11029-
assert(n < MAX_EQUIV);
11030-
11031-
pytype_slotdef **pp = ptrs;
11032-
for(uint8_t i = 0; i < n; i++) {
11033-
uint8_t idx = data[i + 1];
11034-
assert (idx < Py_ARRAY_LENGTH(slotdefs));
11035-
11036-
*pp++ = &slotdefs[idx];
11037-
}
11038-
*pp = NULL;
11039-
11040-
return 1;
11041-
}
11042-
}
11043-
11044-
return 0;
11045-
11046-
#undef ptrs
11047-
}
11048-
1104911008
/* Return a slot pointer for a given name, but ONLY if the attribute has
1105011009
exactly one slot function. The name must be an interned string. */
1105111010
static void **
1105211011
resolve_slotdups(PyTypeObject *type, PyObject *name)
1105311012
{
1105411013
/* XXX Maybe this could be optimized more -- but is it worth it? */
1105511014

11056-
/* pname and ptrs act as a little cache */
1105711015
PyInterpreterState *interp = _PyInterpreterState_GET();
11058-
#define pname _Py_INTERP_CACHED_OBJECT(interp, type_slots_pname)
11059-
#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs)
11060-
pytype_slotdef *p, **pp;
11061-
void **res, **ptr;
11062-
11063-
if (pname != name) {
11064-
/* Collect all slotdefs that match name into ptrs. */
11065-
pname = name;
11066-
11067-
int rc = fill_type_slots_cache_from_slotdefs_cache(interp, name);
11068-
if (rc <= 0) {
11069-
pp = ptrs;
11070-
for (p = slotdefs; p->name_strobj; p++) {
11071-
if (p->name_strobj == name)
11072-
*pp++ = p;
11073-
}
11074-
*pp = NULL;
11075-
}
11076-
}
11016+
PyObject *cache = _Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache);
11017+
assert(cache);
1107711018

11078-
/* Look in all slots of the type matching the name. If exactly one of these
11079-
has a filled-in slot, return a pointer to that slot.
11080-
Otherwise, return NULL. */
11081-
res = NULL;
11082-
for (pp = ptrs; *pp; pp++) {
11083-
ptr = slotptr(type, (*pp)->offset);
11084-
if (ptr == NULL || *ptr == NULL)
11085-
continue;
11086-
if (res != NULL)
11087-
return NULL;
11088-
res = ptr;
11019+
PyObject* bytes = PyDict_GetItemWithError(cache, name);
11020+
assert(!PyErr_Occurred());
11021+
assert(bytes);
11022+
assert(PyBytes_CheckExact(bytes));
11023+
11024+
uint8_t *data = (uint8_t *)PyBytes_AS_STRING(bytes);
11025+
uint8_t n = data[0];
11026+
11027+
assert(n < MAX_EQUIV);
11028+
if (n == 1) {
11029+
pytype_slotdef *p = &slotdefs[data[1]];
11030+
return slotptr(type, p->offset);
1108911031
}
11090-
return res;
11091-
#undef pname
11092-
#undef ptrs
11032+
11033+
return NULL;
1109311034
}
1109411035

1109511036

0 commit comments

Comments
 (0)