Skip to content

Commit

Permalink
pythonGH-90997: Shrink the LOAD_GLOBAL caches (python#102569)
Browse files Browse the repository at this point in the history
  • Loading branch information
brandtbucher authored and iritkatriel committed Mar 12, 2023
1 parent f8d4afb commit 4c8bbe4
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 172 deletions.
6 changes: 3 additions & 3 deletions Doc/library/dis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ the following command can be used to display the disassembly of
2 0 RESUME 0
<BLANKLINE>
3 2 LOAD_GLOBAL 1 (NULL + len)
14 LOAD_FAST 0 (alist)
16 CALL 1
26 RETURN_VALUE
12 LOAD_FAST 0 (alist)
14 CALL 1
24 RETURN_VALUE

(The "2" is a line number).

Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extern "C" {
typedef struct {
uint16_t counter;
uint16_t index;
uint16_t module_keys_version[2];
uint16_t module_keys_version;
uint16_t builtin_keys_version;
} _PyLoadGlobalCache;

Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_opcode.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 9 additions & 4 deletions Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,12 +431,17 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.12a5 3515 (Embed jump mask in COMPARE_OP oparg)
# Python 3.12a5 3516 (Add COMPARE_AND_BRANCH instruction)
# Python 3.12a5 3517 (Change YIELD_VALUE oparg to exception block depth)
# Python 3.12a5 3518 (Add RETURN_CONST instruction)
# Python 3.12a5 3519 (Modify SEND instruction)
# Python 3.12a5 3520 (Remove PREP_RERAISE_STAR, add CALL_INTRINSIC_2)
# Python 3.12a6 3518 (Add RETURN_CONST instruction)
# Python 3.12a6 3519 (Modify SEND instruction)
# Python 3.12a6 3520 (Remove PREP_RERAISE_STAR, add CALL_INTRINSIC_2)
# Python 3.12a7 3521 (Shrink the LOAD_GLOBAL caches)

# Python 3.13 will start with 3550

# Please don't copy-paste the same pre-release tag for new entries above!!!
# You should always use the *upcoming* tag. For example, if 3.12a6 came out
# a week ago, I should put "Python 3.12a7" next to my new magic number.

# MAGIC must change whenever the bytecode emitted by the compiler may no
# longer be understood by older implementations of the eval loop (usually
# due to the addition of new opcodes).
Expand All @@ -446,7 +451,7 @@ def _write_atomic(path, data, mode=0o666):
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.

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

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

Expand Down
2 changes: 1 addition & 1 deletion Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ def pseudo_op(name, op, real_ops):
"LOAD_GLOBAL": {
"counter": 1,
"index": 1,
"module_keys_version": 2,
"module_keys_version": 1,
"builtin_keys_version": 1,
},
"BINARY_OP": {
Expand Down
292 changes: 146 additions & 146 deletions Lib/test/test_dis.py

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Shrink the number of inline :opcode:`CACHE` entries used by
:opcode:`LOAD_GLOBAL`.
6 changes: 3 additions & 3 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ dummy_func(
LOAD_GLOBAL_BUILTIN,
};

inst(LOAD_GLOBAL, (unused/1, unused/1, unused/2, unused/1 -- null if (oparg & 1), v)) {
inst(LOAD_GLOBAL, (unused/1, unused/1, unused/1, unused/1 -- null if (oparg & 1), v)) {
#if ENABLE_SPECIALIZATION
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
Expand Down Expand Up @@ -1133,7 +1133,7 @@ dummy_func(
null = NULL;
}

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

inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/2, bltn_version/1 -- null if (oparg & 1), res)) {
inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/1, bltn_version/1 -- null if (oparg & 1), res)) {
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL);
Expand Down
14 changes: 7 additions & 7 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Python/opcode_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
#endif

enum Direction { DIR_NONE, DIR_READ, DIR_WRITE };
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 };
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 };
struct opcode_metadata {
enum Direction dir_op1;
enum Direction dir_op2;
Expand Down Expand Up @@ -790,9 +790,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[256] = {
[STORE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[DELETE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[LOAD_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
[LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
[LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
[LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC000 },
[LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC000 },
[LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC000 },
[DELETE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[MAKE_CELL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[DELETE_DEREF] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
Expand Down
12 changes: 10 additions & 2 deletions Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -1148,8 +1148,12 @@ _Py_Specialize_LoadGlobal(
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
goto fail;
}
if (keys_version != (uint16_t)keys_version) {
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
goto fail;
}
cache->index = (uint16_t)index;
write_u32(cache->module_keys_version, keys_version);
cache->module_keys_version = (uint16_t)keys_version;
instr->op.code = LOAD_GLOBAL_MODULE;
goto success;
}
Expand Down Expand Up @@ -1177,6 +1181,10 @@ _Py_Specialize_LoadGlobal(
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
goto fail;
}
if (globals_version != (uint16_t)globals_version) {
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
goto fail;
}
uint32_t builtins_version = _PyDictKeys_GetVersionForCurrentState(
interp, builtin_keys);
if (builtins_version == 0) {
Expand All @@ -1188,7 +1196,7 @@ _Py_Specialize_LoadGlobal(
goto fail;
}
cache->index = (uint16_t)index;
write_u32(cache->module_keys_version, globals_version);
cache->module_keys_version = (uint16_t)globals_version;
cache->builtin_keys_version = (uint16_t)builtins_version;
instr->op.code = LOAD_GLOBAL_BUILTIN;
goto success;
Expand Down

0 comments on commit 4c8bbe4

Please sign in to comment.