diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-11-20 08:24:02 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-11-20 08:24:02 (GMT) |
commit | b4efc963d628475c79f02ecf43a4ec564b46428e (patch) | |
tree | ee70295f62c6e30bf45acf29bd9617c1b4802a9f /Objects | |
parent | c50ec007ff1b08fd2677bdd1d785b0e0af2588df (diff) | |
download | cpython-b4efc963d628475c79f02ecf43a4ec564b46428e.zip cpython-b4efc963d628475c79f02ecf43a4ec564b46428e.tar.gz cpython-b4efc963d628475c79f02ecf43a4ec564b46428e.tar.bz2 |
Issue #25557: Refactor _PyDict_LoadGlobal()
Don't fallback to PyDict_GetItemWithError() if the hash is unknown: compute the
hash instead. Add also comments to explain the optimization a little bit.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/dictobject.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 624ae9b..4a72c9a 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1165,39 +1165,42 @@ _PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key) return PyDict_GetItemWithError(dp, kv); } -/* Fast version of global value lookup. +/* Fast version of global value lookup (LOAD_GLOBAL). * Lookup in globals, then builtins. + * + * Raise an exception and return NULL if an error occurred (ex: computing the + * key hash failed, key comparison failed, ...). Return NULL if the key doesn't + * exist. Return the value if the key exists. */ PyObject * _PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key) { - PyObject *x; - if (PyUnicode_CheckExact(key)) { - PyObject **value_addr; - Py_hash_t hash = ((PyASCIIObject *)key)->hash; - if (hash != -1) { - PyDictKeyEntry *e; - e = globals->ma_keys->dk_lookup(globals, key, hash, &value_addr); - if (e == NULL) { - return NULL; - } - x = *value_addr; - if (x != NULL) - return x; - e = builtins->ma_keys->dk_lookup(builtins, key, hash, &value_addr); - if (e == NULL) { - return NULL; - } - x = *value_addr; - return x; - } + Py_hash_t hash; + PyDictKeyEntry *entry; + PyObject **value_addr; + PyObject *value; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; } - x = PyDict_GetItemWithError((PyObject *)globals, key); - if (x != NULL) - return x; - if (PyErr_Occurred()) + + /* namespace 1: globals */ + entry = globals->ma_keys->dk_lookup(globals, key, hash, &value_addr); + if (entry == NULL) return NULL; - return PyDict_GetItemWithError((PyObject *)builtins, key); + value = *value_addr; + if (value != NULL) + return value; + + /* namespace 2: builtins */ + entry = builtins->ma_keys->dk_lookup(builtins, key, hash, &value_addr); + if (entry == NULL) + return NULL; + return *value_addr; } /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the |