Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Include/internal/pycore_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ extern void _PyLineTable_InitAddressRange(
extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range);
extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);

/** API for executors */
extern void _PyCode_Clear_Executors(PyCodeObject *code);

#define ENABLE_SPECIALIZATION 1

/* Specialization functions */
Expand Down
4 changes: 4 additions & 0 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,10 @@ clear_executors(PyCodeObject *co)
co->co_executors = NULL;
}

void _PyCode_Clear_Executors(PyCodeObject *code) {
clear_executors(code);
}

static void
deopt_code(PyCodeObject *code, _Py_CODEUNIT *instructions)
{
Expand Down
52 changes: 20 additions & 32 deletions Python/instrumentation.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "opcode_ids.h"

#include "pycore_call.h"
#include "pycore_code.h" // _PyCode_Clear_Executors()
#include "pycore_frame.h"
#include "pycore_interp.h"
#include "pycore_long.h"
Expand Down Expand Up @@ -566,13 +567,7 @@ de_instrument(PyCodeObject *code, int i, int event)
_Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
uint8_t *opcode_ptr = &instr->op.code;
int opcode = *opcode_ptr;
if (opcode == ENTER_EXECUTOR) {
int oparg = instr->op.arg;
_PyExecutorObject *exec = code->co_executors->executors[oparg];
opcode_ptr = &exec->vm_data.opcode;
opcode = *opcode_ptr;
assert(opcode != ENTER_EXECUTOR);
}
assert(opcode != ENTER_EXECUTOR);
if (opcode == INSTRUMENTED_LINE) {
opcode_ptr = &code->_co_monitoring->lines[i].original_opcode;
opcode = *opcode_ptr;
Expand Down Expand Up @@ -717,22 +712,7 @@ remove_tools(PyCodeObject * code, int offset, int event, int tools)
assert(event != PY_MONITORING_EVENT_LINE);
assert(event != PY_MONITORING_EVENT_INSTRUCTION);
assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event));
#ifndef NDEBUG
_Py_CODEUNIT co_instr = _PyCode_CODE(code)[offset];
uint8_t opcode = co_instr.op.code;
uint8_t oparg = co_instr.op.arg;
if (opcode == ENTER_EXECUTOR) {
_PyExecutorObject *exec = code->co_executors->executors[oparg];
assert(exec->vm_data.opcode != ENTER_EXECUTOR);
opcode = _PyOpcode_Deopt[exec->vm_data.opcode];
opcode = exec->vm_data.oparg;
}
else {
opcode = _Py_GetBaseOpcode(code, offset);
}
assert(opcode != ENTER_EXECUTOR);
assert(opcode_has_event(opcode));
#endif
assert(opcode_has_event(_Py_GetBaseOpcode(code, offset)));
_PyCoMonitoringData *monitoring = code->_co_monitoring;
if (monitoring && monitoring->tools) {
monitoring->tools[offset] &= ~tools;
Expand Down Expand Up @@ -1303,27 +1283,21 @@ initialize_tools(PyCodeObject *code)
for (int i = 0; i < code_len; i++) {
_Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
int opcode = instr->op.code;
int oparg = instr->op.arg;
if (opcode == ENTER_EXECUTOR) {
_PyExecutorObject *exec = code->co_executors->executors[oparg];
opcode = exec->vm_data.opcode;
oparg = exec->vm_data.oparg;
}
else if (opcode == INSTRUMENTED_LINE) {
if (opcode == INSTRUMENTED_LINE) {
opcode = code->_co_monitoring->lines[i].original_opcode;
}
assert(opcode != ENTER_EXECUTOR);
bool instrumented = is_instrumented(opcode);
if (instrumented) {
opcode = DE_INSTRUMENT[opcode];
assert(opcode != 0);
}
assert(opcode != ENTER_EXECUTOR);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was added to test #107265 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the test could reproduce what you did in that comment?

opcode = _PyOpcode_Deopt[opcode];
if (opcode_has_event(opcode)) {
if (instrumented) {
int8_t event;
if (opcode == RESUME) {
event = oparg != 0;
event = instr->op.arg != 0;
}
else {
event = EVENT_FOR_OPCODE[opcode];
Expand Down Expand Up @@ -1577,6 +1551,20 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp)
return 0;
}
int code_len = (int)Py_SIZE(code);
if (code->co_executors != NULL && code->co_executors->size > 0 ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address by @markshannon's comment
: #108482 (comment)

for (int i = 0; i < code_len; i += _PyInstruction_GetLength(code, i)) {
_Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
uint8_t opcode = instr->op.code;
uint8_t oparg = instr->op.arg;
if (opcode == ENTER_EXECUTOR) {
_PyExecutorObject *exec = code->co_executors->executors[oparg];
assert(exec->vm_data.opcode != ENTER_EXECUTOR);
instr->op.code = _PyOpcode_Deopt[exec->vm_data.opcode];
instr->op.arg = exec->vm_data.oparg;
}
}
_PyCode_Clear_Executors(code);
}
if (update_instrumentation_data(code, interp)) {
return -1;
}
Expand Down