8000 bpo-47127: Specialize calls for fastcall c methods with keywords (GH-… · python/cpython@58448cb · GitHub
[go: up one dir, main page]

Skip to content

Commit 58448cb

Browse files
bpo-47127: Specialize calls for fastcall c methods with keywords (GH-32125)
* add PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS
1 parent 785cc67 commit 58448cb

File tree

6 files changed

+77
-37
lines changed

6 files changed

+77
-37
lines changed

Include/opcode.h

Lines changed: 28 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/opcode.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ def jabs_op(name, op, entries=0):
294294
"PRECALL_BOUND_METHOD",
295295
"PRECALL_BUILTIN_CLASS",
296296
"PRECALL_BUILTIN_FAST_WITH_KEYWORDS",
297+
"PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
297298
"PRECALL_NO_KW_BUILTIN_FAST",
298299
"PRECALL_NO_KW_BUILTIN_O",
299300
"PRECALL_NO_KW_ISINSTANCE",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Speed up calls to c functions with keyword arguments by 25% with specialization. Patch by Kumar Aditya.

Python/ceval.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5090,6 +5090,38 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
50905090
DISPATCH();
50915091
}
50925092

5093+
TARGET(PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) {
5094+
int is_meth = is_method(stack_pointer, oparg);
5095+
int total_args = oparg + is_meth;
5096+
PyObject *callable = PEEK(total_args + 1);
5097+
DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL);
5098+
PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method;
5099+
DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), PRECALL);
5100+
STAT_INC(PRECALL, hit);
5101+
SKIP_CALL();
5102+
int nargs = total_args-1;
5103+
STACK_SHRINK(nargs);
5104+
_PyCFunctionFastWithKeywords cfunc = (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth;
5105+
PyObject *self = TOP();
5106+
PyObject *res = cfunc(self, stack_pointer, nargs - KWNAMES_LEN(), call_shape.kwnames);
5107+
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
5108+
call_shape.kwnames = NULL;
5109+
5110+
/* Free the arguments. */
5111+
for (int i = 0; i < nargs; i++) {
5112+
Py_DECREF(stack_pointer[i]);
5113+
}
5114+
Py_DECREF(self);
5115+
STACK_SHRINK(2-is_meth);
5116+
SET_TOP(res);
5117+
Py_DECREF(callable);
5118+
if (res == NULL) {
5119+
goto error;
5120+
}
5121+
CHECK_EVAL_BREAKER();
5122+
DISPATCH();
5123+
}
5124+
50935125
TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) {
50945126
assert(call_shape.kwnames == NULL);
50955127
assert(oparg == 0 || oparg == 1);

Python/opcode_targets.h

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/specialize.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,10 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
14461446
_Py_SET_OPCODE(*instr, PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST);
14471447
return 0;
14481448
}
1449+
case METH_FASTCALL|METH_KEYWORDS: {
1450+
_Py_SET_OPCODE(*instr, PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS);
1451+
return 0;
1452+
}
14491453
}
14501454
SPECIALIZATION_FAIL(PRECALL, builtin_call_fail_kind(descr->d_method->ml_flags));
14511455
return -1;

0 commit comments

Comments
 (0)
0