diff options
author | Mark Shannon <mark@hotpy.org> | 2023-07-12 13:34:14 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-12 13:34:14 (GMT) |
commit | b03755a2347325a89a48b08fc158419000513bcb (patch) | |
tree | f60ec740d2eb0016e44bfef32f2a6cebf5f70e0e /Python/bytecodes.c | |
parent | e2d7366fb3df44e7434132636d49f22d6d25cc9f (diff) | |
download | cpython-b03755a2347325a89a48b08fc158419000513bcb.zip cpython-b03755a2347325a89a48b08fc158419000513bcb.tar.gz cpython-b03755a2347325a89a48b08fc158419000513bcb.tar.bz2 |
GH-104909: Break LOAD_GLOBAL specializations in micro-ops. (GH-106677)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 2f6b8c5..f5ce2e7 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1351,11 +1351,25 @@ dummy_func( null = NULL; } - inst(LOAD_GLOBAL_MODULE, (unused/1, index/1, version/1, unused/1 -- null if (oparg & 1), res)) { - DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + op(_SKIP_CACHE, (unused/1 -- )) { + } + + op(_GUARD_GLOBALS_VERSION, (version/1 --)) { PyDictObject *dict = (PyDictObject *)GLOBALS(); + DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(dict->ma_keys)); + } + + op(_GUARD_BUILTINS_VERSION, (version/1 --)) { + PyDictObject *dict = (PyDictObject *)BUILTINS(); + DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); assert(DK_IS_UNICODE(dict->ma_keys)); + } + + op(_LOAD_GLOBAL_MODULE, (index/1 -- null if (oparg & 1), res)) { + PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); res = entries[index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); @@ -1364,15 +1378,8 @@ dummy_func( null = NULL; } - inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/1, bltn_version/1 -- null if (oparg & 1), res)) { - DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); - DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); - PyDictObject *mdict = (PyDictObject *)GLOBALS(); + op(_LOAD_GLOBAL_BUILTINS, (index/1 -- null if (oparg & 1), res)) { PyDictObject *bdict = (PyDictObject *)BUILTINS(); - assert(opcode == LOAD_GLOBAL_BUILTIN); - DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); - DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); - assert(DK_IS_UNICODE(bdict->ma_keys)); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); res = entries[index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); @@ -1381,6 +1388,18 @@ dummy_func( null = NULL; } + macro(LOAD_GLOBAL_MODULE) = + _SKIP_CACHE + // Skip over the counter + _GUARD_GLOBALS_VERSION + + _SKIP_CACHE + // Skip over the builtins version + _LOAD_GLOBAL_MODULE; + + macro(LOAD_GLOBAL_BUILTIN) = + _SKIP_CACHE + // Skip over the counter + _GUARD_GLOBALS_VERSION + + _GUARD_BUILTINS_VERSION + + _LOAD_GLOBAL_BUILTINS; + inst(DELETE_FAST, (--)) { PyObject *v = GETLOCAL(oparg); ERROR_IF(v == NULL, unbound_local_error); |