mirror of
https://github.com/python/cpython.git
synced 2025-10-10 00:43:41 +00:00
GH-122029: Break INSTRUMENTED_CALL into micro-ops, so that its behavior is consistent with CALL (GH-122177)
This commit is contained in:
parent
afb0aa6ed2
commit
95a73917cd
11 changed files with 341 additions and 153 deletions
|
@ -3241,20 +3241,6 @@ dummy_func(
|
|||
unused/1 +
|
||||
_LOAD_ATTR_METHOD_LAZY_DICT;
|
||||
|
||||
inst(INSTRUMENTED_CALL, (unused/3 -- )) {
|
||||
int is_meth = PyStackRef_AsPyObjectBorrow(PEEK(oparg + 1)) != NULL;
|
||||
int total_args = oparg + is_meth;
|
||||
PyObject *function = PyStackRef_AsPyObjectBorrow(PEEK(oparg + 2));
|
||||
PyObject *arg = total_args == 0 ?
|
||||
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(PEEK(total_args));
|
||||
int err = _Py_call_instrumentation_2args(
|
||||
tstate, PY_MONITORING_EVENT_CALL,
|
||||
frame, this_instr, function, arg);
|
||||
ERROR_IF(err, error);
|
||||
PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
|
||||
GO_TO_INSTRUCTION(CALL);
|
||||
}
|
||||
|
||||
// Cache layout: counter/1, func_version/2
|
||||
// CALL_INTRINSIC_1/2, CALL_KW, and CALL_FUNCTION_EX aren't members!
|
||||
family(CALL, INLINE_CACHE_ENTRIES_CALL) = {
|
||||
|
@ -3292,28 +3278,34 @@ dummy_func(
|
|||
#endif /* ENABLE_SPECIALIZATION */
|
||||
}
|
||||
|
||||
op(_MAYBE_EXPAND_METHOD, (callable, self_or_null, args[oparg] -- func, maybe_self, args[oparg])) {
|
||||
if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null)) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||
maybe_self = PyStackRef_FromPyObjectNew(self);
|
||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||
func = PyStackRef_FromPyObjectNew(method);
|
||||
/* Make sure that callable and all args are in memory */
|
||||
args[-2] = func;
|
||||
args[-1] = maybe_self;
|
||||
PyStackRef_CLOSE(callable);
|
||||
}
|
||||
else {
|
||||
func = callable;
|
||||
maybe_self = self_or_null;
|
||||
}
|
||||
}
|
||||
|
||||
// When calling Python, inline the call using DISPATCH_INLINED().
|
||||
op(_CALL, (callable, self_or_null, args[oparg] -- res)) {
|
||||
op(_DO_CALL, (callable, self_or_null, args[oparg] -- res)) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
|
||||
|
||||
// oparg counts all of the args, but *not* self:
|
||||
int total_args = oparg;
|
||||
if (self_or_null_o != NULL) {
|
||||
if (!PyStackRef_IsNull(self_or_null)) {
|
||||
args--;
|
||||
total_args++;
|
||||
}
|
||||
else if (Py_TYPE(callable_o) == &PyMethod_Type) {
|
||||
args--;
|
||||
total_args++;
|
||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||
args[0] = PyStackRef_FromPyObjectNew(self);
|
||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||
args[-1] = PyStackRef_FromPyObjectNew(method);
|
||||
PyStackRef_CLOSE(callable);
|
||||
callable_o = method;
|
||||
callable = args[-1];
|
||||
}
|
||||
// Check if the call can be inlined or not
|
||||
if (Py_TYPE(callable_o) == &PyFunction_Type &&
|
||||
tstate->interp->eval_frame == NULL &&
|
||||
|
@ -3376,7 +3368,28 @@ dummy_func(
|
|||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
|
||||
macro(CALL) = _SPECIALIZE_CALL + unused/2 + _CALL + _CHECK_PERIODIC;
|
||||
op(_MONITOR_CALL, (func, maybe_self, args[oparg] -- func, maybe_self, args[oparg])) {
|
||||
int is_meth = !PyStackRef_IsNull(maybe_self);
|
||||
PyObject *function = PyStackRef_AsPyObjectBorrow(func);
|
||||
PyObject *arg0;
|
||||
if (is_meth) {
|
||||
arg0 = PyStackRef_AsPyObjectBorrow(maybe_self);
|
||||
}
|
||||
else if (oparg) {
|
||||
arg0 = PyStackRef_AsPyObjectBorrow(args[0]);
|
||||
}
|
||||
else {
|
||||
arg0 = &_PyInstrumentation_MISSING;
|
||||
}
|
||||
int err = _Py_call_instrumentation_2args(
|
||||
tstate, PY_MONITORING_EVENT_CALL,
|
||||
frame, this_instr, function, arg0
|
||||
);
|
||||
ERROR_IF(err, error);
|
||||
}
|
||||
|
||||
macro(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC;
|
||||
macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC;
|
||||
|
||||
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue