mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
GH-122390: Replace _Py_GetbaseOpcode
with _Py_GetBaseCodeUnit
(GH-122942)
This commit is contained in:
parent
fe23f8ed97
commit
7a65439b93
16 changed files with 299 additions and 326 deletions
|
@ -165,6 +165,7 @@ is_instrumented(int opcode)
|
|||
{
|
||||
assert(opcode != 0);
|
||||
assert(opcode != RESERVED);
|
||||
assert(opcode != ENTER_EXECUTOR);
|
||||
return opcode >= MIN_INSTRUMENTED_OPCODE;
|
||||
}
|
||||
|
||||
|
@ -330,13 +331,12 @@ _PyInstruction_GetLength(PyCodeObject *code, int offset)
|
|||
opcode = _PyOpcode_Deopt[opcode];
|
||||
}
|
||||
assert(opcode != 0);
|
||||
assert(!is_instrumented(opcode));
|
||||
if (opcode == ENTER_EXECUTOR) {
|
||||
int exec_index = _PyCode_CODE(code)[offset].op.arg;
|
||||
_PyExecutorObject *exec = code->co_executors->executors[exec_index];
|
||||
opcode = _PyOpcode_Deopt[exec->vm_data.opcode];
|
||||
|
||||
}
|
||||
assert(!is_instrumented(opcode));
|
||||
assert(opcode != ENTER_EXECUTOR);
|
||||
assert(opcode == _PyOpcode_Deopt[opcode]);
|
||||
return 1 + _PyOpcode_Caches[opcode];
|
||||
|
@ -507,7 +507,7 @@ sanity_check_instrumentation(PyCodeObject *code)
|
|||
for (int i = 0; i < code_len;) {
|
||||
_Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
|
||||
int opcode = instr->op.code;
|
||||
int base_opcode = _Py_GetBaseOpcode(code, i);
|
||||
int base_opcode = _Py_GetBaseCodeUnit(code, offset).op.code;
|
||||
CHECK(valid_opcode(opcode));
|
||||
CHECK(valid_opcode(base_opcode));
|
||||
if (opcode == INSTRUMENTED_INSTRUCTION) {
|
||||
|
@ -579,10 +579,26 @@ sanity_check_instrumentation(PyCodeObject *code)
|
|||
|
||||
#endif
|
||||
|
||||
/* Get the underlying opcode, stripping instrumentation */
|
||||
int _Py_GetBaseOpcode(PyCodeObject *code, int i)
|
||||
/* Get the underlying code unit, stripping instrumentation and ENTER_EXECUTOR */
|
||||
_Py_CODEUNIT
|
||||
_Py_GetBaseCodeUnit(PyCodeObject *code, int i)
|
||||
{
|
||||
int opcode = _PyCode_CODE(code)[i].op.code;
|
||||
_Py_CODEUNIT inst = _PyCode_CODE(code)[i];
|
||||
int opcode = inst.op.code;
|
||||
if (opcode < MIN_INSTRUMENTED_OPCODE) {
|
||||
inst.op.code = _PyOpcode_Deopt[opcode];
|
||||
assert(inst.op.code <= RESUME);
|
||||
return inst;
|
||||
}
|
||||
if (opcode == ENTER_EXECUTOR) {
|
||||
_PyExecutorObject *exec = code->co_executors->executors[inst.op.arg];
|
||||
opcode = _PyOpcode_Deopt[exec->vm_data.opcode];
|
||||
inst.op.code = opcode;
|
||||
assert(opcode <= RESUME);
|
||||
inst.op.arg = exec->vm_data.oparg;
|
||||
assert(inst.op.code <= RESUME);
|
||||
return inst;
|
||||
}
|
||||
if (opcode == INSTRUMENTED_LINE) {
|
||||
opcode = code->_co_monitoring->lines[i].original_opcode;
|
||||
}
|
||||
|
@ -593,9 +609,13 @@ int _Py_GetBaseOpcode(PyCodeObject *code, int i)
|
|||
CHECK(opcode != INSTRUMENTED_LINE);
|
||||
int deinstrumented = DE_INSTRUMENT[opcode];
|
||||
if (deinstrumented) {
|
||||
return deinstrumented;
|
||||
inst.op.code = deinstrumented;
|
||||
}
|
||||
return _PyOpcode_Deopt[opcode];
|
||||
else {
|
||||
inst.op.code = _PyOpcode_Deopt[opcode];
|
||||
}
|
||||
assert(inst.op.code < MIN_SPECIALIZED_OPCODE);
|
||||
return inst;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -756,7 +776,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));
|
||||
assert(opcode_has_event(_Py_GetBaseOpcode(code, offset)));
|
||||
assert(opcode_has_event(_Py_GetBaseCodeUnit(code, offset).op.code));
|
||||
_PyCoMonitoringData *monitoring = code->_co_monitoring;
|
||||
if (monitoring && monitoring->tools) {
|
||||
monitoring->tools[offset] &= ~tools;
|
||||
|
@ -1479,7 +1499,7 @@ initialize_lines(PyCodeObject *code)
|
|||
}
|
||||
int current_line = -1;
|
||||
for (int i = code->_co_firsttraceable; i < code_len; ) {
|
||||
int opcode = _Py_GetBaseOpcode(code, i);
|
||||
int opcode = _Py_GetBaseCodeUnit(code, i).op.code;
|
||||
int line = _PyCode_CheckLineNumber(i*(int)sizeof(_Py_CODEUNIT), &range);
|
||||
line_data[i].line_delta = compute_line_delta(code, i, line);
|
||||
int length = _PyInstruction_GetLength(code, i);
|
||||
|
@ -1522,14 +1542,16 @@ initialize_lines(PyCodeObject *code)
|
|||
i += length;
|
||||
}
|
||||
for (int i = code->_co_firsttraceable; i < code_len; ) {
|
||||
int opcode = _Py_GetBaseOpcode(code, i);
|
||||
_Py_CODEUNIT inst =_Py_GetBaseCodeUnit(code, i);
|
||||
int opcode = inst.op.code;
|
||||
int oparg = 0;
|
||||
while (opcode == EXTENDED_ARG) {
|
||||
oparg = (oparg << 8) | _PyCode_CODE(code)[i].op.arg;
|
||||
oparg = (oparg << 8) | inst.op.arg;
|
||||
i++;
|
||||
opcode = _Py_GetBaseOpcode(code, i);
|
||||
inst =_Py_GetBaseCodeUnit(code, i);
|
||||
opcode = inst.op.code;
|
||||
}
|
||||
oparg = (oparg << 8) | _PyCode_CODE(code)[i].op.arg;
|
||||
oparg = (oparg << 8) | inst.op.arg;
|
||||
i += _PyInstruction_GetLength(code, i);
|
||||
int target = -1;
|
||||
switch (opcode) {
|
||||
|
@ -1560,7 +1582,7 @@ initialize_lines(PyCodeObject *code)
|
|||
}
|
||||
assert(target >= 0);
|
||||
if (line_data[target].line_delta != NO_LINE) {
|
||||
line_data[target].original_opcode = _Py_GetBaseOpcode(code, target);
|
||||
line_data[target].original_opcode = _Py_GetBaseCodeUnit(code, target).op.code;
|
||||
if (line_data[target].line_delta == COMPUTED_LINE_LINENO_CHANGE) {
|
||||
// If the line is a jump target, we are not sure if the line
|
||||
// number changes, so we set it to COMPUTED_LINE.
|
||||
|
@ -1582,7 +1604,7 @@ initialize_lines(PyCodeObject *code)
|
|||
assert(handler >= 0 && handler < code_len);
|
||||
int depth_and_lasti;
|
||||
scan = parse_varint(scan, &depth_and_lasti);
|
||||
int original_opcode = _Py_GetBaseOpcode(code, handler);
|
||||
int original_opcode = _Py_GetBaseCodeUnit(code, handler).op.code;
|
||||
/* Skip if not the start of a line.
|
||||
* END_ASYNC_FOR is a bit special as it marks the end of
|
||||
* an `async for` loop, which should not generate its own
|
||||
|
@ -1740,15 +1762,14 @@ force_instrument_lock_held(PyCodeObject *code, PyInterpreterState *interp)
|
|||
}
|
||||
/* Insert instrumentation */
|
||||
for (int i = code->_co_firsttraceable; i < code_len; i+= _PyInstruction_GetLength(code, i)) {
|
||||
_Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
|
||||
CHECK(instr->op.code != 0);
|
||||
assert(instr->op.code != ENTER_EXECUTOR);
|
||||
int base_opcode = _Py_GetBaseOpcode(code, i);
|
||||
assert(base_opcode != ENTER_EXECUTOR);
|
||||
assert(_PyCode_CODE(code)[i].op.code != ENTER_EXECUTOR);
|
||||
_Py_CODEUNIT instr = _Py_GetBaseCodeUnit(code, i);
|
||||
CHECK(instr.op.code != 0);
|
||||
int base_opcode = instr.op.code;
|
||||
if (opcode_has_event(base_opcode)) {
|
||||
int8_t event;
|
||||
if (base_opcode == RESUME) {
|
||||
event = instr->op.arg > 0;
|
||||
event = instr.op.arg > 0;
|
||||
}
|
||||
else {
|
||||
event = EVENT_FOR_OPCODE[base_opcode];
|
||||
|
@ -1781,7 +1802,7 @@ force_instrument_lock_held(PyCodeObject *code, PyInterpreterState *interp)
|
|||
}
|
||||
if (removed_per_instruction_tools) {
|
||||
for (int i = code->_co_firsttraceable; i < code_len;) {
|
||||
int opcode = _Py_GetBaseOpcode(code, i);
|
||||
int opcode = _Py_GetBaseCodeUnit(code, i).op.code;
|
||||
if (opcode == RESUME || opcode == END_FOR) {
|
||||
i += _PyInstruction_GetLength(code, i);
|
||||
continue;
|
||||
|
@ -1808,7 +1829,7 @@ force_instrument_lock_held(PyCodeObject *code, PyInterpreterState *interp)
|
|||
}
|
||||
if (new_per_instruction_tools) {
|
||||
for (int i = code->_co_firsttraceable; i < code_len;) {
|
||||
int opcode = _Py_GetBaseOpcode(code, i);
|
||||
int opcode = _Py_GetBaseCodeUnit(code, i).op.code;
|
||||
if (opcode == RESUME || opcode == END_FOR) {
|
||||
i += _PyInstruction_GetLength(code, i);
|
||||
continue;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue