Skip to content

Commit 08b67fb

Browse files
authored
pythonGH-90997: Shrink the LOAD_GLOBAL caches (python#102569)
1 parent 767d3a8 commit 08b67fb

File tree

11 files changed

+187
-172
lines changed

11 files changed

+187
-172
lines changed

Doc/library/dis.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ the following command can be used to display the disassembly of
5757
2 0 RESUME 0
5858
<BLANKLINE>
5959
3 2 LOAD_GLOBAL 1 (NULL + len)
60-
14 LOAD_FAST 0 (alist)
61-
16 CALL 1
62-
26 RETURN_VALUE
60+
12 LOAD_FAST 0 (alist)
61+
14 CALL 1
62+
24 RETURN_VALUE
6363

6464
(The "2" is a line number).
6565

Include/internal/pycore_code.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ extern "C" {
2020
typedef struct {
2121
uint16_t counter;
2222
uint16_t index;
23-
uint16_t module_keys_version[2];
23+
uint16_t module_keys_version;
2424
uint16_t builtin_keys_version;
2525
} _PyLoadGlobalCache;
2626

Include/internal/pycore_opcode.h

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/importlib/_bootstrap_external.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -431,12 +431,17 @@ def _write_atomic(path, data, mode=0o666):
431431
# Python 3.12a5 3515 (Embed jump mask in COMPARE_OP oparg)
432432
# Python 3.12a5 3516 (Add COMPARE_AND_BRANCH instruction)
433433
# Python 3.12a5 3517 (Change YIELD_VALUE oparg to exception block depth)
434-
# Python 3.12a5 3518 (Add RETURN_CONST instruction)
435-
# Python 3.12a5 3519 (Modify SEND instruction)
436-
# Python 3.12a5 3520 (Remove PREP_RERAISE_STAR, add CALL_INTRINSIC_2)
434+
# Python 3.12a6 3518 (Add RETURN_CONST instruction)
435+
# Python 3.12a6 3519 (Modify SEND instruction)
436+
# Python 3.12a6 3520 (Remove PREP_RERAISE_STAR, add CALL_INTRINSIC_2)
437+
# Python 3.12a7 3521 (Shrink the LOAD_GLOBAL caches)
437438

438439
# Python 3.13 will start with 3550
439440

441+
# Please don't copy-paste the same pre-release tag for new entries above!!!
442+
# You should always use the *upcoming* tag. For example, if 3.12a6 came out
443+
# a week ago, I should put "Python 3.12a7" next to my new magic number.
444+
440445
# MAGIC must change whenever the bytecode emitted by the compiler may no
441446
# longer be understood by older implementations of the eval loop (usually
442447
# due to the addition of new opcodes).
@@ -446,7 +451,7 @@ def _write_atomic(path, data, mode=0o666):
446451
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
447452
# in PC/launcher.c must also be updated.
448453

449-
MAGIC_NUMBER = (3520).to_bytes(2, 'little') + b'\r\n'
454+
MAGIC_NUMBER = (3521).to_bytes(2, 'little') + b'\r\n'
450455

451456
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
452457

Lib/opcode.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def pseudo_op(name, op, real_ops):
390390
"LOAD_GLOBAL": {
391391
"counter": 1,
392392
"index": 1,
393-
"module_keys_version": 2,
393+
"module_keys_version": 1,
394394
"builtin_keys_version": 1,
395395
},
396396
"BINARY_OP": {

Lib/test/test_dis.py

+146-146
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Shrink the number of inline :opcode:`CACHE` entries used by
2+
:opcode:`LOAD_GLOBAL`.

Python/bytecodes.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,7 @@ dummy_func(
10781078
LOAD_GLOBAL_BUILTIN,
10791079
};
10801080

1081-
inst(LOAD_GLOBAL, (unused/1, unused/1, unused/2, unused/1 -- null if (oparg & 1), v)) {
1081+
inst(LOAD_GLOBAL, (unused/1, unused/1, unused/1, unused/1 -- null if (oparg & 1), v)) {
10821082
#if ENABLE_SPECIALIZATION
10831083
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
10841084
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1133,7 +1133,7 @@ dummy_func(
11331133
null = NULL;
11341134
}
11351135

1136-
inst(LOAD_GLOBAL_MODULE, (unused/1, index/1, version/2, unused/1 -- null if (oparg & 1), res)) {
1136+
inst(LOAD_GLOBAL_MODULE, (unused/1, index/1, version/1, unused/1 -- null if (oparg & 1), res)) {
11371137
assert(cframe.use_tracing == 0);
11381138
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
11391139
PyDictObject *dict = (PyDictObject *)GLOBALS();
@@ -1147,7 +1147,7 @@ dummy_func(
11471147
null = NULL;
11481148
}
11491149

1150-
inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/2, bltn_version/1 -- null if (oparg & 1), res)) {
1150+
inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/1, bltn_version/1 -- null if (oparg & 1), res)) {
11511151
assert(cframe.use_tracing == 0);
11521152
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
11531153
DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL);

Python/generated_cases.c.h

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/opcode_metadata.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
708708
#endif
709709

710710
enum Direction { DIR_NONE, DIR_READ, DIR_WRITE };
711-
enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC0, INSTR_FMT_IBC000, INSTR_FMT_IBC0000, INSTR_FMT_IBC00000000, INSTR_FMT_IBIB, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC000 };
711+
enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC0, INSTR_FMT_IBC000, INSTR_FMT_IBC00000000, INSTR_FMT_IBIB, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC000 };
712712
struct opcode_metadata {
713713
enum Direction dir_op1;
714714
enum Direction dir_op2;
@@ -790,9 +790,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[256] = {
790790
[STORE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
791791
[DELETE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
792792
[LOAD_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
793-
[LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
794-
[LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
795-
[LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
793+
[LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC000 },
794+
[LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC000 },
795+
[LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC000 },
796796
[DELETE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
797797
[MAKE_CELL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
798798
[DELETE_DEREF] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },

Python/specialize.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -1148,8 +1148,12 @@ _Py_Specialize_LoadGlobal(
11481148
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
11491149
goto fail;
11501150
}
1151+
if (keys_version != (uint16_t)keys_version) {
1152+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
1153+
goto fail;
1154+
}
11511155
cache->index = (uint16_t)index;
1152-
write_u32(cache->module_keys_version, keys_version);
1156+
cache->module_keys_version = (uint16_t)keys_version;
11531157
instr->op.code = LOAD_GLOBAL_MODULE;
11541158
goto success;
11551159
}
@@ -1177,6 +1181,10 @@ _Py_Specialize_LoadGlobal(
11771181
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
11781182
goto fail;
11791183
}
1184+
if (globals_version != (uint16_t)globals_version) {
1185+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
1186+
goto fail;
1187+
}
11801188
uint32_t builtins_version = _PyDictKeys_GetVersionForCurrentState(
11811189
interp, builtin_keys);
11821190
if (builtins_version == 0) {
@@ -1188,7 +1196,7 @@ _Py_Specialize_LoadGlobal(
11881196
goto fail;
11891197
}
11901198
cache->index = (uint16_t)index;
1191-
write_u32(cache->module_keys_version, globals_version);
1199+
cache->module_keys_version = (uint16_t)globals_version;
11921200
cache->builtin_keys_version = (uint16_t)builtins_version;
11931201
instr->op.code = LOAD_GLOBAL_BUILTIN;
11941202
goto success;

0 commit comments

Comments
 (0)