Skip to content

Commit 3108bbe

Browse files
use stackrefs for dict loopkup
1 parent 5193400 commit 3108bbe

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

Objects/object.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,19 +1753,29 @@ _PyObject_GetMethodStackRef(PyThreadState *ts, PyObject *obj,
17531753
}
17541754
}
17551755
if (dict != NULL) {
1756-
// TODO: use _Py_dict_lookup_threadsafe_stackref
1756+
assert(PyUnicode_CheckExact(name));
1757+
Py_hash_t hash = _PyObject_HashFast(name);
1758+
// cannot fail for exact unicode
1759+
assert(hash != -1);
17571760
Py_INCREF(dict);
1758-
PyObject *value;
1759-
if (PyDict_GetItemRef(dict, name, &value) != 0) {
1760-
// found or error
1761-
Py_DECREF(dict);
1761+
// ref is not visible to gc so there should be
1762+
// no escaping calls before assigning it to method
1763+
_PyStackRef ref;
1764+
Py_ssize_t ix = _Py_dict_lookup_threadsafe_stackref((PyDictObject *)dict,
1765+
name, hash, &ref);
1766+
if (ix == DKIX_ERROR) {
1767+
// error
17621768
PyStackRef_CLEAR(*method);
1763-
if (value != NULL) {
1764-
*method = PyStackRef_FromPyObjectSteal(value);
1765-
}
1769+
Py_DECREF(dict);
1770+
return -1;
1771+
} else if (!PyStackRef_IsNull(ref)) {
1772+
// found
1773+
_PyStackRef tmp = *method;
1774+
*method = ref;
1775+
PyStackRef_XCLOSE(tmp);
1776+
Py_DECREF(dict);
17661777
return 0;
17671778
}
1768-
// not found
17691779
Py_DECREF(dict);
17701780
}
17711781

0 commit comments

Comments
 (0)