Skip to content

Commit ae9b38f

Browse files
authored
gh-98831: Modernize the LOAD_GLOBAL family (#101502)
1 parent eda6091 commit ae9b38f

File tree

3 files changed

+66
-77
lines changed

3 files changed

+66
-77
lines changed

Python/bytecodes.c

+19-38
Original file line numberDiff line numberDiff line change
@@ -1068,8 +1068,13 @@ dummy_func(
10681068
}
10691069
}
10701070

1071-
// error: LOAD_GLOBAL has irregular stack effect
1072-
inst(LOAD_GLOBAL) {
1071+
family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = {
1072+
LOAD_GLOBAL,
1073+
LOAD_GLOBAL_MODULE,
1074+
LOAD_GLOBAL_BUILTIN,
1075+
};
1076+
1077+
inst(LOAD_GLOBAL, (unused/1, unused/1, unused/2, unused/1 -- null if (oparg & 1), v)) {
10731078
#if ENABLE_SPECIALIZATION
10741079
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
10751080
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1082,10 +1087,7 @@ dummy_func(
10821087
STAT_INC(LOAD_GLOBAL, deferred);
10831088
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
10841089
#endif /* ENABLE_SPECIALIZATION */
1085-
int push_null = oparg & 1;
1086-
PEEK(0) = NULL;
10871090
PyObject *name = GETITEM(names, oparg>>1);
1088-
PyObject *v;
10891091
if (PyDict_CheckExact(GLOBALS())
10901092
&& PyDict_CheckExact(BUILTINS()))
10911093
{
@@ -1099,7 +1101,7 @@ dummy_func(
10991101
format_exc_check_arg(tstate, PyExc_NameError,
11001102
NAME_ERROR_MSG, name);
11011103
}
1102-
goto error;
1104+
ERROR_IF(true, error);
11031105
}
11041106
Py_INCREF(v);
11051107
}
@@ -1109,9 +1111,7 @@ dummy_func(
11091111
/* namespace 1: globals */
11101112
v = PyObject_GetItem(GLOBALS(), name);
11111113
if (v == NULL) {
1112-
if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
1113-
goto error;
1114-
}
1114+
ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error);
11151115
_PyErr_Clear(tstate);
11161116

11171117
/* namespace 2: builtins */
@@ -1122,58 +1122,42 @@ dummy_func(
11221122
tstate, PyExc_NameError,
11231123
NAME_ERROR_MSG, name);
11241124
}
1125-
goto error;
1125+
ERROR_IF(true, error);
11261126
}
11271127
}
11281128
}
1129-
/* Skip over inline cache */
1130-
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL);
1131-
STACK_GROW(push_null);
1132-
PUSH(v);
1129+
null = NULL;
11331130
}
11341131

1135-
// error: LOAD_GLOBAL has irregular stack effect
1136-
inst(LOAD_GLOBAL_MODULE) {
1132+
inst(LOAD_GLOBAL_MODULE, (unused/1, index/1, version/2, unused/1 -- null if (oparg & 1), res)) {
11371133
assert(cframe.use_tracing == 0);
11381134
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
11391135
PyDictObject *dict = (PyDictObject *)GLOBALS();
1140-
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
1141-
uint32_t version = read_u32(cache->module_keys_version);
11421136
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
11431137
assert(DK_IS_UNICODE(dict->ma_keys));
11441138
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
1145-
PyObject *res = entries[cache->index].me_value;
1139+
res = entries[index].me_value;
11461140
DEOPT_IF(res == NULL, LOAD_GLOBAL);
1147-
int push_null = oparg & 1;
1148-
PEEK(0) = NULL;
1149-
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL);
1141+
Py_INCREF(res);
11501142
STAT_INC(LOAD_GLOBAL, hit);
1151-
STACK_GROW(push_null+1);
1152-
SET_TOP(Py_NewRef(res));
1143+
null = NULL;
11531144
}
11541145

1155-
// error: LOAD_GLOBAL has irregular stack effect
1156-
inst(LOAD_GLOBAL_BUILTIN) {
1146+
inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/2, bltn_version/1 -- null if (oparg & 1), res)) {
11571147
assert(cframe.use_tracing == 0);
11581148
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
11591149
DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL);
11601150
PyDictObject *mdict = (PyDictObject *)GLOBALS();
11611151
PyDictObject *bdict = (PyDictObject *)BUILTINS();
1162-
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
1163-
uint32_t mod_version = read_u32(cache->module_keys_version);
1164-
uint16_t bltn_version = cache->builtin_keys_version;
11651152
DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL);
11661153
DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL);
11671154
assert(DK_IS_UNICODE(bdict->ma_keys));
11681155
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys);
1169-
PyObject *res = entries[cache->index].me_value;
1156+
res = entries[index].me_value;
11701157
DEOPT_IF(res == NULL, LOAD_GLOBAL);
1171-
int push_null = oparg & 1;
1172-
PEEK(0) = NULL;
1173-
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL);
1158+
Py_INCREF(res);
11741159
STAT_INC(LOAD_GLOBAL, hit);
1175-
STACK_GROW(push_null+1);
1176-
SET_TOP(Py_NewRef(res));
1160+
null = NULL;
11771161
}
11781162

11791163
inst(DELETE_FAST, (--)) {
@@ -3212,9 +3196,6 @@ family(call, INLINE_CACHE_ENTRIES_CALL) = {
32123196
family(for_iter, INLINE_CACHE_ENTRIES_FOR_ITER) = {
32133197
FOR_ITER, FOR_ITER_LIST,
32143198
FOR_ITER_RANGE };
3215-
family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = {
3216-
LOAD_GLOBAL, LOAD_GLOBAL_BUILTIN,
3217-
LOAD_GLOBAL_MODULE };
32183199
family(store_fast) = { STORE_FAST, STORE_FAST__LOAD_FAST, STORE_FAST__STORE_FAST };
32193200
family(unpack_sequence, INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE) = {
32203201
UNPACK_SEQUENCE, UNPACK_SEQUENCE_LIST,

Python/generated_cases.c.h

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

Python/opcode_metadata.h

+10-10
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
141141
case LOAD_NAME:
142142
return 0;
143143
case LOAD_GLOBAL:
144-
return -1;
144+
return 0;
145145
case LOAD_GLOBAL_MODULE:
146-
return -1;
146+
return 0;
147147
case LOAD_GLOBAL_BUILTIN:
148-
return -1;
148+
return 0;
149149
case DELETE_FAST:
150150
return 0;
151151
case MAKE_CELL:
@@ -487,11 +487,11 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
487487
case LOAD_NAME:
488488
return 1;
489489
case LOAD_GLOBAL:
490-
return -1;
490+
return ((oparg & 1) ? 1 : 0) + 1;
491491
case LOAD_GLOBAL_MODULE:
492-
return -1;
492+
return ((oparg & 1) ? 1 : 0) + 1;
493493
case LOAD_GLOBAL_BUILTIN:
494-
return -1;
494+
return ((oparg & 1) ? 1 : 0) + 1;
495495
case DELETE_FAST:
496496
return 0;
497497
case MAKE_CELL:
@@ -694,7 +694,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
694694
}
695695
#endif
696696
enum Direction { DIR_NONE, DIR_READ, DIR_WRITE };
697-
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 };
697+
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 };
698698
struct opcode_metadata {
699699
enum Direction dir_op1;
700700
enum Direction dir_op2;
@@ -769,9 +769,9 @@ struct opcode_metadata {
769769
[STORE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
770770
[DELETE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
771771
[LOAD_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
772-
[LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
773-
[LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
774-
[LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
772+
[LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
773+
[LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
774+
[LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 },
775775
[DELETE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
776776
[MAKE_CELL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
777777
[DELETE_DEREF] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },

0 commit comments

Comments
 (0)