aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Include/cpython/pystats.h1
-rw-r--r--Include/internal/pycore_optimizer.h3
-rw-r--r--Include/internal/pycore_uop_ids.h247
-rw-r--r--Include/internal/pycore_uop_metadata.h4
-rw-r--r--Lib/test/test_capi/test_opt.py1
-rw-r--r--Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst1
-rw-r--r--Python/bytecodes.c36
-rw-r--r--Python/executor_cases.c.h42
-rw-r--r--Python/optimizer.c18
-rw-r--r--Python/optimizer_analysis.c1
-rw-r--r--Python/optimizer_cases.c.h4
-rw-r--r--Python/specialize.c1
-rw-r--r--Tools/scripts/summarize_stats.py5
13 files changed, 138 insertions, 226 deletions
diff --git a/Include/cpython/pystats.h b/Include/cpython/pystats.h
index f52348e42b1..4421b4d6e91 100644
--- a/Include/cpython/pystats.h
+++ b/Include/cpython/pystats.h
@@ -129,6 +129,7 @@ typedef struct _optimization_stats {
uint64_t inner_loop;
uint64_t recursive_call;
uint64_t low_confidence;
+ uint64_t unknown_callee;
uint64_t executors_invalidated;
UOpStats opcode[PYSTATS_MAX_UOP_ID + 1];
uint64_t unsupported_opcode[256];
diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h
index 00fc4338b0a..25c3d3e5a22 100644
--- a/Include/internal/pycore_optimizer.h
+++ b/Include/internal/pycore_optimizer.h
@@ -289,8 +289,7 @@ static inline int is_terminator(const _PyUOpInstruction *uop)
int opcode = uop->opcode;
return (
opcode == _EXIT_TRACE ||
- opcode == _JUMP_TO_TOP ||
- opcode == _DYNAMIC_EXIT
+ opcode == _JUMP_TO_TOP
);
}
diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h
index ca40af55406..554e3439e0b 100644
--- a/Include/internal/pycore_uop_ids.h
+++ b/Include/internal/pycore_uop_ids.h
@@ -101,57 +101,56 @@ extern "C" {
#define _DO_CALL 358
#define _DO_CALL_FUNCTION_EX 359
#define _DO_CALL_KW 360
-#define _DYNAMIC_EXIT 361
#define _END_FOR END_FOR
#define _END_SEND END_SEND
-#define _ERROR_POP_N 362
+#define _ERROR_POP_N 361
#define _EXIT_INIT_CHECK EXIT_INIT_CHECK
-#define _EXPAND_METHOD 363
-#define _EXPAND_METHOD_KW 364
-#define _FATAL_ERROR 365
+#define _EXPAND_METHOD 362
+#define _EXPAND_METHOD_KW 363
+#define _FATAL_ERROR 364
#define _FORMAT_SIMPLE FORMAT_SIMPLE
#define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
-#define _FOR_ITER 366
-#define _FOR_ITER_GEN_FRAME 367
-#define _FOR_ITER_TIER_TWO 368
+#define _FOR_ITER 365
+#define _FOR_ITER_GEN_FRAME 366
+#define _FOR_ITER_TIER_TWO 367
#define _GET_AITER GET_AITER
#define _GET_ANEXT GET_ANEXT
#define _GET_AWAITABLE GET_AWAITABLE
#define _GET_ITER GET_ITER
#define _GET_LEN GET_LEN
#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
-#define _GUARD_BINARY_OP_EXTEND 369
-#define _GUARD_BOTH_FLOAT 370
-#define _GUARD_BOTH_INT 371
-#define _GUARD_BOTH_UNICODE 372
-#define _GUARD_BUILTINS_VERSION_PUSH_KEYS 373
-#define _GUARD_DORV_NO_DICT 374
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 375
-#define _GUARD_GLOBALS_VERSION 376
-#define _GUARD_GLOBALS_VERSION_PUSH_KEYS 377
-#define _GUARD_IS_FALSE_POP 378
-#define _GUARD_IS_NONE_POP 379
-#define _GUARD_IS_NOT_NONE_POP 380
-#define _GUARD_IS_TRUE_POP 381
-#define _GUARD_KEYS_VERSION 382
-#define _GUARD_NOS_FLOAT 383
-#define _GUARD_NOS_INT 384
-#define _GUARD_NOT_EXHAUSTED_LIST 385
-#define _GUARD_NOT_EXHAUSTED_RANGE 386
-#define _GUARD_NOT_EXHAUSTED_TUPLE 387
-#define _GUARD_TOS_FLOAT 388
-#define _GUARD_TOS_INT 389
-#define _GUARD_TYPE_VERSION 390
-#define _GUARD_TYPE_VERSION_AND_LOCK 391
+#define _GUARD_BINARY_OP_EXTEND 368
+#define _GUARD_BOTH_FLOAT 369
+#define _GUARD_BOTH_INT 370
+#define _GUARD_BOTH_UNICODE 371
+#define _GUARD_BUILTINS_VERSION_PUSH_KEYS 372
+#define _GUARD_DORV_NO_DICT 373
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 374
+#define _GUARD_GLOBALS_VERSION 375
+#define _GUARD_GLOBALS_VERSION_PUSH_KEYS 376
+#define _GUARD_IS_FALSE_POP 377
+#define _GUARD_IS_NONE_POP 378
+#define _GUARD_IS_NOT_NONE_POP 379
+#define _GUARD_IS_TRUE_POP 380
+#define _GUARD_KEYS_VERSION 381
+#define _GUARD_NOS_FLOAT 382
+#define _GUARD_NOS_INT 383
+#define _GUARD_NOT_EXHAUSTED_LIST 384
+#define _GUARD_NOT_EXHAUSTED_RANGE 385
+#define _GUARD_NOT_EXHAUSTED_TUPLE 386
+#define _GUARD_TOS_FLOAT 387
+#define _GUARD_TOS_INT 388
+#define _GUARD_TYPE_VERSION 389
+#define _GUARD_TYPE_VERSION_AND_LOCK 390
#define _IMPORT_FROM IMPORT_FROM
#define _IMPORT_NAME IMPORT_NAME
-#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 392
-#define _INIT_CALL_PY_EXACT_ARGS 393
-#define _INIT_CALL_PY_EXACT_ARGS_0 394
-#define _INIT_CALL_PY_EXACT_ARGS_1 395
-#define _INIT_CALL_PY_EXACT_ARGS_2 396
-#define _INIT_CALL_PY_EXACT_ARGS_3 397
-#define _INIT_CALL_PY_EXACT_ARGS_4 398
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 391
+#define _INIT_CALL_PY_EXACT_ARGS 392
+#define _INIT_CALL_PY_EXACT_ARGS_0 393
+#define _INIT_CALL_PY_EXACT_ARGS_1 394
+#define _INIT_CALL_PY_EXACT_ARGS_2 395
+#define _INIT_CALL_PY_EXACT_ARGS_3 396
+#define _INIT_CALL_PY_EXACT_ARGS_4 397
#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
@@ -161,137 +160,137 @@ extern "C" {
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
#define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE
-#define _IS_NONE 399
+#define _IS_NONE 398
#define _IS_OP IS_OP
-#define _ITER_CHECK_LIST 400
-#define _ITER_CHECK_RANGE 401
-#define _ITER_CHECK_TUPLE 402
-#define _ITER_JUMP_LIST 403
-#define _ITER_JUMP_RANGE 404
-#define _ITER_JUMP_TUPLE 405
-#define _ITER_NEXT_LIST 406
-#define _ITER_NEXT_RANGE 407
-#define _ITER_NEXT_TUPLE 408
-#define _JUMP_TO_TOP 409
+#define _ITER_CHECK_LIST 399
+#define _ITER_CHECK_RANGE 400
+#define _ITER_CHECK_TUPLE 401
+#define _ITER_JUMP_LIST 402
+#define _ITER_JUMP_RANGE 403
+#define _ITER_JUMP_TUPLE 404
+#define _ITER_NEXT_LIST 405
+#define _ITER_NEXT_RANGE 406
+#define _ITER_NEXT_TUPLE 407
+#define _JUMP_TO_TOP 408
#define _LIST_APPEND LIST_APPEND
#define _LIST_EXTEND LIST_EXTEND
-#define _LOAD_ATTR 410
-#define _LOAD_ATTR_CLASS 411
+#define _LOAD_ATTR 409
+#define _LOAD_ATTR_CLASS 410
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#define _LOAD_ATTR_INSTANCE_VALUE 412
-#define _LOAD_ATTR_METHOD_LAZY_DICT 413
-#define _LOAD_ATTR_METHOD_NO_DICT 414
-#define _LOAD_ATTR_METHOD_WITH_VALUES 415
-#define _LOAD_ATTR_MODULE 416
-#define _LOAD_ATTR_MODULE_FROM_KEYS 417
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 418
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 419
-#define _LOAD_ATTR_PROPERTY_FRAME 420
-#define _LOAD_ATTR_SLOT 421
-#define _LOAD_ATTR_WITH_HINT 422
+#define _LOAD_ATTR_INSTANCE_VALUE 411
+#define _LOAD_ATTR_METHOD_LAZY_DICT 412
+#define _LOAD_ATTR_METHOD_NO_DICT 413
+#define _LOAD_ATTR_METHOD_WITH_VALUES 414
+#define _LOAD_ATTR_MODULE 415
+#define _LOAD_ATTR_MODULE_FROM_KEYS 416
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 417
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 418
+#define _LOAD_ATTR_PROPERTY_FRAME 419
+#define _LOAD_ATTR_SLOT 420
+#define _LOAD_ATTR_WITH_HINT 421
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
-#define _LOAD_BYTECODE 423
+#define _LOAD_BYTECODE 422
#define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
#define _LOAD_CONST LOAD_CONST
#define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL
-#define _LOAD_CONST_INLINE 424
-#define _LOAD_CONST_INLINE_BORROW 425
+#define _LOAD_CONST_INLINE 423
+#define _LOAD_CONST_INLINE_BORROW 424
#define _LOAD_CONST_MORTAL LOAD_CONST_MORTAL
#define _LOAD_DEREF LOAD_DEREF
-#define _LOAD_FAST 426
-#define _LOAD_FAST_0 427
-#define _LOAD_FAST_1 428
-#define _LOAD_FAST_2 429
-#define _LOAD_FAST_3 430
-#define _LOAD_FAST_4 431
-#define _LOAD_FAST_5 432
-#define _LOAD_FAST_6 433
-#define _LOAD_FAST_7 434
+#define _LOAD_FAST 425
+#define _LOAD_FAST_0 426
+#define _LOAD_FAST_1 427
+#define _LOAD_FAST_2 428
+#define _LOAD_FAST_3 429
+#define _LOAD_FAST_4 430
+#define _LOAD_FAST_5 431
+#define _LOAD_FAST_6 432
+#define _LOAD_FAST_7 433
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
#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 435
-#define _LOAD_GLOBAL_BUILTINS 436
-#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 437
-#define _LOAD_GLOBAL_MODULE 438
-#define _LOAD_GLOBAL_MODULE_FROM_KEYS 439
+#define _LOAD_GLOBAL 434
+#define _LOAD_GLOBAL_BUILTINS 435
+#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 436
+#define _LOAD_GLOBAL_MODULE 437
+#define _LOAD_GLOBAL_MODULE_FROM_KEYS 438
#define _LOAD_LOCALS LOAD_LOCALS
#define _LOAD_NAME LOAD_NAME
-#define _LOAD_SMALL_INT 440
-#define _LOAD_SMALL_INT_0 441
-#define _LOAD_SMALL_INT_1 442
-#define _LOAD_SMALL_INT_2 443
-#define _LOAD_SMALL_INT_3 444
+#define _LOAD_SMALL_INT 439
+#define _LOAD_SMALL_INT_0 440
+#define _LOAD_SMALL_INT_1 441
+#define _LOAD_SMALL_INT_2 442
+#define _LOAD_SMALL_INT_3 443
#define _LOAD_SPECIAL LOAD_SPECIAL
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _MAKE_CALLARGS_A_TUPLE 445
+#define _MAKE_CALLARGS_A_TUPLE 444
#define _MAKE_CELL MAKE_CELL
#define _MAKE_FUNCTION MAKE_FUNCTION
-#define _MAKE_WARM 446
+#define _MAKE_WARM 445
#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 447
-#define _MAYBE_EXPAND_METHOD_KW 448
-#define _MONITOR_CALL 449
-#define _MONITOR_CALL_KW 450
-#define _MONITOR_JUMP_BACKWARD 451
-#define _MONITOR_RESUME 452
+#define _MAYBE_EXPAND_METHOD 446
+#define _MAYBE_EXPAND_METHOD_KW 447
+#define _MONITOR_CALL 448
+#define _MONITOR_CALL_KW 449
+#define _MONITOR_JUMP_BACKWARD 450
+#define _MONITOR_RESUME 451
#define _NOP NOP
#define _POP_EXCEPT POP_EXCEPT
-#define _POP_JUMP_IF_FALSE 453
-#define _POP_JUMP_IF_TRUE 454
+#define _POP_JUMP_IF_FALSE 452
+#define _POP_JUMP_IF_TRUE 453
#define _POP_TOP POP_TOP
-#define _POP_TOP_LOAD_CONST_INLINE_BORROW 455
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW 454
#define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _PUSH_FRAME 456
+#define _PUSH_FRAME 455
#define _PUSH_NULL PUSH_NULL
-#define _PUSH_NULL_CONDITIONAL 457
-#define _PY_FRAME_GENERAL 458
-#define _PY_FRAME_KW 459
-#define _QUICKEN_RESUME 460
-#define _REPLACE_WITH_TRUE 461
+#define _PUSH_NULL_CONDITIONAL 456
+#define _PY_FRAME_GENERAL 457
+#define _PY_FRAME_KW 458
+#define _QUICKEN_RESUME 459
+#define _REPLACE_WITH_TRUE 460
#define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR
#define _RETURN_VALUE RETURN_VALUE
-#define _SAVE_RETURN_OFFSET 462
-#define _SEND 463
-#define _SEND_GEN_FRAME 464
+#define _SAVE_RETURN_OFFSET 461
+#define _SEND 462
+#define _SEND_GEN_FRAME 463
#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 465
-#define _STORE_ATTR 466
-#define _STORE_ATTR_INSTANCE_VALUE 467
-#define _STORE_ATTR_SLOT 468
-#define _STORE_ATTR_WITH_HINT 469
+#define _START_EXECUTOR 464
+#define _STORE_ATTR 465
+#define _STORE_ATTR_INSTANCE_VALUE 466
+#define _STORE_ATTR_SLOT 467
+#define _STORE_ATTR_WITH_HINT 468
#define _STORE_DEREF STORE_DEREF
-#define _STORE_FAST 470
-#define _STORE_FAST_0 471
-#define _STORE_FAST_1 472
-#define _STORE_FAST_2 473
-#define _STORE_FAST_3 474
-#define _STORE_FAST_4 475
-#define _STORE_FAST_5 476
-#define _STORE_FAST_6 477
-#define _STORE_FAST_7 478
+#define _STORE_FAST 469
+#define _STORE_FAST_0 470
+#define _STORE_FAST_1 471
+#define _STORE_FAST_2 472
+#define _STORE_FAST_3 473
+#define _STORE_FAST_4 474
+#define _STORE_FAST_5 475
+#define _STORE_FAST_6 476
+#define _STORE_FAST_7 477
#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 479
-#define _STORE_SUBSCR 480
+#define _STORE_SLICE 478
+#define _STORE_SUBSCR 479
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
#define _SWAP SWAP
-#define _TIER2_RESUME_CHECK 481
-#define _TO_BOOL 482
+#define _TIER2_RESUME_CHECK 480
+#define _TO_BOOL 481
#define _TO_BOOL_BOOL TO_BOOL_BOOL
#define _TO_BOOL_INT TO_BOOL_INT
#define _TO_BOOL_LIST TO_BOOL_LIST
@@ -301,13 +300,13 @@ extern "C" {
#define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT
#define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 483
+#define _UNPACK_SEQUENCE 482
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
#define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _YIELD_VALUE YIELD_VALUE
-#define MAX_UOP_ID 483
+#define MAX_UOP_ID 482
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
index 2f957afb259..2e126b57aa7 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -281,7 +281,6 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_LOAD_GLOBAL_MODULE] = HAS_DEOPT_FLAG,
[_LOAD_GLOBAL_BUILTINS] = HAS_DEOPT_FLAG,
[_LOAD_ATTR_MODULE] = HAS_DEOPT_FLAG,
- [_DYNAMIC_EXIT] = HAS_ESCAPES_FLAG,
[_START_EXECUTOR] = HAS_ESCAPES_FLAG,
[_MAKE_WARM] = 0,
[_FATAL_ERROR] = 0,
@@ -386,7 +385,6 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_DEOPT] = "_DEOPT",
[_DICT_MERGE] = "_DICT_MERGE",
[_DICT_UPDATE] = "_DICT_UPDATE",
- [_DYNAMIC_EXIT] = "_DYNAMIC_EXIT",
[_END_FOR] = "_END_FOR",
[_END_SEND] = "_END_SEND",
[_ERROR_POP_N] = "_ERROR_POP_N",
@@ -1097,8 +1095,6 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0;
case _LOAD_ATTR_MODULE:
return 1;
- case _DYNAMIC_EXIT:
- return 0;
case _START_EXECUTOR:
return 0;
case _MAKE_WARM:
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index 02e534caec1..2a9b777862c 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -1160,6 +1160,7 @@ class TestUopsOptimization(unittest.TestCase):
self.assertIsNotNone(ex)
self.assertIn("_RETURN_GENERATOR", get_opnames(ex))
+ @unittest.skip("Tracing into generators currently isn't supported.")
def test_for_iter_gen(self):
def gen(n):
for i in range(n):
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst
new file mode 100644
index 00000000000..f8eb7481aea
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst
@@ -0,0 +1 @@
+Improve JIT performance for generators.
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 9fb58b9cdcc..bef120b6477 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -5117,42 +5117,6 @@ dummy_func(
DECREF_INPUTS();
}
- tier2 op(_DYNAMIC_EXIT, (exit_p/4 --)) {
- tstate->previous_executor = (PyObject *)current_executor;
- _PyExitData *exit = (_PyExitData *)exit_p;
- _Py_CODEUNIT *target = frame->instr_ptr;
- #if defined(Py_DEBUG) && !defined(_Py_JIT)
- OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
- if (frame->lltrace >= 2) {
- printf("DYNAMIC EXIT: [UOp ");
- _PyUOpPrint(&next_uop[-1]);
- printf(", exit %lu, temp %d, target %d -> %s]\n",
- exit - current_executor->exits, exit->temperature.value_and_backoff,
- (int)(target - _PyFrame_GetBytecode(frame)),
- _PyOpcode_OpName[target->op.code]);
- }
- #endif
- _PyExecutorObject *executor;
- if (target->op.code == ENTER_EXECUTOR) {
- PyCodeObject *code = _PyFrame_GetCode(frame);
- executor = code->co_executors->executors[target->op.arg];
- Py_INCREF(executor);
- }
- else {
- if (!backoff_counter_triggers(exit->temperature)) {
- exit->temperature = advance_backoff_counter(exit->temperature);
- GOTO_TIER_ONE(target);
- }
- int optimized = _PyOptimizer_Optimize(frame, target, &executor, 0);
- if (optimized <= 0) {
- exit->temperature = restart_backoff_counter(exit->temperature);
- GOTO_TIER_ONE(optimized < 0 ? NULL : target);
- }
- exit->temperature = initial_temperature_backoff_counter();
- }
- GOTO_TIER_TWO(executor);
- }
-
tier2 op(_START_EXECUTOR, (executor/4 --)) {
Py_CLEAR(tstate->previous_executor);
#ifndef _Py_JIT
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 2e7f5ecc7aa..dc657281321 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -6510,48 +6510,6 @@
break;
}
- case _DYNAMIC_EXIT: {
- PyObject *exit_p = (PyObject *)CURRENT_OPERAND0();
- tstate->previous_executor = (PyObject *)current_executor;
- _PyExitData *exit = (_PyExitData *)exit_p;
- _Py_CODEUNIT *target = frame->instr_ptr;
- #if defined(Py_DEBUG) && !defined(_Py_JIT)
- OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
- if (frame->lltrace >= 2) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- printf("DYNAMIC EXIT: [UOp ");
- _PyUOpPrint(&next_uop[-1]);
- printf(", exit %lu, temp %d, target %d -> %s]\n",
- exit - current_executor->exits, exit->temperature.value_and_backoff,
- (int)(target - _PyFrame_GetBytecode(frame)),
- _PyOpcode_OpName[target->op.code]);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- #endif
- _PyExecutorObject *executor;
- if (target->op.code == ENTER_EXECUTOR) {
- PyCodeObject *code = _PyFrame_GetCode(frame);
- executor = code->co_executors->executors[target->op.arg];
- Py_INCREF(executor);
- }
- else {
- if (!backoff_counter_triggers(exit->temperature)) {
- exit->temperature = advance_backoff_counter(exit->temperature);
- GOTO_TIER_ONE(target);
- }
- _PyFrame_SetStackPointer(frame, stack_pointer);
- int optimized = _PyOptimizer_Optimize(frame, target, &executor, 0);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- if (optimized <= 0) {
- exit->temperature = restart_backoff_counter(exit->temperature);
- GOTO_TIER_ONE(optimized < 0 ? NULL : target);
- }
- exit->temperature = initial_temperature_backoff_counter();
- }
- GOTO_TIER_TWO(executor);
- break;
- }
-
case _START_EXECUTOR: {
PyObject *executor = (PyObject *)CURRENT_OPERAND0();
_PyFrame_SetStackPointer(frame, stack_pointer);
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 97831f58098..340770ae55e 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -757,9 +757,8 @@ translate_bytecode_to_trace(
opcode == SEND_GEN)
{
DPRINTF(2, "Bailing due to dynamic target\n");
- ADD_TO_TRACE(uop, oparg, 0, target);
- ADD_TO_TRACE(_DYNAMIC_EXIT, 0, 0, 0);
- goto done;
+ OPT_STAT_INC(unknown_callee);
+ return 0;
}
assert(_PyOpcode_Deopt[opcode] == CALL || _PyOpcode_Deopt[opcode] == CALL_KW);
int func_version_offset =
@@ -825,9 +824,8 @@ translate_bytecode_to_trace(
goto top;
}
DPRINTF(2, "Bail, new_code == NULL\n");
- ADD_TO_TRACE(uop, oparg, 0, target);
- ADD_TO_TRACE(_DYNAMIC_EXIT, 0, 0, 0);
- goto done;
+ OPT_STAT_INC(unknown_callee);
+ return 0;
}
if (uop == _BINARY_OP_INPLACE_ADD_UNICODE) {
@@ -914,7 +912,7 @@ count_exits(_PyUOpInstruction *buffer, int length)
int exit_count = 0;
for (int i = 0; i < length; i++) {
int opcode = buffer[i].opcode;
- if (opcode == _EXIT_TRACE || opcode == _DYNAMIC_EXIT) {
+ if (opcode == _EXIT_TRACE) {
exit_count++;
}
}
@@ -1119,12 +1117,6 @@ make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFil
dest->operand0 = (uint64_t)exit;
next_exit--;
}
- if (opcode == _DYNAMIC_EXIT) {
- _PyExitData *exit = &executor->exits[next_exit];
- exit->target = 0;
- dest->operand0 = (uint64_t)exit;
- next_exit--;
- }
}
assert(next_exit == -1);
assert(dest == executor->trace);
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c
index 5dd7725f398..6c0aadb87e6 100644
--- a/Python/optimizer_analysis.c
+++ b/Python/optimizer_analysis.c
@@ -616,7 +616,6 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
}
case _JUMP_TO_TOP:
case _EXIT_TRACE:
- case _DYNAMIC_EXIT:
return pc + 1;
default:
{
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index dde41d9407e..2383be8ea30 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -2469,10 +2469,6 @@
break;
}
- case _DYNAMIC_EXIT: {
- break;
- }
-
case _START_EXECUTOR: {
break;
}
diff --git a/Python/specialize.c b/Python/specialize.c
index 8831cfaa82b..4f84b2970ba 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -260,6 +260,7 @@ print_optimization_stats(FILE *out, OptimizationStats *stats)
fprintf(out, "Optimization inner loop: %" PRIu64 "\n", stats->inner_loop);
fprintf(out, "Optimization recursive call: %" PRIu64 "\n", stats->recursive_call);
fprintf(out, "Optimization low confidence: %" PRIu64 "\n", stats->low_confidence);
+ fprintf(out, "Optimization unknown callee: %" PRIu64 "\n", stats->unknown_callee);
fprintf(out, "Executors invalidated: %" PRIu64 "\n", stats->executors_invalidated);
print_histogram(out, "Trace length", stats->trace_length_hist);
diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py
index 161af09183a..4243b53850b 100644
--- a/Tools/scripts/summarize_stats.py
+++ b/Tools/scripts/summarize_stats.py
@@ -457,6 +457,7 @@ class Stats:
inner_loop = self._data["Optimization inner loop"]
recursive_call = self._data["Optimization recursive call"]
low_confidence = self._data["Optimization low confidence"]
+ unknown_callee = self._data["Optimization unknown callee"]
executors_invalidated = self._data["Executors invalidated"]
return {
@@ -498,6 +499,10 @@ class Stats:
"is too low.",
): (low_confidence, attempts),
Doc(
+ "Unknown callee",
+ "A trace is abandoned because the target of a call is unknown.",
+ ): (unknown_callee, attempts),
+ Doc(
"Executors invalidated",
"The number of executors that were invalidated due to watched "
"dictionary changes.",