Skip to content

Commit bac95a5

Browse files
Move slotdefs_cache to interp
1 parent bba66d6 commit bac95a5

File tree

3 files changed

+80
-90
lines changed

3 files changed

+80
-90
lines changed

Include/internal/pycore_interp_structs.h

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

682683
struct _Py_interp_static_objects {

Objects/typeobject.c

Lines changed: 75 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -10962,10 +10962,6 @@ static pytype_slotdef slotdefs[] = {
1096210962
{NULL}
1096310963
};
1096410964

10965-
/* {name: [pytype_slotdef]}
10966-
*/
10967-
static PyObject *slotdefs_cache = NULL;
10968-
1096910965

1097010966
/* Given a type pointer and an offset gotten from a slotdef entry, return a
1097110967
pointer to the actual slot. This is not quite the same as simply adding
@@ -11014,61 +11010,55 @@ slotptr(PyTypeObject *type, int ioffset)
1101411010
static void **
1101511011
resolve_slotdups(PyTypeObject *type, PyObject *name)
1101611012
{
11013+
PyInterpreterState *interp = _PyInterpreterState_GET();
11014+
1101711015
/* XXX Maybe this could be optimized more -- but is it worth it? */
1101811016
void **res, **ptr;
1101911017
res = NULL;
1102011018

11021-
if (slotdefs_cache) {
11019+
PyObject *cache = Py_XNewRef(interp->cached_objects.slotdefs_cache);
11020+
if (cache) {
1102211021
int rc = 0;
11023-
// PyObject *cache = Py_NewRef(slotdefs_cache);
11024-
Py_BEGIN_CRITICAL_SECTION(slotdefs_cache);
11025-
PyObject *cache = slotdefs_cache;
11026-
assert(Py_REFCNT(cache) >= 1);
11027-
11028-
Py_INCREF(cache);
11029-
assert(Py_REFCNT(cache) > 1);
11022+
// Py_BEGIN_CRITICAL_SECTION(cache);
1103011023

1103111024
PyObject* list=NULL;
1103211025
rc = PyDict_GetItemRef(cache, name, &list);
11033-
assert(Py_REFCNT(cache) > 1);
1103411026
if (rc > 0) {
1103511027

11036-
// assert(list);
11037-
// Py_ssize_t n = PyList_Size(list);
11038-
// assert(n >= 0);
11039-
// Py_ssize_t i;
11040-
// for(i = 0; i < n; i++) {
11041-
// PyObject *py_idx = PyList_GET_ITEM(list, i);
11042-
// assert(PyLong_Check(py_idx));
11043-
// Py_ssize_t idx = PyLong_AsSsize_t(py_idx);
11044-
// assert (idx < Py_ARRAY_LENGTH(slotdefs));
11045-
// pytype_slotdef *x = &slotdefs[idx];
11046-
// ptr = slotptr(type, x->offset);
11047-
// if (ptr == NULL || *ptr == NULL) {
11048-
// continue;
11049-
// }
11050-
// if (res != NULL) {
11051-
// res = NULL;
11052-
// break;
11053-
// }
11054-
// res = ptr;
11055-
// }
11028+
assert(list);
11029+
Py_ssize_t n = PyList_Size(list);
11030+
assert(n >= 0);
11031+
Py_ssize_t i;
11032+
for(i = 0; i < n; i++) {
11033+
PyObject *py_idx = PyList_GET_ITEM(list, i);
11034+
assert(PyLong_Check(py_idx));
11035+
Py_ssize_t idx = PyLong_AsSsize_t(py_idx);
11036+
assert (idx < Py_ARRAY_LENGTH(slotdefs));
11037+
pytype_slotdef *x = &slotdefs[idx];
11038+
ptr = slotptr(type, x->offset);
11039+
if (ptr == NULL || *ptr == NULL) {
11040+
continue;
11041+
}
11042+
if (res != NULL) {
11043+
res = NULL;
11044+
break;
11045+
}
11046+
res = ptr;
11047+
}
1105611048
assert(Py_REFCNT(list) > 1);
1105711049
Py_DECREF(list);
1105811050
} else if (rc < 0) {
1105911051
PyErr_Clear();
1106011052
}
1106111053

11062-
assert(Py_REFCNT(cache) > 1);
1106311054
Py_DECREF(cache);
11064-
Py_END_CRITICAL_SECTION();
11055+
// Py_END_CRITICAL_SECTION();
1106511056
if (rc > 0) {
1106611057
return res;
1106711058
}
1106811059
}
1106911060

1107011061
/* pname and ptrs act as a little cache */
11071-
PyInterpreterState *interp = _PyInterpreterState_GET();
1107211062
#define pname _Py_INTERP_CACHED_OBJECT(interp, type_slots_pname)
1107311063
#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs)
1107411064
pytype_slotdef *p, **pp;
@@ -11360,68 +11350,63 @@ fixup_slot_dispatchers(PyTypeObject *type)
1136011350
}
1136111351
}
1136211352

11363-
if (!slotdefs_cache) {
11364-
PyObject *cache = PyDict_New();
11353+
PyInterpreterState *interp = _PyInterpreterState_GET();
11354+
if (!interp->cached_objects.slotdefs_cache) {
11355+
11356+
PyObject* cache = PyDict_New();
1136511357
if (cache) {
1136611358
pytype_slotdef *p;
1136711359
Py_ssize_t idx = 0;
1136811360
for (p = slotdefs; p->name_strobj; p++, idx++) {
11369-
// Py_hash_t hash = _PyObject_HashFast(p->name_strobj);
11370-
// if (hash == -1) {
11371-
// Py_CLEAR(cache);
11372-
// break;
11373-
// }
11374-
11375-
// PyObject *list;
11376-
// if (_PyDict_GetItemRef_KnownHash_LockHeld((PyDictObject *)cache, p->name_strobj, hash, &list) < 0) {
11377-
// Py_CLEAR(cache);
11378-
// break;
11379-
// }
11380-
11381-
// if (!list) {
11382-
// list = PyList_New(0);
11383-
// if (!list) {
11384-
// Py_CLEAR(cache);
11385-
// break;
11386-
// }
11387-
11388-
// if (_PyDict_SetItem_KnownHash_LockHeld((PyDictObject *)cache, p->name_strobj, list, hash) < 0) {
11389-
// Py_DECREF(list);
11390-
// Py_CLEAR(cache);
11391-
// break;
11392-
// }
11393-
// }
11394-
11395-
// PyObject *py_idx = PyLong_FromSsize_t(idx);
11396-
// if (!py_idx) {
11397-
// Py_DECREF(list);
11398-
// Py_CLEAR(cache);
11399-
// break;
11400-
// }
11401-
11402-
// if (PyList_Append(list, py_idx) < 0) {
11403-
// Py_DECREF(py_idx);
11404-
// Py_DECREF(list);
11405-
// Py_CLEAR(cache);
11406-
// break;
11407-
// }
11408-
11409-
// Py_DECREF(py_idx);
11410-
// Py_DECREF(list);
11361+
Py_hash_t hash = _PyObject_HashFast(p->name_strobj);
11362+
if (hash == -1) {
11363+
Py_CLEAR(cache);
11364+
break;
11365+
}
11366+
11367+
PyObject *list;
11368+
if (_PyDict_GetItemRef_KnownHash_LockHeld((PyDictObject *)cache, p->name_strobj, hash, &list) < 0) {
11369+
Py_CLEAR(cache);
11370+
break;
11371+
}
11372+
11373+
if (!list) {
11374+
list = PyList_New(0);
11375+
if (!list) {
11376+
Py_CLEAR(cache);
11377+
break;
11378+
}
11379+
11380+
if (_PyDict_SetItem_KnownHash_LockHeld((PyDictObject *)cache, p->name_strobj, list, hash) < 0) {
11381+
Py_DECREF(list);
11382+
Py_CLEAR(cache);
11383+
break;
11384+
}
11385+
}
11386+
11387+
PyObject *py_idx = PyLong_FromSsize_t(idx);
11388+
if (!py_idx) {
11389+
Py_DECREF(list);
11390+
Py_CLEAR(cache);
11391+
break;
11392+
}
11393+
11394+
if (PyList_Append(list, py_idx) < 0) {
11395+
Py_DECREF(py_idx);
11396+
Py_DECREF(list);
11397+
Py_CLEAR(cache);
11398+
break;
11399+
}
11400+
11401+
Py_DECREF(py_idx);
11402+
Py_DECREF(list);
1141111403
}
1141211404
}
1141311405

1141411406
if (cache) {
11415-
Py_ssize_t pos = 0;
11416-
PyObject* key=NULL;
11417-
PyObject* value=NULL;
11418-
while (PyDict_Next(cache, &pos, &key, &value)) {
11419-
assert(Py_REFCNT(key) > 1);
11420-
assert(Py_REFCNT(value) == 1);
11421-
}
11422-
11423-
Py_XSETREF(slotdefs_cache, cache);
11424-
} else {
11407+
Py_XSETREF(interp->cached_objects.slotdefs_cache, cache);
11408+
}
11409+
else {
1142511410
PyErr_Clear();
1142611411
}
1142711412
}

Python/pystate.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ init_interpreter(PyInterpreterState *interp,
699699
_Py_stackref_associate(interp, Py_True, PyStackRef_True);
700700
#endif
701701

702+
703+
interp->cached_objects.slotdefs_cache = NULL;
702704
interp->_initialized = 1;
703705
return _PyStatus_OK();
704706
}
@@ -829,6 +831,8 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
829831
_PyErr_Clear(tstate);
830832
}
831833

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

0 commit comments

Comments
 (0)