diff options
author | Mark Shannon <mark@hotpy.org> | 2022-03-17 16:14:57 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-17 16:14:57 (GMT) |
commit | 3011a097bd9500c007bd8b8d005edeea895f6b44 (patch) | |
tree | d2637ab682e1265eaf23316add1039b3829abb19 /Python | |
parent | ef1327e3b622e0cafdf8bfc1f480fed0dd386be6 (diff) | |
download | cpython-3011a097bd9500c007bd8b8d005edeea895f6b44.zip cpython-3011a097bd9500c007bd8b8d005edeea895f6b44.tar.gz cpython-3011a097bd9500c007bd8b8d005edeea895f6b44.tar.bz2 |
Use low bit of LOAD_GLOBAL's oparg to indicate whether it should push an additional NULL. (GH-31933)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 18 | ||||
-rw-r--r-- | Python/compile.c | 15 |
2 files changed, 26 insertions, 7 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 81759ad..1a120bb 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2947,7 +2947,9 @@ handle_eval_breaker: TARGET(LOAD_GLOBAL) { PREDICTED(LOAD_GLOBAL); - PyObject *name = GETITEM(names, oparg); + int push_null = oparg & 1; + PEEK(0) = NULL; + PyObject *name = GETITEM(names, oparg>>1); PyObject *v; if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) @@ -2970,7 +2972,6 @@ handle_eval_breaker: /* Slow-path if globals or builtins is not a dict */ /* namespace 1: globals */ - name = GETITEM(names, oparg); v = PyObject_GetItem(GLOBALS(), name); if (v == NULL) { if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { @@ -2992,6 +2993,7 @@ handle_eval_breaker: } /* Skip over inline cache */ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + STACK_GROW(push_null); PUSH(v); DISPATCH(); } @@ -3000,7 +3002,7 @@ handle_eval_breaker: assert(cframe.use_tracing == 0); _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (cache->counter == 0) { - PyObject *name = GETITEM(names, oparg); + PyObject *name = GETITEM(names, oparg>>1); next_instr--; if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name) < 0) { goto error; @@ -3025,10 +3027,13 @@ handle_eval_breaker: PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyObject *res = entries[cache->index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); + int push_null = oparg & 1; + PEEK(0) = NULL; JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); + STACK_GROW(push_null+1); Py_INCREF(res); - PUSH(res); + SET_TOP(res); NOTRACE_DISPATCH(); } @@ -3047,10 +3052,13 @@ handle_eval_breaker: PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); PyObject *res = entries[cache->index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); + int push_null = oparg & 1; + PEEK(0) = NULL; JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); + STACK_GROW(push_null+1); Py_INCREF(res); - PUSH(res); + SET_TOP(res); NOTRACE_DISPATCH(); } diff --git a/Python/compile.c b/Python/compile.c index ac9ddbc..950c44a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1000,7 +1000,7 @@ stack_effect(int opcode, int oparg, int jump) return -1; case LOAD_GLOBAL: - return 1; + return (oparg & 1) + 1; /* Exception handling pseudo-instructions */ case SETUP_FINALLY: @@ -4185,8 +4185,12 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) assert(op); arg = compiler_add_o(dict, mangled); Py_DECREF(mangled); - if (arg < 0) + if (arg < 0) { return 0; + } + if (op == LOAD_GLOBAL) { + arg <<= 1; + } return compiler_addop_i(c, op, arg); } @@ -8812,6 +8816,13 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) break; case KW_NAMES: break; + case PUSH_NULL: + if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) { + inst->i_opcode = NOP; + inst->i_oparg = 0; + inst[1].i_oparg |= 1; + } + break; default: /* All HAS_CONST opcodes should be handled with LOAD_CONST */ assert (!HAS_CONST(inst->i_opcode)); |