Skip to content

Commit b03755a

Browse files
authored
pythonGH-104909: Break LOAD_GLOBAL specializations in micro-ops. (pythonGH-106677)
1 parent e2d7366 commit b03755a

File tree

6 files changed

+586
-502
lines changed

6 files changed

+586
-502
lines changed

Include/internal/pycore_code.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ extern "C" {
1919

2020
typedef struct {
2121
uint16_t counter;
22-
uint16_t index;
2322
uint16_t module_keys_version;
2423
uint16_t builtin_keys_version;
24+
uint16_t index;
2525
} _PyLoadGlobalCache;
2626

2727
#define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache)

Include/internal/pycore_opcode_metadata.h

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Split :opcode:`LOAD_GLOBAL` specializations into micro-ops.

Python/bytecodes.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,11 +1351,25 @@ dummy_func(
13511351
null = NULL;
13521352
}
13531353

1354-
inst(LOAD_GLOBAL_MODULE, (unused/1, index/1, version/1, unused/1 -- null if (oparg & 1), res)) {
1355-
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
1354+
op(_SKIP_CACHE, (unused/1 -- )) {
1355+
}
1356+
1357+
op(_GUARD_GLOBALS_VERSION, (version/1 --)) {
13561358
PyDictObject *dict = (PyDictObject *)GLOBALS();
1359+
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
1360+
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
1361+
assert(DK_IS_UNICODE(dict->ma_keys));
1362+
}
1363+
1364+
op(_GUARD_BUILTINS_VERSION, (version/1 --)) {
1365+
PyDictObject *dict = (PyDictObject *)BUILTINS();
1366+
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
13571367
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
13581368
assert(DK_IS_UNICODE(dict->ma_keys));
1369+
}
1370+
1371+
op(_LOAD_GLOBAL_MODULE, (index/1 -- null if (oparg & 1), res)) {
1372+
PyDictObject *dict = (PyDictObject *)GLOBALS();
13591373
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
13601374
res = entries[index].me_value;
13611375
DEOPT_IF(res == NULL, LOAD_GLOBAL);
@@ -1364,15 +1378,8 @@ dummy_func(
13641378
null = NULL;
13651379
}
13661380

1367-
inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/1, bltn_version/1 -- null if (oparg & 1), res)) {
1368-
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
1369-
DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL);
1370-
PyDictObject *mdict = (PyDictObject *)GLOBALS();
1381+
op(_LOAD_GLOBAL_BUILTINS, (index/1 -- null if (oparg & 1), res)) {
13711382
PyDictObject *bdict = (PyDictObject *)BUILTINS();
1372-
assert(opcode == LOAD_GLOBAL_BUILTIN);
1373-
DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL);
1374-
DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL);
1375-
assert(DK_IS_UNICODE(bdict->ma_keys));
13761383
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys);
13771384
res = entries[index].me_value;
13781385
DEOPT_IF(res == NULL, LOAD_GLOBAL);
@@ -1381,6 +1388,18 @@ dummy_func(
13811388
null = NULL;
13821389
}
13831390

1391+
macro(LOAD_GLOBAL_MODULE) =
1392+
_SKIP_CACHE + // Skip over the counter
1393+
_GUARD_GLOBALS_VERSION +
1394+
_SKIP_CACHE + // Skip over the builtins version
1395+
_LOAD_GLOBAL_MODULE;
1396+
1397+
macro(LOAD_GLOBAL_BUILTIN) =
1398+
_SKIP_CACHE + // Skip over the counter
1399+
_GUARD_GLOBALS_VERSION +
1400+
_GUARD_BUILTINS_VERSION +
1401+
_LOAD_GLOBAL_BUILTINS;
1402+
13841403
inst(DELETE_FAST, (--)) {
13851404
PyObject *v = GETLOCAL(oparg);
13861405
ERROR_IF(v == NULL, unbound_local_error);

0 commit comments

Comments
 (0)