mirror of
https://github.com/python/cpython.git
synced 2025-08-23 18:24:46 +00:00
gh-104584: Move super-instruction special-casing to generator (#106500)
Instead of special-casing specific instructions, we add a few more special values to the 'size' field of expansions, so in the future we can automatically handle additional super-instructions in the generator.
This commit is contained in:
parent
363f4f99c5
commit
11038c56ad
3 changed files with 84 additions and 39 deletions
|
@ -411,44 +411,15 @@ translate_bytecode_to_trace(
|
|||
for (;;) {
|
||||
ADD_TO_TRACE(SAVE_IP, (int)(instr - (_Py_CODEUNIT *)code->co_code_adaptive));
|
||||
int opcode = instr->op.code;
|
||||
uint64_t operand = instr->op.arg;
|
||||
int oparg = instr->op.arg;
|
||||
int extras = 0;
|
||||
while (opcode == EXTENDED_ARG) {
|
||||
instr++;
|
||||
extras += 1;
|
||||
opcode = instr->op.code;
|
||||
operand = (operand << 8) | instr->op.arg;
|
||||
oparg = (oparg << 8) | instr->op.arg;
|
||||
}
|
||||
switch (opcode) {
|
||||
case LOAD_FAST_LOAD_FAST:
|
||||
case STORE_FAST_LOAD_FAST:
|
||||
case STORE_FAST_STORE_FAST:
|
||||
{
|
||||
// Reserve space for two uops (+ SAVE_IP + EXIT_TRACE)
|
||||
if (trace_length + 4 > max_length) {
|
||||
DPRINTF(1, "Ran out of space for LOAD_FAST_LOAD_FAST\n");
|
||||
goto done;
|
||||
}
|
||||
uint64_t oparg1 = operand >> 4;
|
||||
uint64_t oparg2 = operand & 15;
|
||||
switch (opcode) {
|
||||
case LOAD_FAST_LOAD_FAST:
|
||||
ADD_TO_TRACE(LOAD_FAST, oparg1);
|
||||
ADD_TO_TRACE(LOAD_FAST, oparg2);
|
||||
break;
|
||||
case STORE_FAST_LOAD_FAST:
|
||||
ADD_TO_TRACE(STORE_FAST, oparg1);
|
||||
ADD_TO_TRACE(LOAD_FAST, oparg2);
|
||||
break;
|
||||
case STORE_FAST_STORE_FAST:
|
||||
ADD_TO_TRACE(STORE_FAST, oparg1);
|
||||
ADD_TO_TRACE(STORE_FAST, oparg2);
|
||||
break;
|
||||
default:
|
||||
Py_FatalError("Missing case");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode];
|
||||
|
@ -462,9 +433,11 @@ translate_bytecode_to_trace(
|
|||
goto done;
|
||||
}
|
||||
for (int i = 0; i < nuops; i++) {
|
||||
uint64_t operand;
|
||||
int offset = expansion->uops[i].offset;
|
||||
switch (expansion->uops[i].size) {
|
||||
case 0:
|
||||
case OPARG_FULL:
|
||||
operand = oparg;
|
||||
if (extras && OPCODE_HAS_JUMP(opcode)) {
|
||||
if (opcode == JUMP_BACKWARD_NO_INTERRUPT) {
|
||||
operand -= extras;
|
||||
|
@ -475,19 +448,25 @@ translate_bytecode_to_trace(
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case OPARG_CACHE_1:
|
||||
operand = read_u16(&instr[offset].cache);
|
||||
break;
|
||||
case 2:
|
||||
case OPARG_CACHE_2:
|
||||
operand = read_u32(&instr[offset].cache);
|
||||
break;
|
||||
case 4:
|
||||
case OPARG_CACHE_4:
|
||||
operand = read_u64(&instr[offset].cache);
|
||||
break;
|
||||
case OPARG_TOP: // First half of super-instr
|
||||
operand = oparg >> 4;
|
||||
break;
|
||||
case OPARG_BOTTOM: // Second half of super-instr
|
||||
operand = oparg & 0xF;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"opcode=%d, operand=%" PRIu64 "; nuops=%d, i=%d; size=%d, offset=%d\n",
|
||||
opcode, operand, nuops, i,
|
||||
"opcode=%d, oparg=%d; nuops=%d, i=%d; size=%d, offset=%d\n",
|
||||
opcode, oparg, nuops, i,
|
||||
expansion->uops[i].size,
|
||||
expansion->uops[i].offset);
|
||||
Py_FatalError("garbled expansion");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue