Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b4efc96

Browse files
committed
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.
1 parent c50ec00 commit b4efc96

2 files changed

Lines changed: 38 additions & 28 deletions

File tree

Objects/dictobject.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,39 +1165,42 @@ _PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key)
11651165
return PyDict_GetItemWithError(dp, kv);
11661166
}
11671167

1168-
/* Fast version of global value lookup.
1168+
/* Fast version of global value lookup (LOAD_GLOBAL).
11691169
* Lookup in globals, then builtins.
1170+
*
1171+
* Raise an exception and return NULL if an error occurred (ex: computing the
1172+
* key hash failed, key comparison failed, ...). Return NULL if the key doesn't
1173+
* exist. Return the value if the key exists.
11701174
*/
11711175
PyObject *
11721176
_PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key)
11731177
{
1174-
PyObject *x;
1175-
if (PyUnicode_CheckExact(key)) {
1176-
PyObject **value_addr;
1177-
Py_hash_t hash = ((PyASCIIObject *)key)->hash;
1178-
if (hash != -1) {
1179-
PyDictKeyEntry *e;
1180-
e = globals->ma_keys->dk_lookup(globals, key, hash, &value_addr);
1181-
if (e == NULL) {
1182-
return NULL;
1183-
}
1184-
x = *value_addr;
1185-
if (x != NULL)
1186-
return x;
1187-
e = builtins->ma_keys->dk_lookup(builtins, key, hash, &value_addr);
1188-
if (e == NULL) {
1189-
return NULL;
1190-
}
1191-
x = *value_addr;
1192-
return x;
1193-
}
1178+
Py_hash_t hash;
1179+
PyDictKeyEntry *entry;
1180+
PyObject **value_addr;
1181+
PyObject *value;
1182+
1183+
if (!PyUnicode_CheckExact(key) ||
1184+
(hash = ((PyASCIIObject *) key)->hash) == -1)
1185+
{
1186+
hash = PyObject_Hash(key);
1187+
if (hash == -1)
1188+
return NULL;
11941189
}
1195-
x = PyDict_GetItemWithError((PyObject *)globals, key);
1196-
if (x != NULL)
1197-
return x;
1198-
if (PyErr_Occurred())
1190+
1191+
/* namespace 1: globals */
1192+
entry = globals->ma_keys->dk_lookup(globals, key, hash, &value_addr);
1193+
if (entry == NULL)
11991194
return NULL;
1200-
return PyDict_GetItemWithError((PyObject *)builtins, key);
1195+
value = *value_addr;
1196+
if (value != NULL)
1197+
return value;
1198+
1199+
/* namespace 2: builtins */
1200+
entry = builtins->ma_keys->dk_lookup(builtins, key, hash, &value_addr);
1201+
if (entry == NULL)
1202+
return NULL;
1203+
return *value_addr;
12011204
}
12021205

12031206
/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the

Python/ceval.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,26 +2347,33 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
23472347
PyObject *name = GETITEM(names, oparg);
23482348
PyObject *v;
23492349
if (PyDict_CheckExact(f->f_globals)
2350-
&& PyDict_CheckExact(f->f_builtins)) {
2350+
&& PyDict_CheckExact(f->f_builtins))
2351+
{
23512352
v = _PyDict_LoadGlobal((PyDictObject *)f->f_globals,
23522353
(PyDictObject *)f->f_builtins,
23532354
name);
23542355
if (v == NULL) {
2355-
if (!_PyErr_OCCURRED())
2356+
if (!_PyErr_OCCURRED()) {
2357+
/* _PyDict_LoadGlobal() returns NULL without raising
2358+
* an exception if the key doesn't exist */
23562359
format_exc_check_arg(PyExc_NameError,
23572360
NAME_ERROR_MSG, name);
2361+
}
23582362
goto error;
23592363
}
23602364
Py_INCREF(v);
23612365
}
23622366
else {
23632367
/* Slow-path if globals or builtins is not a dict */
2368+
2369+
/* namespace 1: globals */
23642370
v = PyObject_GetItem(f->f_globals, name);
23652371
if (v == NULL) {
23662372
if (!PyErr_ExceptionMatches(PyExc_KeyError))
23672373
goto error;
23682374
PyErr_Clear();
23692375

2376+
/* namespace 2: builtins */
23702377
v = PyObject_GetItem(f->f_builtins, name);
23712378
if (v == NULL) {
23722379
if (PyErr_ExceptionMatches(PyExc_KeyError))

0 commit comments

Comments
 (0)