From ed7bd4607083b9d98b74ff5e34f08eda76ab54d1 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 3 Mar 2022 12:48:37 +0000 Subject: [PATCH] Move check for str-only keys in LOAD_GLOBAL specializations to specialization time. --- Python/ceval.c | 21 ++++++--------------- Python/specialize.c | 8 ++++++++ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index e47e0521ea9413..c86b7443768a15 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1595,19 +1595,6 @@ is_method(PyObject **stack_pointer, int args) { return PEEK(args+2) != NULL; } -static PyObject* -dictkeys_get_value_by_index(PyDictKeysObject *dk, int index) -{ - if (DK_IS_UNICODE(dk)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dk) + index; - return ep->me_value; - } - else { - PyDictKeyEntry *ep = DK_ENTRIES(dk) + index; - return ep->me_value; - } -} - #define KWNAMES_LEN() \ (call_shape.kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(call_shape.kwnames))) @@ -3043,7 +3030,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; uint32_t version = read32(&cache->module_keys_version); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); - PyObject *res = dictkeys_get_value_by_index(dict->ma_keys, cache->index); + assert(DK_IS_UNICODE(dict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); + PyObject *res = entries[cache->index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); @@ -3063,7 +3052,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int uint16_t bltn_version = cache->builtin_keys_version; DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); - PyObject *res = dictkeys_get_value_by_index(bdict->ma_keys, cache->index); + assert(DK_IS_UNICODE(bdict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); + PyObject *res = entries[cache->index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); diff --git a/Python/specialize.c b/Python/specialize.c index 5486b5b1f65dc9..676258268f1786 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1219,6 +1219,10 @@ _Py_Specialize_LoadGlobal( goto fail; } PyDictKeysObject * globals_keys = ((PyDictObject *)globals)->ma_keys; + if (!DK_IS_UNICODE(globals_keys)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); + goto fail; + } Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name); if (index == DKIX_ERROR) { SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); @@ -1241,6 +1245,10 @@ _Py_Specialize_LoadGlobal( goto fail; } PyDictKeysObject * builtin_keys = ((PyDictObject *)builtins)->ma_keys; + if (!DK_IS_UNICODE(builtin_keys)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); + goto fail; + } index = _PyDictKeys_StringLookup(builtin_keys, name); if (index == DKIX_ERROR) { SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT);