summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-08-13 13:22:57 (GMT)
committerGitHub <noreply@github.com>2024-08-13 13:22:57 (GMT)
commit7a65439b93d6ee4d4e32757b55909b882f9a2056 (patch)
tree0df6d926c920125cf98e02ab7d8c0612565b055e /Python
parentfe23f8ed970425828de20fb48750fa89da914886 (diff)
downloadcpython-7a65439b93d6ee4d4e32757b55909b882f9a2056.zip
cpython-7a65439b93d6ee4d4e32757b55909b882f9a2056.tar.gz
cpython-7a65439b93d6ee4d4e32757b55909b882f9a2056.tar.bz2
GH-122390: Replace `_Py_GetbaseOpcode` with `_Py_GetBaseCodeUnit` (GH-122942)
Diffstat (limited to 'Python')
-rw-r--r--Python/instrumentation.c69
-rw-r--r--Python/opcode_targets.h4
-rw-r--r--Python/optimizer.c19
-rw-r--r--Python/specialize.c6
4 files changed, 52 insertions, 46 deletions
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index 3481b5d..5e51a9c 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -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;
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 6b5f231..db92b02 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -65,7 +65,6 @@ static void *opcode_targets[256] = {
&&TARGET_DELETE_NAME,
&&TARGET_DICT_MERGE,
&&TARGET_DICT_UPDATE,
- &&TARGET_ENTER_EXECUTOR,
&&TARGET_EXTENDED_ARG,
&&TARGET_FOR_ITER,
&&TARGET_GET_AWAITABLE,
@@ -148,6 +147,7 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
+ &&_unknown_opcode,
&&TARGET_RESUME,
&&TARGET_BINARY_OP_ADD_FLOAT,
&&TARGET_BINARY_OP_ADD_INT,
@@ -254,5 +254,5 @@ static void *opcode_targets[256] = {
&&TARGET_INSTRUMENTED_YIELD_VALUE,
&&TARGET_INSTRUMENTED_CALL,
&&TARGET_INSTRUMENTED_LINE,
- &&_unknown_opcode,
+ &&TARGET_ENTER_EXECUTOR,
};
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 1758329..dbd5467 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -22,20 +22,6 @@
#define MAX_EXECUTORS_SIZE 256
-#ifdef Py_DEBUG
-static int
-base_opcode(PyCodeObject *code, int offset)
-{
- int opcode = _Py_GetBaseOpcode(code, offset);
- if (opcode == ENTER_EXECUTOR) {
- int oparg = _PyCode_CODE(code)[offset].op.arg;
- _PyExecutorObject *ex = code->co_executors->executors[oparg];
- return ex->vm_data.opcode;
- }
- return opcode;
-}
-#endif
-
static bool
has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr)
{
@@ -771,9 +757,8 @@ translate_bytecode_to_trace(
{
uint32_t next_inst = target + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + (oparg > 255);
uint32_t jump_target = next_inst + oparg;
- assert(base_opcode(code, jump_target) == END_FOR ||
- base_opcode(code, jump_target) == INSTRUMENTED_END_FOR);
- assert(base_opcode(code, jump_target+1) == POP_TOP);
+ assert(_Py_GetBaseCodeUnit(code, jump_target).op.code == END_FOR);
+ assert(_Py_GetBaseCodeUnit(code, jump_target+1).op.code == POP_TOP);
}
#endif
break;
diff --git a/Python/specialize.c b/Python/specialize.c
index c354a90..4a22738 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -428,9 +428,9 @@ _PyCode_Quicken(PyCodeObject *code)
#if ENABLE_SPECIALIZATION
int opcode = 0;
_Py_CODEUNIT *instructions = _PyCode_CODE(code);
- for (int i = 0; i < Py_SIZE(code); i++) {
- opcode = _Py_GetBaseOpcode(code, i);
- assert(opcode < MIN_INSTRUMENTED_OPCODE);
+ /* The last code unit cannot have a cache, so we don't need to check it */
+ for (int i = 0; i < Py_SIZE(code)-1; i++) {
+ opcode = instructions[i].op.code;
int caches = _PyOpcode_Caches[opcode];
if (caches) {
// The initial value depends on the opcode