summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-11-20 08:24:02 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-11-20 08:24:02 (GMT)
commitb4efc963d628475c79f02ecf43a4ec564b46428e (patch)
treeee70295f62c6e30bf45acf29bd9617c1b4802a9f /Objects
parentc50ec007ff1b08fd2677bdd1d785b0e0af2588df (diff)
downloadcpython-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.c55
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