gh-131798: JIT inline function addresses of builtin methods (#146906)

This commit is contained in:
Kumar Aditya 2026-04-04 09:12:13 +05:30 committed by GitHub
parent b8470deb5d
commit 7e275d4965
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 1724 additions and 1282 deletions

View file

@ -4813,13 +4813,11 @@ dummy_func(
}
// CPython promises to check all non-vectorcall function calls.
EXIT_IF(_Py_ReachedRecursionLimit(tstate));
_PyStackRef arg_stackref = arguments[1];
_PyStackRef self_stackref = arguments[0];
STAT_INC(CALL, hit);
PyCFunction cfunc = method->d_method->ml_meth;
PyObject *res_o = _PyCFunction_TrampolineCall(cfunc,
PyStackRef_AsPyObjectBorrow(self_stackref),
PyStackRef_AsPyObjectBorrow(arg_stackref));
PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]);
PyObject *arg = PyStackRef_AsPyObjectBorrow(arguments[1]);
PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, arg);
_Py_LeaveRecursiveCallTstate(tstate);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
if (res_o == NULL) {
@ -4832,6 +4830,26 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o);
}
tier2 op(_CALL_METHOD_DESCRIPTOR_O_INLINE, (callable, args[oparg], cfunc/4 -- res, c, s, a)) {
assert(oparg == 2);
EXIT_IF(_Py_ReachedRecursionLimit(tstate));
STAT_INC(CALL, hit);
volatile PyCFunction cfunc_v = (PyCFunction)cfunc;
PyObject *self = PyStackRef_AsPyObjectBorrow(args[0]);
PyObject *arg = PyStackRef_AsPyObjectBorrow(args[1]);
PyObject *res_o = _PyCFunction_TrampolineCall(cfunc_v, self, arg);
_Py_LeaveRecursiveCallTstate(tstate);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
if (res_o == NULL) {
ERROR_NO_POP();
}
c = callable;
s = args[0];
a = args[1];
INPUTS_DEAD();
res = PyStackRef_FromPyObjectSteal(res_o);
}
macro(CALL_METHOD_DESCRIPTOR_O) =
_RECORD_CALLABLE +
unused/1 +
@ -4872,9 +4890,10 @@ dummy_func(
PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]);
assert(self != NULL);
STAT_INC(CALL, hit);
PyCFunctionFastWithKeywords cfunc = _PyCFunctionFastWithKeywords_CAST(method->d_method->ml_meth);
PyObject *res_o = _PyCallMethodDescriptorFastWithKeywords_StackRefSteal(
callable,
method->d_method,
cfunc,
self,
arguments,
total_args
@ -4886,6 +4905,24 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o);
}
tier2 op(_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_INLINE, (callable, args[oparg], cfunc/4 -- res)) {
PyObject *self = PyStackRef_AsPyObjectBorrow(args[0]);
assert(self != NULL);
STAT_INC(CALL, hit);
volatile PyCFunctionFastWithKeywords cfunc_v = _PyCFunctionFastWithKeywords_CAST(cfunc);
PyObject *res_o = _PyCallMethodDescriptorFastWithKeywords_StackRefSteal(
callable,
cfunc_v,
self,
args,
oparg
);
DEAD(args);
DEAD(callable);
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
macro(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) =
_RECORD_CALLABLE +
unused/1 +
@ -4934,6 +4971,23 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o);
}
tier2 op(_CALL_METHOD_DESCRIPTOR_NOARGS_INLINE, (callable, args[oparg], cfunc/4 -- res)) {
assert(oparg == 1);
_PyStackRef self_stackref = args[0];
PyObject *self = PyStackRef_AsPyObjectBorrow(self_stackref);
EXIT_IF(_Py_ReachedRecursionLimit(tstate));
STAT_INC(CALL, hit);
volatile PyCFunction cfunc_v = (PyCFunction)cfunc;
PyObject *res_o = _PyCFunction_TrampolineCall(cfunc_v, self, NULL);
_Py_LeaveRecursiveCallTstate(tstate);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
PyStackRef_CLOSE(self_stackref);
DEAD(args);
PyStackRef_CLOSE(callable);
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
macro(CALL_METHOD_DESCRIPTOR_NOARGS) =
_RECORD_CALLABLE +
unused/1 +
@ -4971,9 +5025,10 @@ dummy_func(
PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]);
assert(self != NULL);
STAT_INC(CALL, hit);
PyCFunctionFast cfunc = _PyCFunctionFast_CAST(method->d_method->ml_meth);
PyObject *res_o = _PyCallMethodDescriptorFast_StackRefSteal(
callable,
method->d_method,
cfunc,
self,
arguments,
total_args
@ -4985,6 +5040,24 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o);
}
tier2 op(_CALL_METHOD_DESCRIPTOR_FAST_INLINE, (callable, args[oparg], cfunc/4 -- res)) {
PyObject *self = PyStackRef_AsPyObjectBorrow(args[0]);
assert(self != NULL);
STAT_INC(CALL, hit);
volatile PyCFunctionFast cfunc_v = _PyCFunctionFast_CAST(cfunc);
PyObject *res_o = _PyCallMethodDescriptorFast_StackRefSteal(
callable,
cfunc_v,
self,
args,
oparg
);
DEAD(args);
DEAD(callable);
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
macro(CALL_METHOD_DESCRIPTOR_FAST) =
unused/1 +
unused/2 +