mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
GH-118093: Specialize CALL_KW
(GH-123006)
This commit is contained in:
parent
e2f2dc708e
commit
c13e7d98fb
17 changed files with 1083 additions and 273 deletions
|
@ -1904,6 +1904,33 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
specialize_py_call_kw(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
|
||||
bool bound_method)
|
||||
{
|
||||
_PyCallCache *cache = (_PyCallCache *)(instr + 1);
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
int kind = function_kind(code);
|
||||
/* Don't specialize if PEP 523 is active */
|
||||
if (_PyInterpreterState_GET()->eval_frame) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523);
|
||||
return -1;
|
||||
}
|
||||
if (kind == SPEC_FAIL_CODE_NOT_OPTIMIZED) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CODE_NOT_OPTIMIZED);
|
||||
return -1;
|
||||
}
|
||||
int version = _PyFunction_GetVersionForCurrentState(func);
|
||||
if (version == 0) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_VERSIONS);
|
||||
return -1;
|
||||
}
|
||||
write_u32(cache->func_version, version);
|
||||
instr->op.code = bound_method ? CALL_KW_BOUND_METHOD : CALL_KW_PY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
||||
{
|
||||
|
@ -1999,6 +2026,46 @@ _Py_Specialize_Call(_PyStackRef callable_st, _Py_CODEUNIT *instr, int nargs)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
_Py_Specialize_CallKw(_PyStackRef callable_st, _Py_CODEUNIT *instr, int nargs)
|
||||
{
|
||||
PyObject *callable = PyStackRef_AsPyObjectBorrow(callable_st);
|
||||
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[CALL_KW] == INLINE_CACHE_ENTRIES_CALL_KW);
|
||||
assert(_Py_OPCODE(*instr) != INSTRUMENTED_CALL_KW);
|
||||
_PyCallCache *cache = (_PyCallCache *)(instr + 1);
|
||||
int fail;
|
||||
if (PyFunction_Check(callable)) {
|
||||
fail = specialize_py_call_kw((PyFunctionObject *)callable, instr, nargs, false);
|
||||
}
|
||||
else if (PyMethod_Check(callable)) {
|
||||
PyObject *func = ((PyMethodObject *)callable)->im_func;
|
||||
if (PyFunction_Check(func)) {
|
||||
fail = specialize_py_call_kw((PyFunctionObject *)func, instr, nargs, true);
|
||||
}
|
||||
else {
|
||||
SPECIALIZATION_FAIL(CALL_KW, SPEC_FAIL_CALL_BOUND_METHOD);
|
||||
fail = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
instr->op.code = CALL_KW_NON_PY;
|
||||
fail = 0;
|
||||
}
|
||||
if (fail) {
|
||||
STAT_INC(CALL, failure);
|
||||
assert(!PyErr_Occurred());
|
||||
instr->op.code = CALL_KW;
|
||||
cache->counter = adaptive_counter_backoff(cache->counter);
|
||||
}
|
||||
else {
|
||||
STAT_INC(CALL, success);
|
||||
assert(!PyErr_Occurred());
|
||||
cache->counter = adaptive_counter_cooldown();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Py_STATS
|
||||
static int
|
||||
binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue