summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorCarl Meyer <carl@oddbird.net>2023-05-16 16:29:00 (GMT)
committerGitHub <noreply@github.com>2023-05-16 16:29:00 (GMT)
commitf40890b124a330b589c8093127be1274e15dbd7f (patch)
treea6a68ed80a4103ff60b33375c17e4fa1dc40bc6d /Python/bytecodes.c
parentfebcc6ccfb0726dab588e64b68d91abb37db1939 (diff)
downloadcpython-f40890b124a330b589c8093127be1274e15dbd7f.zip
cpython-f40890b124a330b589c8093127be1274e15dbd7f.tar.gz
cpython-f40890b124a330b589c8093127be1274e15dbd7f.tar.bz2
gh-103865: add monitoring support to LOAD_SUPER_ATTR (#103866)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 1b8820f..b38d37a 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -1582,6 +1582,14 @@ dummy_func(
PREDICT(JUMP_BACKWARD);
}
+ inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/9, unused, unused, unused -- unused if (oparg & 1), unused)) {
+ _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr;
+ // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
+ // don't want to specialize instrumented instructions
+ INCREMENT_ADAPTIVE_COUNTER(cache->counter);
+ GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
+ }
+
family(load_super_attr, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
LOAD_SUPER_ATTR,
LOAD_SUPER_ATTR_ATTR,
@@ -1602,10 +1610,34 @@ dummy_func(
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
#endif /* ENABLE_SPECIALIZATION */
+ if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
+ PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
+ int err = _Py_call_instrumentation_2args(
+ tstate, PY_MONITORING_EVENT_CALL,
+ frame, next_instr-1, global_super, arg);
+ ERROR_IF(err, error);
+ }
+
// we make no attempt to optimize here; specializations should
// handle any case whose performance we care about
PyObject *stack[] = {class, self};
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
+ if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
+ PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
+ if (super == NULL) {
+ _Py_call_instrumentation_exc2(
+ tstate, PY_MONITORING_EVENT_C_RAISE,
+ frame, next_instr-1, global_super, arg);
+ }
+ else {
+ int err = _Py_call_instrumentation_2args(
+ tstate, PY_MONITORING_EVENT_C_RETURN,
+ frame, next_instr-1, global_super, arg);
+ if (err < 0) {
+ Py_CLEAR(super);
+ }
+ }
+ }
DECREF_INPUTS();
ERROR_IF(super == NULL, error);
res = PyObject_GetAttr(super, name);