Skip to content

Commit 75c17fb

Browse files
Add name_count to pytype_slotdef and get rid of slotdefs_cache and resolve_slotdups
1 parent a853294 commit 75c17fb

4 files changed

Lines changed: 25 additions & 46 deletions

File tree

Include/cpython/descrobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct wrapperbase {
1616
const char *doc;
1717
int flags;
1818
PyObject *name_strobj;
19+
uint8_t name_count;
1920
};
2021

2122
/* Flags for above struct */

Include/internal/pycore_interp_structs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,6 @@ struct _Py_interp_cached_objects {
677677
PyTypeObject *paramspecargs_type;
678678
PyTypeObject *paramspeckwargs_type;
679679
PyTypeObject *constevaluator_type;
680-
PyObject *slotdefs_cache;
681680
};
682681

683682
struct _Py_interp_static_objects {

Objects/typeobject.c

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

11008-
/* Return a slot pointer for a given name, but ONLY if the attribute has
11009-
exactly one slot function. The name must be an interned string. */
11010-
static void **
11011-
resolve_slotdups(PyTypeObject *type, PyObject *name)
11012-
{
11013-
/* XXX Maybe this could be optimized more -- but is it worth it? */
11014-
11015-
PyInterpreterState *interp = _PyInterpreterState_GET();
11016-
PyObject *cache = _Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache);
11017-
assert(cache);
11018-
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);
11031-
}
11032-
11033-
return NULL;
11034-
}
11035-
1103611008

1103711009
/* Common code for update_slots_callback() and fixup_slot_dispatchers().
1103811010
*
@@ -11139,7 +11111,10 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, PyObject *mro_dict)
1113911111
}
1114011112
if (Py_IS_TYPE(descr, &PyWrapperDescr_Type) &&
1114111113
((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_strobj) {
11142-
void **tptr = resolve_slotdups(type, p->name_strobj);
11114+
void **tptr = NULL;
11115+
if (p->name_count == 1)
11116+
tptr = slotptr(type, p->offset);
11117+
1114311118
if (tptr == NULL || tptr == ptr)
1114411119
generic = p->function;
1114511120
d = (PyWrapperDescrObject *)descr;
@@ -11322,21 +11297,15 @@ update_all_slots(PyTypeObject* type)
1132211297
int
1132311298
_PyType_InitSlotDefsCache(PyInterpreterState *interp)
1132411299
{
11325-
PyObject *cache;
11326-
PyObject *bytes = NULL;
11327-
11328-
assert (!_Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache));
11329-
PyInterpreterState *main = interp->runtime->interpreters.main;
11330-
if (interp != main) {
11331-
cache = _Py_INTERP_CACHED_OBJECT(main, slotdefs_cache);
11332-
_Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache) = Py_NewRef(cache);
11300+
if (interp != interp->runtime->interpreters.main) {
1133311301
return 0;
1133411302
}
11335-
11336-
cache = PyDict_New();
11303+
PyObject *bytes = NULL;
11304+
PyObject *cache = PyDict_New();
1133711305
if (!cache) {
11338-
goto error;
11306+
return -1;
1133911307
}
11308+
1134011309
pytype_slotdef *p;
1134111310
Py_ssize_t idx = 0;
1134211311
for (p = slotdefs; p->name_strobj; p++, idx++) {
@@ -11380,12 +11349,25 @@ _PyType_InitSlotDefsCache(PyInterpreterState *interp)
1138011349
Py_CLEAR(bytes);
1138111350
}
1138211351

11383-
_Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache) = cache;
11352+
Py_ssize_t pos=0;
11353+
PyObject *key=NULL;
11354+
PyObject *value=NULL;
11355+
while (PyDict_Next(cache, &pos, &key, &value)) {
11356+
uint8_t *data = (uint8_t *)PyBytes_AS_STRING(value);
11357+
uint8_t n = data[0];
11358+
uint8_t i = 0;
11359+
for(; i < n; i++) {
11360+
uint8_t idx = data[i + 1];
11361+
slotdefs[idx].name_count = n;
11362+
}
11363+
}
11364+
11365+
Py_DECREF(cache);
1138411366
return 0;
1138511367

1138611368
error:
1138711369
Py_XDECREF(bytes);
11388-
Py_XDECREF(cache);
11370+
Py_DECREF(cache);
1138911371
return -1;
1139011372
}
1139111373

Python/pystate.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,6 @@ init_interpreter(PyInterpreterState *interp,
700700
#endif
701701

702702

703-
interp->cached_objects.slotdefs_cache = NULL;
704703
interp->_initialized = 1;
705704
return _PyStatus_OK();
706705
}
@@ -831,8 +830,6 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
831830
_PyErr_Clear(tstate);
832831
}
833832

834-
Py_CLEAR(interp->cached_objects.slotdefs_cache);
835-
836833
// Clear the current/main thread state last.
837834
_Py_FOR_EACH_TSTATE_BEGIN(interp, p) {
838835
// See https://github.com/python/cpython/issues/102126

0 commit comments

Comments
 (0)