mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-122029: Move monitoring after method expand for CALL_KW (GH-130488)
This commit is contained in:
parent
3774d9f7b5
commit
c5f925c8c9
4 changed files with 45 additions and 28 deletions
|
@ -493,6 +493,24 @@ class TestEdgeCases(unittest.TestCase):
|
||||||
# The last c_call is the call to sys.setprofile
|
# The last c_call is the call to sys.setprofile
|
||||||
self.assertEqual(events, ['c_call', 'c_return', 'c_call'])
|
self.assertEqual(events, ['c_call', 'c_return', 'c_call'])
|
||||||
|
|
||||||
|
class B:
|
||||||
|
f = classmethod(max)
|
||||||
|
events = []
|
||||||
|
sys.setprofile(lambda frame, event, args: events.append(event))
|
||||||
|
# Not important, we only want to trigger INSTRUMENTED_CALL_KW
|
||||||
|
B().f(1, key=lambda x: 0)
|
||||||
|
sys.setprofile(None)
|
||||||
|
# The last c_call is the call to sys.setprofile
|
||||||
|
self.assertEqual(
|
||||||
|
events,
|
||||||
|
['c_call',
|
||||||
|
'call', 'return',
|
||||||
|
'call', 'return',
|
||||||
|
'c_return',
|
||||||
|
'c_call'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
``INSTRUMENTED_CALL_KW`` will expand the method before monitoring to reflect the actual behavior more accurately.
|
|
@ -4509,8 +4509,8 @@ dummy_func(
|
||||||
macro(INSTRUMENTED_CALL_KW) =
|
macro(INSTRUMENTED_CALL_KW) =
|
||||||
counter/1 +
|
counter/1 +
|
||||||
unused/2 +
|
unused/2 +
|
||||||
_MONITOR_CALL_KW +
|
|
||||||
_MAYBE_EXPAND_METHOD_KW +
|
_MAYBE_EXPAND_METHOD_KW +
|
||||||
|
_MONITOR_CALL_KW +
|
||||||
_DO_CALL_KW;
|
_DO_CALL_KW;
|
||||||
|
|
||||||
op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable[1], unused[1], unused[oparg], kwnames -- callable[1], unused[1], unused[oparg], kwnames)) {
|
op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable[1], unused[1], unused[oparg], kwnames -- callable[1], unused[1], unused[oparg], kwnames)) {
|
||||||
|
|
52
Python/generated_cases.c.h
generated
52
Python/generated_cases.c.h
generated
|
@ -6413,14 +6413,37 @@
|
||||||
_PyStackRef *callable;
|
_PyStackRef *callable;
|
||||||
_PyStackRef *self_or_null;
|
_PyStackRef *self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef kwnames;
|
|
||||||
_PyStackRef kwnames_in;
|
_PyStackRef kwnames_in;
|
||||||
_PyStackRef *func;
|
_PyStackRef *func;
|
||||||
_PyStackRef *maybe_self;
|
_PyStackRef *maybe_self;
|
||||||
_PyStackRef kwnames_out;
|
_PyStackRef kwnames_out;
|
||||||
|
_PyStackRef kwnames;
|
||||||
_PyStackRef res;
|
_PyStackRef res;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
/* Skip 2 cache entries */
|
/* Skip 2 cache entries */
|
||||||
|
// _MAYBE_EXPAND_METHOD_KW
|
||||||
|
{
|
||||||
|
kwnames_in = stack_pointer[-1];
|
||||||
|
args = &stack_pointer[-1 - oparg];
|
||||||
|
self_or_null = &stack_pointer[-2 - oparg];
|
||||||
|
callable = &stack_pointer[-3 - oparg];
|
||||||
|
func = &stack_pointer[-3 - oparg];
|
||||||
|
maybe_self = &stack_pointer[-2 - oparg];
|
||||||
|
args = &stack_pointer[-1 - oparg];
|
||||||
|
(void)args;
|
||||||
|
if (PyStackRef_TYPE(callable[0]) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
|
||||||
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
|
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||||
|
maybe_self[0] = PyStackRef_FromPyObjectNew(self);
|
||||||
|
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||||
|
_PyStackRef temp = callable[0];
|
||||||
|
func[0] = PyStackRef_FromPyObjectNew(method);
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyStackRef_CLOSE(temp);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
}
|
||||||
|
kwnames_out = kwnames_in;
|
||||||
|
}
|
||||||
// _MONITOR_CALL_KW
|
// _MONITOR_CALL_KW
|
||||||
{
|
{
|
||||||
args = &stack_pointer[-1 - oparg];
|
args = &stack_pointer[-1 - oparg];
|
||||||
|
@ -6440,6 +6463,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PyObject *function = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *function = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
|
stack_pointer[-1] = kwnames_out;
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
int err = _Py_call_instrumentation_2args(
|
int err = _Py_call_instrumentation_2args(
|
||||||
tstate, PY_MONITORING_EVENT_CALL,
|
tstate, PY_MONITORING_EVENT_CALL,
|
||||||
|
@ -6449,32 +6473,9 @@
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// _MAYBE_EXPAND_METHOD_KW
|
|
||||||
{
|
|
||||||
kwnames_in = stack_pointer[-1];
|
|
||||||
func = &stack_pointer[-3 - oparg];
|
|
||||||
maybe_self = &stack_pointer[-2 - oparg];
|
|
||||||
args = &stack_pointer[-1 - oparg];
|
|
||||||
(void)args;
|
|
||||||
if (PyStackRef_TYPE(callable[0]) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
|
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
|
||||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
|
||||||
maybe_self[0] = PyStackRef_FromPyObjectNew(self);
|
|
||||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
|
||||||
_PyStackRef temp = callable[0];
|
|
||||||
func[0] = PyStackRef_FromPyObjectNew(method);
|
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
|
||||||
PyStackRef_CLOSE(temp);
|
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
|
||||||
}
|
|
||||||
kwnames_out = kwnames_in;
|
|
||||||
}
|
|
||||||
// _DO_CALL_KW
|
// _DO_CALL_KW
|
||||||
{
|
{
|
||||||
kwnames = kwnames_out;
|
kwnames = kwnames_out;
|
||||||
args = &stack_pointer[-1 - oparg];
|
|
||||||
self_or_null = &stack_pointer[-2 - oparg];
|
|
||||||
callable = &stack_pointer[-3 - oparg];
|
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
|
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
|
||||||
// oparg counts all of the args, but *not* self:
|
// oparg counts all of the args, but *not* self:
|
||||||
|
@ -6492,7 +6493,6 @@
|
||||||
{
|
{
|
||||||
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable_o))->co_flags;
|
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable_o))->co_flags;
|
||||||
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
|
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
|
||||||
stack_pointer[-1] = kwnames;
|
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
|
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
|
||||||
tstate, callable[0], locals,
|
tstate, callable[0], locals,
|
||||||
|
@ -6519,7 +6519,6 @@
|
||||||
/* Callable is not a normal Python function */
|
/* Callable is not a normal Python function */
|
||||||
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||||
if (CONVERSION_FAILED(args_o)) {
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
stack_pointer[-1] = kwnames;
|
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
_PyStackRef tmp = kwnames;
|
_PyStackRef tmp = kwnames;
|
||||||
kwnames = PyStackRef_NULL;
|
kwnames = PyStackRef_NULL;
|
||||||
|
@ -6541,7 +6540,6 @@
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
stack_pointer[-1] = kwnames;
|
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
PyObject *res_o = PyObject_Vectorcall(
|
PyObject *res_o = PyObject_Vectorcall(
|
||||||
callable_o, args_o,
|
callable_o, args_o,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue