@@ -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)
1101411010static void * *
1101511011resolve_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 }
0 commit comments