gh-121459: Deferred LOAD_GLOBAL (GH-123128)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Sam Gross <655866+colesbury@users.noreply.github.com>
This commit is contained in:
Ken Jin 2024-09-14 00:23:51 +08:00 committed by GitHub
parent 74330d992b
commit 8810e286fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 108 additions and 29 deletions

View file

@ -1496,6 +1496,45 @@ read_failed:
return ix;
}
Py_ssize_t
_Py_dict_lookup_threadsafe_stackref(PyDictObject *mp, PyObject *key, Py_hash_t hash, _PyStackRef *value_addr)
{
PyDictKeysObject *dk = _Py_atomic_load_ptr(&mp->ma_keys);
if (dk->dk_kind == DICT_KEYS_UNICODE && PyUnicode_CheckExact(key)) {
Py_ssize_t ix = unicodekeys_lookup_unicode_threadsafe(dk, key, hash);
if (ix == DKIX_EMPTY) {
*value_addr = PyStackRef_NULL;
return ix;
}
else if (ix >= 0) {
PyObject **addr_of_value = &DK_UNICODE_ENTRIES(dk)[ix].me_value;
PyObject *value = _Py_atomic_load_ptr(addr_of_value);
if (value == NULL) {
*value_addr = PyStackRef_NULL;
return DKIX_EMPTY;
}
if (_Py_IsImmortal(value) || _PyObject_HasDeferredRefcount(value)) {
*value_addr = (_PyStackRef){ .bits = (uintptr_t)value | Py_TAG_DEFERRED };
return ix;
}
if (_Py_TryIncrefCompare(addr_of_value, value)) {
*value_addr = PyStackRef_FromPyObjectSteal(value);
return ix;
}
}
}
PyObject *obj;
Py_ssize_t ix = _Py_dict_lookup_threadsafe(mp, key, hash, &obj);
if (ix >= 0 && obj != NULL) {
*value_addr = PyStackRef_FromPyObjectSteal(obj);
}
else {
*value_addr = PyStackRef_NULL;
}
return ix;
}
#else // Py_GIL_DISABLED
Py_ssize_t
@ -1506,6 +1545,15 @@ _Py_dict_lookup_threadsafe(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyOb
return ix;
}
Py_ssize_t
_Py_dict_lookup_threadsafe_stackref(PyDictObject *mp, PyObject *key, Py_hash_t hash, _PyStackRef *value_addr)
{
PyObject *val;
Py_ssize_t ix = _Py_dict_lookup(mp, key, hash, &val);
*value_addr = val == NULL ? PyStackRef_NULL : PyStackRef_FromPyObjectNew(val);
return ix;
}
#endif
int
@ -2420,6 +2468,32 @@ _PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key)
return value;
}
void
_PyDict_LoadGlobalStackRef(PyDictObject *globals, PyDictObject *builtins, PyObject *key, _PyStackRef *res)
{
Py_ssize_t ix;
Py_hash_t hash;
hash = _PyObject_HashFast(key);
if (hash == -1) {
*res = PyStackRef_NULL;
return;
}
/* namespace 1: globals */
ix = _Py_dict_lookup_threadsafe_stackref(globals, key, hash, res);
if (ix == DKIX_ERROR) {
*res = PyStackRef_NULL;
}
if (ix != DKIX_EMPTY && !PyStackRef_IsNull(*res)) {
return;
}
/* namespace 2: builtins */
ix = _Py_dict_lookup_threadsafe_stackref(builtins, key, hash, res);
assert(ix >= 0 || PyStackRef_IsNull(*res));
}
/* Consumes references to key and value */
static int
setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value)