summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2023-07-12 13:34:14 (GMT)
committerGitHub <noreply@github.com>2023-07-12 13:34:14 (GMT)
commitb03755a2347325a89a48b08fc158419000513bcb (patch)
treef60ec740d2eb0016e44bfef32f2a6cebf5f70e0e /Python/bytecodes.c
parente2d7366fb3df44e7434132636d49f22d6d25cc9f (diff)
downloadcpython-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.c39
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);