#define _ITER_NEXT_LIST_TIER_TWO 442
#define _ITER_NEXT_RANGE 443
#define _ITER_NEXT_TUPLE 444
-#define _JUMP_BACKWARD_NO_INTERRUPT 445
-#define _JUMP_TO_TOP 446
+#define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT
+#define _JUMP_TO_TOP 445
#define _LIST_APPEND LIST_APPEND
#define _LIST_EXTEND LIST_EXTEND
-#define _LOAD_ATTR 447
-#define _LOAD_ATTR_CLASS 448
+#define _LOAD_ATTR 446
+#define _LOAD_ATTR_CLASS 447
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#define _LOAD_ATTR_INSTANCE_VALUE 449
-#define _LOAD_ATTR_METHOD_LAZY_DICT 450
-#define _LOAD_ATTR_METHOD_NO_DICT 451
-#define _LOAD_ATTR_METHOD_WITH_VALUES 452
-#define _LOAD_ATTR_MODULE 453
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 454
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 455
-#define _LOAD_ATTR_PROPERTY_FRAME 456
-#define _LOAD_ATTR_SLOT 457
-#define _LOAD_ATTR_WITH_HINT 458
+#define _LOAD_ATTR_INSTANCE_VALUE 448
+#define _LOAD_ATTR_METHOD_LAZY_DICT 449
+#define _LOAD_ATTR_METHOD_NO_DICT 450
+#define _LOAD_ATTR_METHOD_WITH_VALUES 451
+#define _LOAD_ATTR_MODULE 452
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 453
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 454
+#define _LOAD_ATTR_PROPERTY_FRAME 455
+#define _LOAD_ATTR_SLOT 456
+#define _LOAD_ATTR_WITH_HINT 457
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
-#define _LOAD_BYTECODE 459
+#define _LOAD_BYTECODE 458
#define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
#define _LOAD_CONST LOAD_CONST
-#define _LOAD_CONST_INLINE 460
-#define _LOAD_CONST_INLINE_BORROW 461
-#define _LOAD_CONST_UNDER_INLINE 462
-#define _LOAD_CONST_UNDER_INLINE_BORROW 463
+#define _LOAD_CONST_INLINE 459
+#define _LOAD_CONST_INLINE_BORROW 460
+#define _LOAD_CONST_UNDER_INLINE 461
+#define _LOAD_CONST_UNDER_INLINE_BORROW 462
#define _LOAD_DEREF LOAD_DEREF
-#define _LOAD_FAST 464
-#define _LOAD_FAST_0 465
-#define _LOAD_FAST_1 466
-#define _LOAD_FAST_2 467
-#define _LOAD_FAST_3 468
-#define _LOAD_FAST_4 469
-#define _LOAD_FAST_5 470
-#define _LOAD_FAST_6 471
-#define _LOAD_FAST_7 472
+#define _LOAD_FAST 463
+#define _LOAD_FAST_0 464
+#define _LOAD_FAST_1 465
+#define _LOAD_FAST_2 466
+#define _LOAD_FAST_3 467
+#define _LOAD_FAST_4 468
+#define _LOAD_FAST_5 469
+#define _LOAD_FAST_6 470
+#define _LOAD_FAST_7 471
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
-#define _LOAD_FAST_BORROW 473
-#define _LOAD_FAST_BORROW_0 474
-#define _LOAD_FAST_BORROW_1 475
-#define _LOAD_FAST_BORROW_2 476
-#define _LOAD_FAST_BORROW_3 477
-#define _LOAD_FAST_BORROW_4 478
-#define _LOAD_FAST_BORROW_5 479
-#define _LOAD_FAST_BORROW_6 480
-#define _LOAD_FAST_BORROW_7 481
+#define _LOAD_FAST_BORROW 472
+#define _LOAD_FAST_BORROW_0 473
+#define _LOAD_FAST_BORROW_1 474
+#define _LOAD_FAST_BORROW_2 475
+#define _LOAD_FAST_BORROW_3 476
+#define _LOAD_FAST_BORROW_4 477
+#define _LOAD_FAST_BORROW_5 478
+#define _LOAD_FAST_BORROW_6 479
+#define _LOAD_FAST_BORROW_7 480
#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW LOAD_FAST_BORROW_LOAD_FAST_BORROW
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK
#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST
#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
-#define _LOAD_GLOBAL 482
-#define _LOAD_GLOBAL_BUILTINS 483
-#define _LOAD_GLOBAL_MODULE 484
+#define _LOAD_GLOBAL 481
+#define _LOAD_GLOBAL_BUILTINS 482
+#define _LOAD_GLOBAL_MODULE 483
#define _LOAD_LOCALS LOAD_LOCALS
#define _LOAD_NAME LOAD_NAME
-#define _LOAD_SMALL_INT 485
-#define _LOAD_SMALL_INT_0 486
-#define _LOAD_SMALL_INT_1 487
-#define _LOAD_SMALL_INT_2 488
-#define _LOAD_SMALL_INT_3 489
-#define _LOAD_SPECIAL 490
+#define _LOAD_SMALL_INT 484
+#define _LOAD_SMALL_INT_0 485
+#define _LOAD_SMALL_INT_1 486
+#define _LOAD_SMALL_INT_2 487
+#define _LOAD_SMALL_INT_3 488
+#define _LOAD_SPECIAL 489
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _MAKE_CALLARGS_A_TUPLE 491
+#define _MAKE_CALLARGS_A_TUPLE 490
#define _MAKE_CELL MAKE_CELL
#define _MAKE_FUNCTION MAKE_FUNCTION
-#define _MAKE_WARM 492
+#define _MAKE_WARM 491
#define _MAP_ADD MAP_ADD
#define _MATCH_CLASS MATCH_CLASS
#define _MATCH_KEYS MATCH_KEYS
#define _MATCH_MAPPING MATCH_MAPPING
#define _MATCH_SEQUENCE MATCH_SEQUENCE
-#define _MAYBE_EXPAND_METHOD 493
-#define _MAYBE_EXPAND_METHOD_KW 494
-#define _MONITOR_CALL 495
-#define _MONITOR_CALL_KW 496
-#define _MONITOR_JUMP_BACKWARD 497
-#define _MONITOR_RESUME 498
+#define _MAYBE_EXPAND_METHOD 492
+#define _MAYBE_EXPAND_METHOD_KW 493
+#define _MONITOR_CALL 494
+#define _MONITOR_CALL_KW 495
+#define _MONITOR_JUMP_BACKWARD 496
+#define _MONITOR_RESUME 497
#define _NOP NOP
-#define _POP_CALL 499
-#define _POP_CALL_LOAD_CONST_INLINE_BORROW 500
-#define _POP_CALL_ONE 501
-#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 502
-#define _POP_CALL_TWO 503
-#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 504
+#define _POP_CALL 498
+#define _POP_CALL_LOAD_CONST_INLINE_BORROW 499
+#define _POP_CALL_ONE 500
+#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 501
+#define _POP_CALL_TWO 502
+#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 503
#define _POP_EXCEPT POP_EXCEPT
#define _POP_ITER POP_ITER
-#define _POP_JUMP_IF_FALSE 505
-#define _POP_JUMP_IF_TRUE 506
+#define _POP_JUMP_IF_FALSE 504
+#define _POP_JUMP_IF_TRUE 505
#define _POP_TOP POP_TOP
-#define _POP_TOP_FLOAT 507
-#define _POP_TOP_INT 508
-#define _POP_TOP_LOAD_CONST_INLINE 509
-#define _POP_TOP_LOAD_CONST_INLINE_BORROW 510
-#define _POP_TOP_NOP 511
-#define _POP_TOP_UNICODE 512
-#define _POP_TWO 513
-#define _POP_TWO_LOAD_CONST_INLINE_BORROW 514
+#define _POP_TOP_FLOAT 506
+#define _POP_TOP_INT 507
+#define _POP_TOP_LOAD_CONST_INLINE 508
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW 509
+#define _POP_TOP_NOP 510
+#define _POP_TOP_UNICODE 511
+#define _POP_TWO 512
+#define _POP_TWO_LOAD_CONST_INLINE_BORROW 513
#define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _PUSH_FRAME 515
+#define _PUSH_FRAME 514
#define _PUSH_NULL PUSH_NULL
-#define _PUSH_NULL_CONDITIONAL 516
-#define _PY_FRAME_GENERAL 517
-#define _PY_FRAME_KW 518
-#define _QUICKEN_RESUME 519
-#define _REPLACE_WITH_TRUE 520
+#define _PUSH_NULL_CONDITIONAL 515
+#define _PY_FRAME_GENERAL 516
+#define _PY_FRAME_KW 517
+#define _QUICKEN_RESUME 518
+#define _REPLACE_WITH_TRUE 519
#define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR
#define _RETURN_VALUE RETURN_VALUE
-#define _SAVE_RETURN_OFFSET 521
-#define _SEND 522
-#define _SEND_GEN_FRAME 523
+#define _SAVE_RETURN_OFFSET 520
+#define _SEND 521
+#define _SEND_GEN_FRAME 522
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
#define _SET_ADD SET_ADD
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
#define _SET_UPDATE SET_UPDATE
-#define _START_EXECUTOR 524
-#define _STORE_ATTR 525
-#define _STORE_ATTR_INSTANCE_VALUE 526
-#define _STORE_ATTR_SLOT 527
-#define _STORE_ATTR_WITH_HINT 528
+#define _START_EXECUTOR 523
+#define _STORE_ATTR 524
+#define _STORE_ATTR_INSTANCE_VALUE 525
+#define _STORE_ATTR_SLOT 526
+#define _STORE_ATTR_WITH_HINT 527
#define _STORE_DEREF STORE_DEREF
-#define _STORE_FAST 529
-#define _STORE_FAST_0 530
-#define _STORE_FAST_1 531
-#define _STORE_FAST_2 532
-#define _STORE_FAST_3 533
-#define _STORE_FAST_4 534
-#define _STORE_FAST_5 535
-#define _STORE_FAST_6 536
-#define _STORE_FAST_7 537
+#define _STORE_FAST 528
+#define _STORE_FAST_0 529
+#define _STORE_FAST_1 530
+#define _STORE_FAST_2 531
+#define _STORE_FAST_3 532
+#define _STORE_FAST_4 533
+#define _STORE_FAST_5 534
+#define _STORE_FAST_6 535
+#define _STORE_FAST_7 536
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
#define _STORE_GLOBAL STORE_GLOBAL
#define _STORE_NAME STORE_NAME
-#define _STORE_SLICE 538
-#define _STORE_SUBSCR 539
-#define _STORE_SUBSCR_DICT 540
-#define _STORE_SUBSCR_LIST_INT 541
-#define _SWAP 542
-#define _SWAP_2 543
-#define _SWAP_3 544
-#define _TIER2_RESUME_CHECK 545
-#define _TO_BOOL 546
+#define _STORE_SLICE 537
+#define _STORE_SUBSCR 538
+#define _STORE_SUBSCR_DICT 539
+#define _STORE_SUBSCR_LIST_INT 540
+#define _SWAP 541
+#define _SWAP_2 542
+#define _SWAP_3 543
+#define _TIER2_RESUME_CHECK 544
+#define _TO_BOOL 545
#define _TO_BOOL_BOOL TO_BOOL_BOOL
#define _TO_BOOL_INT TO_BOOL_INT
-#define _TO_BOOL_LIST 547
+#define _TO_BOOL_LIST 546
#define _TO_BOOL_NONE TO_BOOL_NONE
-#define _TO_BOOL_STR 548
+#define _TO_BOOL_STR 547
#define _UNARY_INVERT UNARY_INVERT
#define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT
#define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 549
-#define _UNPACK_SEQUENCE_LIST 550
-#define _UNPACK_SEQUENCE_TUPLE 551
-#define _UNPACK_SEQUENCE_TWO_TUPLE 552
+#define _UNPACK_SEQUENCE 548
+#define _UNPACK_SEQUENCE_LIST 549
+#define _UNPACK_SEQUENCE_TUPLE 550
+#define _UNPACK_SEQUENCE_TWO_TUPLE 551
#define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _YIELD_VALUE YIELD_VALUE
-#define MAX_UOP_ID 552
+#define MAX_UOP_ID 551
#ifdef __cplusplus
}
unused/1 +
_SPECIALIZE_JUMP_BACKWARD +
_CHECK_PERIODIC +
- _JUMP_BACKWARD_NO_INTERRUPT;
+ JUMP_BACKWARD_NO_INTERRUPT;
macro(JUMP_BACKWARD_NO_JIT) =
unused/1 +
_CHECK_PERIODIC +
- _JUMP_BACKWARD_NO_INTERRUPT;
+ JUMP_BACKWARD_NO_INTERRUPT;
macro(JUMP_BACKWARD_JIT) =
unused/1 +
_CHECK_PERIODIC +
- _JUMP_BACKWARD_NO_INTERRUPT +
+ JUMP_BACKWARD_NO_INTERRUPT +
_JIT;
pseudo(JUMP, (--)) = {
macro(POP_JUMP_IF_NOT_NONE) = unused/1 + _IS_NONE + _POP_JUMP_IF_FALSE;
- // This actually has 1 cache entry, but for some reason it's not factored in the oparg.
- macro(JUMP_BACKWARD_NO_INTERRUPT) = _JUMP_BACKWARD_NO_INTERRUPT;
-
- op(_JUMP_BACKWARD_NO_INTERRUPT, (--)) {
+ inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) {
/* This bytecode is used in the `yield from` or `await` loop.
* If there is an interrupt, we want it handled in the innermost
* generator or coroutine, so we deliberately do not check it here.
tier2 op(_COLD_EXIT, ( -- )) {
_PyExitData *exit = tstate->jit_exit;
assert(exit != NULL);
- _Py_CODEUNIT *target = (_PyFrame_GetBytecode(frame) + exit->target);
+ _Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
_Py_BackoffCounter temperature = exit->temperature;
+ if (!backoff_counter_triggers(temperature)) {
+ exit->temperature = advance_backoff_counter(temperature);
+ GOTO_TIER_ONE(target, 0);
+ }
+ _PyExecutorObject *executor;
if (target->op.code == ENTER_EXECUTOR) {
PyCodeObject *code = _PyFrame_GetCode(frame);
- _PyExecutorObject *executor = code->co_executors->executors[target->op.arg];
+ executor = code->co_executors->executors[target->op.arg];
Py_INCREF(executor);
- assert(tstate->jit_exit == exit);
- exit->executor = executor;
- TIER2_TO_TIER2(exit->executor);
}
else {
- if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
- GOTO_TIER_ONE(target, 0);
- }
- if (!backoff_counter_triggers(temperature)) {
- exit->temperature = advance_backoff_counter(temperature);
- GOTO_TIER_ONE(target, 0);
- }
- exit->temperature = initial_temperature_backoff_counter();
_PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit);
assert(tstate->current_executor == (PyObject *)previous_executor);
int chain_depth = previous_executor->vm_data.chain_depth + 1;
_PyJIT_InitializeTracing(tstate, frame, target, STACK_LEVEL(), chain_depth, exit);
+ exit->temperature = initial_temperature_backoff_counter();
GOTO_TIER_ONE(target, 1);
}
+ assert(tstate->jit_exit == exit);
+ exit->executor = executor;
+ TIER2_TO_TIER2(exit->executor);
}
tier2 op(_GUARD_IP, (ip/4 --)) {
GOTO_TIER_ONE(target, 0);
}
exit->temperature = initial_temperature_backoff_counter();
- _PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit);
- assert(tstate->current_executor == (PyObject *)previous_executor);
_PyJIT_InitializeTracing(tstate, frame, target, STACK_LEVEL(), 0, NULL);
GOTO_TIER_ONE(target, 1);
}
// make progress in order to avoid infinite loops or excessively-long
// side-exit chains. We can only insert the executor into the bytecode if
// this is true, since a deopt won't infinitely re-enter the executor:
- bool progress_needed = (chain_depth % MAX_CHAIN_DEPTH) == 0;
+ chain_depth %= MAX_CHAIN_DEPTH;
+ bool progress_needed = chain_depth == 0;
PyCodeObject *code = (PyCodeObject *)tstate->interp->jit_tracer_initial_code;
_Py_CODEUNIT *start = tstate->interp->jit_tracer_initial_instr;
// A recursive trace might've cleared the values. In that case, bail.
int oparg,
int jump_taken)
{
- if (Py_IsNone((PyObject *)func)) {
- func = NULL;
+ if (PyStackRef_IsNull(frame->f_funcobj)) {
+ goto unsupported;
}
int is_first_instr = tstate->interp->jit_tracer_initial_instr == this_instr;
(frame != tstate->interp->jit_tracer_current_frame && !needs_guard_ip) ||
// TODO handle extended args.
oparg > 255 || opcode == EXTENDED_ARG ||
+ // TODO handle BINARY_OP_INPLACE_ADD_UNICODE
+ opcode == BINARY_OP_INPLACE_ADD_UNICODE ||
+ // TODO (gh-140277): The constituent uops are invalid.
+ opcode == BINARY_OP_SUBSCR_GETITEM ||
+ // Exception stuff, could be handled in the future maybe?
opcode == WITH_EXCEPT_START || opcode == RERAISE || opcode == CLEANUP_THROW || opcode == PUSH_EXC_INFO ||
frame->owner >= FRAME_OWNED_BY_INTERPRETER
) {
{
// Rewind to previous instruction and replace with _EXIT_TRACE.
_PyUOpInstruction *curr = &trace[trace_length-1];
- while (curr->opcode != _SET_IP && trace_length > 1) {
+ while (curr->opcode != _SET_IP && trace_length > 2) {
trace_length--;
curr = &trace[trace_length-1];
}
- assert(curr->opcode == _SET_IP || trace_length == 1);
- curr->opcode = _EXIT_TRACE;
+ assert(curr->opcode == _SET_IP || trace_length == 2);
+ if (curr->opcode == _SET_IP) {
+ int32_t old_target = (int32_t)uop_get_target(curr);
+ curr++;
+ trace_length++;
+ curr->opcode = _EXIT_TRACE;
+ curr->format = UOP_FORMAT_TARGET;
+ curr->target = old_target;
+ }
goto done;
}
}
return 1;
}
- if (opcode == JUMP_BACKWARD_NO_INTERRUPT) {
- return 1;
- }
-
if (opcode == JUMP_FORWARD) {
return 1;
}
// Loop back to the start
if (is_first_instr && tstate->interp->jit_tracer_code_curr_size > 2) {
- // Undo the last few instructions.
- trace_length = tstate->interp->jit_tracer_code_curr_size;
+ ADD_TO_TRACE(_CHECK_PERIODIC, 0, 0, target);
ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0, 0);
goto done;
}