mirror of
https://github.com/python/cpython.git
synced 2025-07-09 20:35:26 +00:00
gh-106581: Split CALL_BOUND_METHOD_EXACT_ARGS into uops (#108462)
Instead of using `GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS)` we just add the macro elements of the latter to the macro for the former. This requires lengthening the uops array in struct opcode_macro_expansion. (It also required changes to stacking.py that were merged already.)
This commit is contained in:
parent
546cab8444
commit
ddf66b54ed
6 changed files with 171 additions and 35 deletions
98
Python/generated_cases.c.h
generated
98
Python/generated_cases.c.h
generated
|
@ -3795,23 +3795,99 @@
|
|||
TARGET(CALL_BOUND_METHOD_EXACT_ARGS) {
|
||||
PyObject *null;
|
||||
PyObject *callable;
|
||||
PyObject *self;
|
||||
PyObject *self_or_null;
|
||||
PyObject *func;
|
||||
PyObject **args;
|
||||
_PyInterpreterFrame *new_frame;
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||
}
|
||||
// _CHECK_CALL_BOUND_METHOD_EXACT_ARGS
|
||||
null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
DEOPT_IF(null != NULL, CALL);
|
||||
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
|
||||
STAT_INC(CALL, hit);
|
||||
PyObject *self = ((PyMethodObject *)callable)->im_self;
|
||||
PEEK(oparg + 1) = Py_NewRef(self); // self_or_null
|
||||
PyObject *meth = ((PyMethodObject *)callable)->im_func;
|
||||
PEEK(oparg + 2) = Py_NewRef(meth); // callable
|
||||
Py_DECREF(callable);
|
||||
GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS);
|
||||
{
|
||||
DEOPT_IF(null != NULL, CALL);
|
||||
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
|
||||
}
|
||||
// _INIT_CALL_BOUND_METHOD_EXACT_ARGS
|
||||
{
|
||||
STAT_INC(CALL, hit);
|
||||
self = Py_NewRef(((PyMethodObject *)callable)->im_self);
|
||||
stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _INIT_CALL_PY_EXACT_ARGS
|
||||
func = Py_NewRef(((PyMethodObject *)callable)->im_func);
|
||||
stack_pointer[-2 - oparg] = func; // This is used by CALL, upon deoptimization
|
||||
Py_DECREF(callable);
|
||||
}
|
||||
// _CHECK_FUNCTION_EXACT_ARGS
|
||||
self_or_null = self;
|
||||
callable = func;
|
||||
{
|
||||
uint32_t func_version = read_u32(&next_instr[1].cache);
|
||||
ASSERT_KWNAMES_IS_NULL();
|
||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
DEOPT_IF(func->func_version != func_version, CALL);
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
||||
}
|
||||
// _CHECK_STACK_SPACE
|
||||
{
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
|
||||
}
|
||||
// _INIT_CALL_PY_EXACT_ARGS
|
||||
args = stack_pointer - oparg;
|
||||
{
|
||||
int argcount = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
argcount++;
|
||||
}
|
||||
STAT_INC(CALL, hit);
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
new_frame = _PyFrame_PushUnchecked(tstate, func, argcount);
|
||||
for (int i = 0; i < argcount; i++) {
|
||||
new_frame->localsplus[i] = args[i];
|
||||
}
|
||||
}
|
||||
// SAVE_CURRENT_IP
|
||||
next_instr += 3;
|
||||
{
|
||||
#if TIER_ONE
|
||||
frame->prev_instr = next_instr - 1;
|
||||
#endif
|
||||
#if TIER_TWO
|
||||
// Relies on a preceding SAVE_IP
|
||||
frame->prev_instr--;
|
||||
#endif
|
||||
}
|
||||
// _PUSH_FRAME
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
STACK_SHRINK(2);
|
||||
{
|
||||
// Write it out explicitly because it's subtly different.
|
||||
// Eventually this should be the only occurrence of this code.
|
||||
frame->return_offset = 0;
|
||||
assert(tstate->interp->eval_frame == NULL);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
new_frame->previous = frame;
|
||||
CALL_STAT_INC(inlined_py_calls);
|
||||
frame = tstate->current_frame = new_frame;
|
||||
#if TIER_ONE
|
||||
goto start_frame;
|
||||
#endif
|
||||
#if TIER_TWO
|
||||
if (_Py_EnterRecursivePy(tstate)) goto pop_1_exit_unwind;
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
TARGET(CALL_PY_EXACT_ARGS) {
|
||||
PREDICTED(CALL_PY_EXACT_ARGS);
|
||||
PyObject *self_or_null;
|
||||
PyObject *callable;
|
||||
PyObject **args;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue