mirror of https://github.com/python/cpython
bpo-46031: add POP_JUMP_IF_NOT_NONE and POP_JUMP_IF_NONE (GH-30019)
This commit is contained in:
parent
35d6540c90
commit
3db762db72
|
@ -896,6 +896,20 @@ All of the following opcodes use their arguments.
|
||||||
.. versionadded:: 3.11
|
.. versionadded:: 3.11
|
||||||
|
|
||||||
|
|
||||||
|
.. opcode:: POP_JUMP_IF_NOT_NONE (target)
|
||||||
|
|
||||||
|
If TOS is not none, sets the bytecode counter to *target*. TOS is popped.
|
||||||
|
|
||||||
|
.. versionadded:: 3.11
|
||||||
|
|
||||||
|
|
||||||
|
.. opcode:: POP_JUMP_IF_NONE (target)
|
||||||
|
|
||||||
|
If TOS is none, sets the bytecode counter to *target*. TOS is popped.
|
||||||
|
|
||||||
|
.. versionadded:: 3.11
|
||||||
|
|
||||||
|
|
||||||
.. opcode:: PREP_RERAISE_STAR
|
.. opcode:: PREP_RERAISE_STAR
|
||||||
|
|
||||||
Combines the raised and reraised exceptions list from TOS, into an exception
|
Combines the raised and reraised exceptions list from TOS, into an exception
|
||||||
|
|
|
@ -398,6 +398,9 @@ CPython bytecode changes
|
||||||
* Added :opcode:`COPY`, which pushes the *i*-th item to the top of the stack.
|
* Added :opcode:`COPY`, which pushes the *i*-th item to the top of the stack.
|
||||||
The item is not removed from its original location.
|
The item is not removed from its original location.
|
||||||
|
|
||||||
|
* Add :opcode:`POP_JUMP_IF_NOT_NONE` and :opcode:`POP_JUMP_IF_NONE` opcodes to
|
||||||
|
speed up conditional jumps.
|
||||||
|
|
||||||
* :opcode:`JUMP_IF_NOT_EXC_MATCH` no longer pops the active exception.
|
* :opcode:`JUMP_IF_NOT_EXC_MATCH` no longer pops the active exception.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@ extern "C" {
|
||||||
#define STORE_FAST 125
|
#define STORE_FAST 125
|
||||||
#define DELETE_FAST 126
|
#define DELETE_FAST 126
|
||||||
#define JUMP_IF_NOT_EG_MATCH 127
|
#define JUMP_IF_NOT_EG_MATCH 127
|
||||||
|
#define POP_JUMP_IF_NOT_NONE 128
|
||||||
|
#define POP_JUMP_IF_NONE 129
|
||||||
#define RAISE_VARARGS 130
|
#define RAISE_VARARGS 130
|
||||||
#define MAKE_FUNCTION 132
|
#define MAKE_FUNCTION 132
|
||||||
#define BUILD_SLICE 133
|
#define BUILD_SLICE 133
|
||||||
|
@ -162,10 +164,10 @@ extern "C" {
|
||||||
#define STORE_ATTR_SLOT 80
|
#define STORE_ATTR_SLOT 80
|
||||||
#define STORE_ATTR_WITH_HINT 81
|
#define STORE_ATTR_WITH_HINT 81
|
||||||
#define LOAD_FAST__LOAD_FAST 87
|
#define LOAD_FAST__LOAD_FAST 87
|
||||||
#define STORE_FAST__LOAD_FAST 128
|
#define STORE_FAST__LOAD_FAST 131
|
||||||
#define LOAD_FAST__LOAD_CONST 129
|
#define LOAD_FAST__LOAD_CONST 134
|
||||||
#define LOAD_CONST__LOAD_FAST 131
|
#define LOAD_CONST__LOAD_FAST 140
|
||||||
#define STORE_FAST__STORE_FAST 134
|
#define STORE_FAST__STORE_FAST 141
|
||||||
#define DO_TRACING 255
|
#define DO_TRACING 255
|
||||||
#ifdef NEED_OPCODE_JUMP_TABLES
|
#ifdef NEED_OPCODE_JUMP_TABLES
|
||||||
static uint32_t _PyOpcode_RelativeJump[8] = {
|
static uint32_t _PyOpcode_RelativeJump[8] = {
|
||||||
|
@ -183,7 +185,7 @@ static uint32_t _PyOpcode_Jump[8] = {
|
||||||
0U,
|
0U,
|
||||||
536870912U,
|
536870912U,
|
||||||
2316288000U,
|
2316288000U,
|
||||||
0U,
|
3U,
|
||||||
0U,
|
0U,
|
||||||
0U,
|
0U,
|
||||||
0U,
|
0U,
|
||||||
|
|
|
@ -378,6 +378,7 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Python 3.11a4 3470 (bpo-46221: PREP_RERAISE_STAR no longer pushes lasti)
|
# Python 3.11a4 3470 (bpo-46221: PREP_RERAISE_STAR no longer pushes lasti)
|
||||||
# Python 3.11a4 3471 (bpo-46202: remove pop POP_EXCEPT_AND_RERAISE)
|
# Python 3.11a4 3471 (bpo-46202: remove pop POP_EXCEPT_AND_RERAISE)
|
||||||
# Python 3.11a4 3472 (bpo-46009: replace GEN_START with POP_TOP)
|
# Python 3.11a4 3472 (bpo-46009: replace GEN_START with POP_TOP)
|
||||||
|
# Python 3.11a4 3473 (Add POP_JUMP_IF_NOT_NONE/POP_JUMP_IF_NONE opcodes)
|
||||||
|
|
||||||
#
|
#
|
||||||
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
||||||
|
@ -387,7 +388,7 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||||
# in PC/launcher.c must also be updated.
|
# in PC/launcher.c must also be updated.
|
||||||
|
|
||||||
MAGIC_NUMBER = (3472).to_bytes(2, 'little') + b'\r\n'
|
MAGIC_NUMBER = (3473).to_bytes(2, 'little') + b'\r\n'
|
||||||
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||||
|
|
||||||
_PYCACHE = '__pycache__'
|
_PYCACHE = '__pycache__'
|
||||||
|
|
|
@ -148,9 +148,9 @@ def_op('STORE_FAST', 125) # Local variable number
|
||||||
haslocal.append(125)
|
haslocal.append(125)
|
||||||
def_op('DELETE_FAST', 126) # Local variable number
|
def_op('DELETE_FAST', 126) # Local variable number
|
||||||
haslocal.append(126)
|
haslocal.append(126)
|
||||||
|
|
||||||
jabs_op('JUMP_IF_NOT_EG_MATCH', 127)
|
jabs_op('JUMP_IF_NOT_EG_MATCH', 127)
|
||||||
|
jabs_op('POP_JUMP_IF_NOT_NONE', 128)
|
||||||
|
jabs_op('POP_JUMP_IF_NONE', 129)
|
||||||
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
|
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
|
||||||
|
|
||||||
def_op('MAKE_FUNCTION', 132) # Flags
|
def_op('MAKE_FUNCTION', 132) # Flags
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Add :opcode:`POP_JUMP_IF_NOT_NONE` and :opcode:`POP_JUMP_IF_NONE` opcodes to speed up conditional jumps.
|
|
@ -4049,6 +4049,30 @@ check_eval_breaker:
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TARGET(POP_JUMP_IF_NOT_NONE) {
|
||||||
|
PyObject *value = POP();
|
||||||
|
if (!Py_IsNone(value)) {
|
||||||
|
Py_DECREF(value);
|
||||||
|
JUMPTO(oparg);
|
||||||
|
CHECK_EVAL_BREAKER();
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
Py_DECREF(value);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
|
||||||
|
TARGET(POP_JUMP_IF_NONE) {
|
||||||
|
PyObject *value = POP();
|
||||||
|
if (Py_IsNone(value)) {
|
||||||
|
Py_DECREF(value);
|
||||||
|
JUMPTO(oparg);
|
||||||
|
CHECK_EVAL_BREAKER();
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
Py_DECREF(value);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
|
||||||
TARGET(JUMP_IF_FALSE_OR_POP) {
|
TARGET(JUMP_IF_FALSE_OR_POP) {
|
||||||
PyObject *cond = TOP();
|
PyObject *cond = TOP();
|
||||||
int err;
|
int err;
|
||||||
|
|
|
@ -1110,6 +1110,8 @@ stack_effect(int opcode, int oparg, int jump)
|
||||||
|
|
||||||
case POP_JUMP_IF_FALSE:
|
case POP_JUMP_IF_FALSE:
|
||||||
case POP_JUMP_IF_TRUE:
|
case POP_JUMP_IF_TRUE:
|
||||||
|
case POP_JUMP_IF_NONE:
|
||||||
|
case POP_JUMP_IF_NOT_NONE:
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case LOAD_GLOBAL:
|
case LOAD_GLOBAL:
|
||||||
|
@ -8519,6 +8521,21 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
|
||||||
bb->b_instr[i+1].i_opcode = NOP;
|
bb->b_instr[i+1].i_opcode = NOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IS_OP:
|
||||||
|
cnt = get_const_value(inst->i_opcode, oparg, consts);
|
||||||
|
if (cnt == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0;
|
||||||
|
if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) {
|
||||||
|
unsigned char nextarg = bb->b_instr[i+1].i_oparg;
|
||||||
|
inst->i_opcode = NOP;
|
||||||
|
bb->b_instr[i+1].i_opcode = NOP;
|
||||||
|
bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ?
|
||||||
|
POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE;
|
||||||
|
}
|
||||||
|
Py_DECREF(cnt);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8611,6 +8628,14 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case POP_JUMP_IF_NOT_NONE:
|
||||||
|
case POP_JUMP_IF_NONE:
|
||||||
|
switch (target->i_opcode) {
|
||||||
|
case JUMP_ABSOLUTE:
|
||||||
|
case JUMP_FORWARD:
|
||||||
|
i -= jump_thread(inst, target, inst->i_opcode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case POP_JUMP_IF_FALSE:
|
case POP_JUMP_IF_FALSE:
|
||||||
switch (target->i_opcode) {
|
switch (target->i_opcode) {
|
||||||
case JUMP_ABSOLUTE:
|
case JUMP_ABSOLUTE:
|
||||||
|
@ -8766,6 +8791,8 @@ normalize_basic_block(basicblock *bb) {
|
||||||
case JUMP_FORWARD:
|
case JUMP_FORWARD:
|
||||||
bb->b_nofallthrough = 1;
|
bb->b_nofallthrough = 1;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
case POP_JUMP_IF_NOT_NONE:
|
||||||
|
case POP_JUMP_IF_NONE:
|
||||||
case POP_JUMP_IF_FALSE:
|
case POP_JUMP_IF_FALSE:
|
||||||
case POP_JUMP_IF_TRUE:
|
case POP_JUMP_IF_TRUE:
|
||||||
case JUMP_IF_FALSE_OR_POP:
|
case JUMP_IF_FALSE_OR_POP:
|
||||||
|
|
|
@ -127,20 +127,20 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_STORE_FAST,
|
&&TARGET_STORE_FAST,
|
||||||
&&TARGET_DELETE_FAST,
|
&&TARGET_DELETE_FAST,
|
||||||
&&TARGET_JUMP_IF_NOT_EG_MATCH,
|
&&TARGET_JUMP_IF_NOT_EG_MATCH,
|
||||||
&&TARGET_STORE_FAST__LOAD_FAST,
|
&&TARGET_POP_JUMP_IF_NOT_NONE,
|
||||||
&&TARGET_LOAD_FAST__LOAD_CONST,
|
&&TARGET_POP_JUMP_IF_NONE,
|
||||||
&&TARGET_RAISE_VARARGS,
|
&&TARGET_RAISE_VARARGS,
|
||||||
&&TARGET_LOAD_CONST__LOAD_FAST,
|
&&TARGET_STORE_FAST__LOAD_FAST,
|
||||||
&&TARGET_MAKE_FUNCTION,
|
&&TARGET_MAKE_FUNCTION,
|
||||||
&&TARGET_BUILD_SLICE,
|
&&TARGET_BUILD_SLICE,
|
||||||
&&TARGET_STORE_FAST__STORE_FAST,
|
&&TARGET_LOAD_FAST__LOAD_CONST,
|
||||||
&&TARGET_MAKE_CELL,
|
&&TARGET_MAKE_CELL,
|
||||||
&&TARGET_LOAD_CLOSURE,
|
&&TARGET_LOAD_CLOSURE,
|
||||||
&&TARGET_LOAD_DEREF,
|
&&TARGET_LOAD_DEREF,
|
||||||
&&TARGET_STORE_DEREF,
|
&&TARGET_STORE_DEREF,
|
||||||
&&TARGET_DELETE_DEREF,
|
&&TARGET_DELETE_DEREF,
|
||||||
&&_unknown_opcode,
|
&&TARGET_LOAD_CONST__LOAD_FAST,
|
||||||
&&_unknown_opcode,
|
&&TARGET_STORE_FAST__STORE_FAST,
|
||||||
&&TARGET_CALL_FUNCTION_EX,
|
&&TARGET_CALL_FUNCTION_EX,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&TARGET_EXTENDED_ARG,
|
&&TARGET_EXTENDED_ARG,
|
||||||
|
|
Loading…
Reference in New Issue