mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
bpo-42093: Add opcode cache for LOAD_ATTR (GH-22803)
This commit is contained in:
parent
871934d4cf
commit
109826c850
7 changed files with 296 additions and 7 deletions
|
@ -1437,6 +1437,71 @@ PyDict_GetItem(PyObject *op, PyObject *key)
|
|||
return value;
|
||||
}
|
||||
|
||||
Py_ssize_t
|
||||
_PyDict_GetItemHint(PyDictObject *mp, PyObject *key,
|
||||
Py_ssize_t hint, PyObject **value)
|
||||
{
|
||||
Py_hash_t hash;
|
||||
PyThreadState *tstate;
|
||||
|
||||
assert(*value == NULL);
|
||||
assert(PyDict_CheckExact((PyObject*)mp));
|
||||
assert(PyUnicode_CheckExact(key));
|
||||
|
||||
if (hint >= 0 && hint < _PyDict_KeysSize(mp->ma_keys)) {
|
||||
PyObject *res = NULL;
|
||||
|
||||
PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint;
|
||||
if (ep->me_key == key) {
|
||||
if (mp->ma_keys->dk_lookup == lookdict_split) {
|
||||
assert(mp->ma_values != NULL);
|
||||
res = mp->ma_values[(size_t)hint];
|
||||
}
|
||||
else {
|
||||
res = ep->me_value;
|
||||
}
|
||||
if (res != NULL) {
|
||||
*value = res;
|
||||
return hint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((hash = ((PyASCIIObject *) key)->hash) == -1)
|
||||
{
|
||||
hash = PyObject_Hash(key);
|
||||
if (hash == -1) {
|
||||
PyErr_Clear();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// We can arrive here with a NULL tstate during initialization: try
|
||||
// running "python -Wi" for an example related to string interning
|
||||
tstate = _PyThreadState_UncheckedGet();
|
||||
Py_ssize_t ix = 0;
|
||||
if (tstate != NULL && tstate->curexc_type != NULL) {
|
||||
/* preserve the existing exception */
|
||||
PyObject *err_type, *err_value, *err_tb;
|
||||
PyErr_Fetch(&err_type, &err_value, &err_tb);
|
||||
ix = (mp->ma_keys->dk_lookup)(mp, key, hash, value);
|
||||
/* ignore errors */
|
||||
PyErr_Restore(err_type, err_value, err_tb);
|
||||
if (ix < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ix = (mp->ma_keys->dk_lookup)(mp, key, hash, value);
|
||||
if (ix < 0) {
|
||||
PyErr_Clear();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ix;
|
||||
}
|
||||
|
||||
/* Same as PyDict_GetItemWithError() but with hash supplied by caller.
|
||||
This returns NULL *with* an exception set if an exception occurred.
|
||||
It returns NULL *without* an exception set if the key wasn't present.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue