mirror of
https://github.com/python/cpython.git
synced 2025-08-30 05:35:08 +00:00
GH-128685: Specialize (rather than quicken) LOAD_CONST into LOAD_CONST_[IM]MORTAL (GH-128708)
This commit is contained in:
parent
29fe8072cf
commit
ddd959987c
14 changed files with 121 additions and 65 deletions
|
@ -285,11 +285,25 @@ dummy_func(
|
|||
}
|
||||
|
||||
family(LOAD_CONST, 0) = {
|
||||
LOAD_CONST_MORTAL,
|
||||
LOAD_CONST_IMMORTAL,
|
||||
};
|
||||
|
||||
pure inst(LOAD_CONST, (-- value)) {
|
||||
value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg));
|
||||
inst(LOAD_CONST, (-- value)) {
|
||||
/* We can't do this in the bytecode compiler as
|
||||
* marshalling can intern strings and make them immortal. */
|
||||
PyObject *obj = GETITEM(FRAME_CO_CONSTS, oparg);
|
||||
value = PyStackRef_FromPyObjectNew(obj);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
if (this_instr->op.code == LOAD_CONST) {
|
||||
this_instr->op.code = _Py_IsImmortal(obj) ? LOAD_CONST_IMMORTAL : LOAD_CONST_MORTAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inst(LOAD_CONST_MORTAL, (-- value)) {
|
||||
PyObject *obj = GETITEM(FRAME_CO_CONSTS, oparg);
|
||||
value = PyStackRef_FromPyObjectNew(obj);
|
||||
}
|
||||
|
||||
inst(LOAD_CONST_IMMORTAL, (-- value)) {
|
||||
|
|
7
Python/executor_cases.c.h
generated
7
Python/executor_cases.c.h
generated
|
@ -209,10 +209,13 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _LOAD_CONST: {
|
||||
/* _LOAD_CONST is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||
|
||||
case _LOAD_CONST_MORTAL: {
|
||||
_PyStackRef value;
|
||||
oparg = CURRENT_OPARG();
|
||||
value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg));
|
||||
PyObject *obj = GETITEM(FRAME_CO_CONSTS, oparg);
|
||||
value = PyStackRef_FromPyObjectNew(obj);
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
|
26
Python/generated_cases.c.h
generated
26
Python/generated_cases.c.h
generated
|
@ -5913,8 +5913,18 @@
|
|||
next_instr += 1;
|
||||
INSTRUCTION_STATS(LOAD_CONST);
|
||||
PREDICTED(LOAD_CONST);
|
||||
_Py_CODEUNIT* const this_instr = next_instr - 1;
|
||||
(void)this_instr;
|
||||
_PyStackRef value;
|
||||
value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg));
|
||||
/* We can't do this in the bytecode compiler as
|
||||
* marshalling can intern strings and make them immortal. */
|
||||
PyObject *obj = GETITEM(FRAME_CO_CONSTS, oparg);
|
||||
value = PyStackRef_FromPyObjectNew(obj);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
if (this_instr->op.code == LOAD_CONST) {
|
||||
this_instr->op.code = _Py_IsImmortal(obj) ? LOAD_CONST_IMMORTAL : LOAD_CONST_MORTAL;
|
||||
}
|
||||
#endif
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -5936,6 +5946,20 @@
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(LOAD_CONST_MORTAL) {
|
||||
frame->instr_ptr = next_instr;
|
||||
next_instr += 1;
|
||||
INSTRUCTION_STATS(LOAD_CONST_MORTAL);
|
||||
static_assert(0 == 0, "incorrect cache size");
|
||||
_PyStackRef value;
|
||||
PyObject *obj = GETITEM(FRAME_CO_CONSTS, oparg);
|
||||
value = PyStackRef_FromPyObjectNew(obj);
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(LOAD_DEREF) {
|
||||
frame->instr_ptr = next_instr;
|
||||
next_instr += 1;
|
||||
|
|
2
Python/opcode_targets.h
generated
2
Python/opcode_targets.h
generated
|
@ -207,6 +207,7 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_LOAD_ATTR_SLOT,
|
||||
&&TARGET_LOAD_ATTR_WITH_HINT,
|
||||
&&TARGET_LOAD_CONST_IMMORTAL,
|
||||
&&TARGET_LOAD_CONST_MORTAL,
|
||||
&&TARGET_LOAD_GLOBAL_BUILTIN,
|
||||
&&TARGET_LOAD_GLOBAL_MODULE,
|
||||
&&TARGET_LOAD_SUPER_ATTR_ATTR,
|
||||
|
@ -233,7 +234,6 @@ static void *opcode_targets[256] = {
|
|||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&TARGET_INSTRUMENTED_END_FOR,
|
||||
&&TARGET_INSTRUMENTED_POP_ITER,
|
||||
&&TARGET_INSTRUMENTED_END_SEND,
|
||||
|
|
|
@ -479,6 +479,13 @@ dummy_func(void) {
|
|||
value = sym_new_const(ctx, val);
|
||||
}
|
||||
|
||||
op(_LOAD_CONST_MORTAL, (-- value)) {
|
||||
PyObject *val = PyTuple_GET_ITEM(co->co_consts, this_instr->oparg);
|
||||
int opcode = _Py_IsImmortal(val) ? _LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE;
|
||||
REPLACE_OP(this_instr, opcode, 0, (uintptr_t)val);
|
||||
value = sym_new_const(ctx, val);
|
||||
}
|
||||
|
||||
op(_LOAD_CONST_IMMORTAL, (-- value)) {
|
||||
PyObject *val = PyTuple_GET_ITEM(co->co_consts, this_instr->oparg);
|
||||
REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val);
|
||||
|
|
4
Python/optimizer_cases.c.h
generated
4
Python/optimizer_cases.c.h
generated
|
@ -58,7 +58,9 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _LOAD_CONST: {
|
||||
/* _LOAD_CONST is not a viable micro-op for tier 2 */
|
||||
|
||||
case _LOAD_CONST_MORTAL: {
|
||||
_Py_UopsSymbol *value;
|
||||
PyObject *val = PyTuple_GET_ITEM(co->co_consts, this_instr->oparg);
|
||||
int opcode = _Py_IsImmortal(val) ? _LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE;
|
||||
|
|
|
@ -478,15 +478,6 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, PyObject *consts,
|
|||
}
|
||||
i += caches;
|
||||
}
|
||||
else if (opcode == LOAD_CONST) {
|
||||
/* We can't do this in the bytecode compiler as
|
||||
* marshalling can intern strings and make them immortal. */
|
||||
|
||||
PyObject *obj = PyTuple_GET_ITEM(consts, oparg);
|
||||
if (_Py_IsImmortal(obj)) {
|
||||
instructions[i].op.code = LOAD_CONST_IMMORTAL;
|
||||
}
|
||||
}
|
||||
if (opcode != EXTENDED_ARG) {
|
||||
oparg = 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue