mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
GH-113710: Improve _SET_IP
and _CHECK_VALIDITY
(GH-115248)
This commit is contained in:
parent
de07941729
commit
681778c56a
7 changed files with 79 additions and 35 deletions
3
Include/internal/pycore_uop_ids.h
generated
3
Include/internal/pycore_uop_ids.h
generated
|
@ -237,7 +237,8 @@ extern "C" {
|
||||||
#define _CHECK_GLOBALS 384
|
#define _CHECK_GLOBALS 384
|
||||||
#define _CHECK_BUILTINS 385
|
#define _CHECK_BUILTINS 385
|
||||||
#define _INTERNAL_INCREMENT_OPT_COUNTER 386
|
#define _INTERNAL_INCREMENT_OPT_COUNTER 386
|
||||||
#define MAX_UOP_ID 386
|
#define _CHECK_VALIDITY_AND_SET_IP 387
|
||||||
|
#define MAX_UOP_ID 387
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||||
[_GUARD_IS_NONE_POP] = HAS_DEOPT_FLAG,
|
[_GUARD_IS_NONE_POP] = HAS_DEOPT_FLAG,
|
||||||
[_GUARD_IS_NOT_NONE_POP] = HAS_DEOPT_FLAG,
|
[_GUARD_IS_NOT_NONE_POP] = HAS_DEOPT_FLAG,
|
||||||
[_JUMP_TO_TOP] = HAS_EVAL_BREAK_FLAG,
|
[_JUMP_TO_TOP] = HAS_EVAL_BREAK_FLAG,
|
||||||
[_SET_IP] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
|
[_SET_IP] = 0,
|
||||||
[_SAVE_RETURN_OFFSET] = HAS_ARG_FLAG,
|
[_SAVE_RETURN_OFFSET] = HAS_ARG_FLAG,
|
||||||
[_EXIT_TRACE] = HAS_DEOPT_FLAG,
|
[_EXIT_TRACE] = HAS_DEOPT_FLAG,
|
||||||
[_CHECK_VALIDITY] = HAS_DEOPT_FLAG,
|
[_CHECK_VALIDITY] = HAS_DEOPT_FLAG,
|
||||||
|
@ -209,6 +209,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||||
[_CHECK_GLOBALS] = HAS_DEOPT_FLAG,
|
[_CHECK_GLOBALS] = HAS_DEOPT_FLAG,
|
||||||
[_CHECK_BUILTINS] = HAS_DEOPT_FLAG,
|
[_CHECK_BUILTINS] = HAS_DEOPT_FLAG,
|
||||||
[_INTERNAL_INCREMENT_OPT_COUNTER] = 0,
|
[_INTERNAL_INCREMENT_OPT_COUNTER] = 0,
|
||||||
|
[_CHECK_VALIDITY_AND_SET_IP] = HAS_DEOPT_FLAG,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
||||||
|
@ -264,6 +265,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
||||||
[_CHECK_PEP_523] = "_CHECK_PEP_523",
|
[_CHECK_PEP_523] = "_CHECK_PEP_523",
|
||||||
[_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
|
[_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
|
||||||
[_CHECK_VALIDITY] = "_CHECK_VALIDITY",
|
[_CHECK_VALIDITY] = "_CHECK_VALIDITY",
|
||||||
|
[_CHECK_VALIDITY_AND_SET_IP] = "_CHECK_VALIDITY_AND_SET_IP",
|
||||||
[_COMPARE_OP] = "_COMPARE_OP",
|
[_COMPARE_OP] = "_COMPARE_OP",
|
||||||
[_COMPARE_OP_FLOAT] = "_COMPARE_OP_FLOAT",
|
[_COMPARE_OP_FLOAT] = "_COMPARE_OP_FLOAT",
|
||||||
[_COMPARE_OP_INT] = "_COMPARE_OP_INT",
|
[_COMPARE_OP_INT] = "_COMPARE_OP_INT",
|
||||||
|
|
|
@ -4037,10 +4037,9 @@ dummy_func(
|
||||||
CHECK_EVAL_BREAKER();
|
CHECK_EVAL_BREAKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_SET_IP, (--)) {
|
op(_SET_IP, (instr_ptr/4 --)) {
|
||||||
TIER_TWO_ONLY
|
TIER_TWO_ONLY
|
||||||
// TODO: Put the code pointer in `operand` to avoid indirection via `frame`
|
frame->instr_ptr = (_Py_CODEUNIT *)instr_ptr;
|
||||||
frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + oparg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_SAVE_RETURN_OFFSET, (--)) {
|
op(_SAVE_RETURN_OFFSET, (--)) {
|
||||||
|
@ -4100,6 +4099,11 @@ dummy_func(
|
||||||
exe->count++;
|
exe->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
op(_CHECK_VALIDITY_AND_SET_IP, (instr_ptr/4 --)) {
|
||||||
|
TIER_TWO_ONLY
|
||||||
|
DEOPT_IF(!current_executor->vm_data.valid);
|
||||||
|
frame->instr_ptr = (_Py_CODEUNIT *)instr_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
// END BYTECODES //
|
// END BYTECODES //
|
||||||
|
|
||||||
|
|
13
Python/executor_cases.c.h
generated
13
Python/executor_cases.c.h
generated
|
@ -3360,10 +3360,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
case _SET_IP: {
|
case _SET_IP: {
|
||||||
oparg = CURRENT_OPARG();
|
PyObject *instr_ptr = (PyObject *)CURRENT_OPERAND();
|
||||||
TIER_TWO_ONLY
|
TIER_TWO_ONLY
|
||||||
// TODO: Put the code pointer in `operand` to avoid indirection via `frame`
|
frame->instr_ptr = (_Py_CODEUNIT *)instr_ptr;
|
||||||
frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + oparg;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3459,4 +3458,12 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case _CHECK_VALIDITY_AND_SET_IP: {
|
||||||
|
PyObject *instr_ptr = (PyObject *)CURRENT_OPERAND();
|
||||||
|
TIER_TWO_ONLY
|
||||||
|
if (!current_executor->vm_data.valid) goto deoptimize;
|
||||||
|
frame->instr_ptr = (_Py_CODEUNIT *)instr_ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#undef TIER_TWO
|
#undef TIER_TWO
|
||||||
|
|
|
@ -432,9 +432,8 @@ translate_bytecode_to_trace(
|
||||||
top: // Jump here after _PUSH_FRAME or likely branches
|
top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
for (;;) {
|
for (;;) {
|
||||||
target = INSTR_IP(instr, code);
|
target = INSTR_IP(instr, code);
|
||||||
RESERVE_RAW(3, "epilogue"); // Always need space for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
|
RESERVE_RAW(2, "epilogue"); // Always need space for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
|
||||||
ADD_TO_TRACE(_SET_IP, target, 0, target);
|
ADD_TO_TRACE(_CHECK_VALIDITY_AND_SET_IP, 0, (uintptr_t)instr, target);
|
||||||
ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target);
|
|
||||||
|
|
||||||
uint32_t opcode = instr->op.code;
|
uint32_t opcode = instr->op.code;
|
||||||
uint32_t oparg = instr->op.arg;
|
uint32_t oparg = instr->op.arg;
|
||||||
|
|
|
@ -652,35 +652,62 @@ error:
|
||||||
static void
|
static void
|
||||||
remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
|
remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
|
||||||
{
|
{
|
||||||
|
/* Remove _SET_IP and _CHECK_VALIDITY where possible.
|
||||||
|
* _SET_IP is needed if the following instruction escapes or
|
||||||
|
* could error. _CHECK_VALIDITY is needed if the previous
|
||||||
|
* instruction could have escaped. */
|
||||||
int last_set_ip = -1;
|
int last_set_ip = -1;
|
||||||
bool maybe_invalid = false;
|
bool may_have_escaped = false;
|
||||||
for (int pc = 0; pc < buffer_size; pc++) {
|
for (int pc = 0; pc < buffer_size; pc++) {
|
||||||
int opcode = buffer[pc].opcode;
|
int opcode = buffer[pc].opcode;
|
||||||
if (opcode == _SET_IP) {
|
switch (opcode) {
|
||||||
buffer[pc].opcode = NOP;
|
case _SET_IP:
|
||||||
last_set_ip = pc;
|
|
||||||
}
|
|
||||||
else if (opcode == _CHECK_VALIDITY) {
|
|
||||||
if (maybe_invalid) {
|
|
||||||
maybe_invalid = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
buffer[pc].opcode = NOP;
|
buffer[pc].opcode = NOP;
|
||||||
}
|
last_set_ip = pc;
|
||||||
}
|
break;
|
||||||
else if (op_is_end(opcode)) {
|
case _CHECK_VALIDITY:
|
||||||
break;
|
if (may_have_escaped) {
|
||||||
}
|
may_have_escaped = false;
|
||||||
else {
|
|
||||||
if (_PyUop_Flags[opcode] & HAS_ESCAPES_FLAG) {
|
|
||||||
maybe_invalid = true;
|
|
||||||
if (last_set_ip >= 0) {
|
|
||||||
buffer[last_set_ip].opcode = _SET_IP;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
if ((_PyUop_Flags[opcode] & HAS_ERROR_FLAG) || opcode == _PUSH_FRAME) {
|
buffer[pc].opcode = NOP;
|
||||||
if (last_set_ip >= 0) {
|
}
|
||||||
buffer[last_set_ip].opcode = _SET_IP;
|
break;
|
||||||
|
case _CHECK_VALIDITY_AND_SET_IP:
|
||||||
|
if (may_have_escaped) {
|
||||||
|
may_have_escaped = false;
|
||||||
|
buffer[pc].opcode = _CHECK_VALIDITY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buffer[pc].opcode = NOP;
|
||||||
|
}
|
||||||
|
last_set_ip = pc;
|
||||||
|
break;
|
||||||
|
case _JUMP_TO_TOP:
|
||||||
|
case _EXIT_TRACE:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
bool needs_ip = false;
|
||||||
|
if (_PyUop_Flags[opcode] & HAS_ESCAPES_FLAG) {
|
||||||
|
needs_ip = true;
|
||||||
|
may_have_escaped = true;
|
||||||
|
}
|
||||||
|
if (_PyUop_Flags[opcode] & HAS_ERROR_FLAG) {
|
||||||
|
needs_ip = true;
|
||||||
|
}
|
||||||
|
if (opcode == _PUSH_FRAME) {
|
||||||
|
needs_ip = true;
|
||||||
|
}
|
||||||
|
if (needs_ip && last_set_ip >= 0) {
|
||||||
|
if (buffer[last_set_ip].opcode == _CHECK_VALIDITY) {
|
||||||
|
buffer[last_set_ip].opcode = _CHECK_VALIDITY_AND_SET_IP;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(buffer[last_set_ip].opcode == _NOP);
|
||||||
|
buffer[last_set_ip].opcode = _SET_IP;
|
||||||
|
}
|
||||||
|
last_set_ip = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1674,3 +1674,7 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case _CHECK_VALIDITY_AND_SET_IP: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue