Skip to content

Commit b0ad875

Browse files
Move slotdefs_cache init to pycore_init_builtins
1 parent 8cf19e8 commit b0ad875

File tree

3 files changed

+79
-72
lines changed

3 files changed

+79
-72
lines changed

Include/internal/pycore_typeobject.h

+2
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ typedef int (*_py_validate_type)(PyTypeObject *);
149149
extern int _PyType_Validate(PyTypeObject *ty, _py_validate_type validate, unsigned int *tp_version);
150150
extern int _PyType_CacheGetItemForSpecialization(PyHeapTypeObject *ht, PyObject *descriptor, uint32_t tp_version);
151151

152+
extern int _PyType_InitSlotDefsCache(PyInterpreterState *interp);
153+
152154
#ifdef __cplusplus
153155
}
154156
#endif

Objects/typeobject.c

+73-72
Original file line numberDiff line numberDiff line change
@@ -11011,19 +11011,21 @@ fill_type_slots_cache_from_slotdefs_cache(PyInterpreterState *interp,
1101111011
{
1101211012
#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs)
1101311013

11014-
int rc = 0;
11015-
PyObject *cache = Py_XNewRef(interp->cached_objects.slotdefs_cache);
11014+
PyObject *cache = _Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache);
1101611015
if (cache) {
11017-
PyObject* bytes=NULL;
11018-
rc = PyDict_GetItemRef(cache, name, &bytes);
11019-
if (rc > 0) {
11020-
assert(bytes);
11016+
11017+
PyObject* bytes = PyDict_GetItemWithError(cache, name);
11018+
if (PyErr_Occurred()) {
11019+
PyErr_Clear();
11020+
return -1;
11021+
}
11022+
11023+
if (bytes != NULL) {
1102111024
assert(PyBytes_CheckExact(bytes));
1102211025

1102311026
uint8_t *data = (uint8_t *)PyBytes_AS_STRING(bytes);
1102411027
uint8_t n = data[0];
1102511028

11026-
assert(n >= 0);
1102711029
assert(n < MAX_EQUIV);
1102811030

1102911031
pytype_slotdef **pp = ptrs;
@@ -11035,15 +11037,11 @@ fill_type_slots_cache_from_slotdefs_cache(PyInterpreterState *interp,
1103511037
}
1103611038
*pp = NULL;
1103711039

11038-
Py_DECREF(bytes);
11039-
} else if (rc < 0) {
11040-
PyErr_Clear();
11040+
return 1;
1104111041
}
11042-
11043-
Py_DECREF(cache);
1104411042
}
1104511043

11046-
return rc;
11044+
return 0;
1104711045

1104811046
#undef ptrs
1104911047
}
@@ -11354,65 +11352,6 @@ fixup_slot_dispatchers(PyTypeObject *type)
1135411352
}
1135511353
}
1135611354

11357-
PyInterpreterState *interp = _PyInterpreterState_GET();
11358-
if (!interp->cached_objects.slotdefs_cache) {
11359-
11360-
PyObject* cache = PyDict_New();
11361-
if (cache) {
11362-
pytype_slotdef *p;
11363-
Py_ssize_t idx = 0;
11364-
for (p = slotdefs; p->name_strobj; p++, idx++) {
11365-
Py_hash_t hash = _PyObject_HashFast(p->name_strobj);
11366-
if (hash == -1) {
11367-
Py_CLEAR(cache);
11368-
break;
11369-
}
11370-
assert (idx < 255);
11371-
11372-
PyObject *bytes;
11373-
if (_PyDict_GetItemRef_KnownHash_LockHeld((PyDictObject *)cache, p->name_strobj, hash, &bytes) < 0) {
11374-
Py_CLEAR(cache);
11375-
break;
11376-
}
11377-
11378-
if (!bytes) {
11379-
bytes = PyBytes_FromStringAndSize(NULL, sizeof(uint8_t) * (1 + MAX_EQUIV));
11380-
if (!bytes) {
11381-
Py_CLEAR(cache);
11382-
break;
11383-
}
11384-
11385-
uint8_t *data = (uint8_t *)PyBytes_AS_STRING(bytes);
11386-
data[0] = 0;
11387-
11388-
if (_PyDict_SetItem_KnownHash_LockHeld((PyDictObject *)cache, p->name_strobj, bytes, hash) < 0) {
11389-
Py_DECREF(bytes);
11390-
Py_CLEAR(cache);
11391-
break;
11392-
}
11393-
}
11394-
11395-
assert (PyBytes_CheckExact(bytes));
11396-
uint8_t *data = (uint8_t *)PyBytes_AS_STRING(bytes);
11397-
11398-
data[0] += 1;
11399-
assert (data[0] < MAX_EQUIV);
11400-
11401-
data[data[0]] = (uint8_t)idx;
11402-
11403-
Py_DECREF(bytes);
11404-
}
11405-
11406-
}
11407-
11408-
if (cache) {
11409-
Py_XSETREF(interp->cached_objects.slotdefs_cache, cache);
11410-
}
11411-
else {
11412-
PyErr_Clear();
11413-
}
11414-
}
11415-
1141611355
assert(!PyErr_Occurred());
1141711356
for (pytype_slotdef *p = slotdefs; p->name; ) {
1141811357
p = update_one_slot(type, p, mro_dict);
@@ -11439,6 +11378,68 @@ update_all_slots(PyTypeObject* type)
1143911378
}
1144011379
}
1144111380

11381+
int
11382+
_PyType_InitSlotDefsCache(PyInterpreterState *interp)
11383+
{
11384+
assert (!_Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache));
11385+
11386+
PyObject *bytes = NULL;
11387+
PyObject* cache = PyDict_New();
11388+
if (!cache) {
11389+
goto error;
11390+
}
11391+
pytype_slotdef *p;
11392+
Py_ssize_t idx = 0;
11393+
for (p = slotdefs; p->name_strobj; p++, idx++) {
11394+
Py_hash_t hash = _PyObject_HashFast(p->name_strobj);
11395+
if (hash == -1) {
11396+
goto error;
11397+
}
11398+
assert (idx < 255);
11399+
11400+
if (_PyDict_GetItemRef_KnownHash_LockHeld((PyDictObject *)cache,
11401+
p->name_strobj, hash,
11402+
&bytes) < 0) {
11403+
goto error;
11404+
}
11405+
11406+
if (!bytes) {
11407+
Py_ssize_t size = sizeof(uint8_t) * (1 + MAX_EQUIV);
11408+
bytes = PyBytes_FromStringAndSize(NULL, size);
11409+
if (!bytes) {
11410+
goto error;
11411+
}
11412+
11413+
uint8_t *data = (uint8_t *)PyBytes_AS_STRING(bytes);
11414+
data[0] = 0;
11415+
11416+
if (_PyDict_SetItem_KnownHash_LockHeld((PyDictObject *)cache,
11417+
p->name_strobj,
11418+
bytes, hash) < 0) {
11419+
goto error;
11420+
}
11421+
}
11422+
11423+
assert (PyBytes_CheckExact(bytes));
11424+
uint8_t *data = (uint8_t *)PyBytes_AS_STRING(bytes);
11425+
11426+
data[0] += 1;
11427+
assert (data[0] < MAX_EQUIV);
11428+
11429+
data[data[0]] = (uint8_t)idx;
11430+
11431+
Py_CLEAR(bytes);
11432+
}
11433+
11434+
Py_XSETREF(_Py_INTERP_CACHED_OBJECT(interp, slotdefs_cache), cache);
11435+
return 0;
11436+
11437+
error:
11438+
Py_XDECREF(bytes);
11439+
Py_XDECREF(cache);
11440+
return -1;
11441+
}
11442+
1144211443

1144311444
PyObject *
1144411445
_PyType_GetSlotWrapperNames(void)

Python/pylifecycle.c

+4
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,10 @@ pycore_init_builtins(PyThreadState *tstate)
822822
}
823823
interp->callable_cache.object__getattribute__ = object__getattribute__;
824824

825+
if (_PyType_InitSlotDefsCache(interp) < 0) {
826+
return _PyStatus_ERR("failed to init slotdefs cache");
827+
}
828+
825829
if (_PyBuiltins_AddExceptions(bimod) < 0) {
826830
return _PyStatus_ERR("failed to add exceptions to builtins");
827831
}

0 commit comments

Comments
 (0)