Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7797182

Browse files
authored
GH-118093: Improve handling of short and mid-loop traces (GH-122252)
1 parent78df104 commit7797182

File tree

2 files changed

+34
-35
lines changed

2 files changed

+34
-35
lines changed

‎Objects/genobject.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,9 @@ _PyGen_yf(PyGenObject *gen)
342342
{
343343
if (gen->gi_frame_state==FRAME_SUSPENDED_YIELD_FROM) {
344344
_PyInterpreterFrame*frame=&gen->gi_iframe;
345-
assert(is_resume(frame->instr_ptr));
346-
assert((frame->instr_ptr->op.arg&RESUME_OPARG_LOCATION_MASK) >=RESUME_AFTER_YIELD_FROM);
345+
// GH-122390: These asserts are wrong in the presence of ENTER_EXECUTOR!
346+
// assert(is_resume(frame->instr_ptr));
347+
// assert((frame->instr_ptr->op.arg & RESUME_OPARG_LOCATION_MASK) >= RESUME_AFTER_YIELD_FROM);
347348
returnPyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame));
348349
}
349350
returnNULL;

‎Python/optimizer.c‎

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,7 @@ add_to_trace(
503503
if (trace_stack_depth >= TRACE_STACK_SIZE) { \
504504
DPRINTF(2, "Trace stack overflow\n"); \
505505
OPT_STAT_INC(trace_stack_overflow); \
506-
trace_length = 0; \
507-
goto done; \
506+
return 0; \
508507
} \
509508
assert(func == NULL || func->func_code == (PyObject *)code); \
510509
trace_stack[trace_stack_depth].func = func; \
@@ -550,6 +549,7 @@ translate_bytecode_to_trace(
550549
}trace_stack[TRACE_STACK_SIZE];
551550
inttrace_stack_depth=0;
552551
intconfidence=CONFIDENCE_RANGE;// Adjusted by branch instructions
552+
booljump_seen= false;
553553

554554
#ifdefPy_DEBUG
555555
char*python_lltrace=Py_GETENV("PYTHON_LLTRACE");
@@ -568,7 +568,6 @@ translate_bytecode_to_trace(
568568
ADD_TO_TRACE(_START_EXECUTOR,0, (uintptr_t)instr,INSTR_IP(instr,code));
569569
uint32_ttarget=0;
570570

571-
top:// Jump here after _PUSH_FRAME or likely branches
572571
for (;;) {
573572
target=INSTR_IP(instr,code);
574573
// Need space for _DEOPT
@@ -577,6 +576,13 @@ translate_bytecode_to_trace(
577576
uint32_topcode=instr->op.code;
578577
uint32_toparg=instr->op.arg;
579578

579+
if (!progress_needed&&instr==initial_instr) {
580+
// We have looped around to the start:
581+
RESERVE(1);
582+
ADD_TO_TRACE(_JUMP_TO_TOP,0,0,0);
583+
gotodone;
584+
}
585+
580586
DPRINTF(2,"%d: %s(%d)\n",target,_PyOpcode_OpName[opcode],oparg);
581587

582588
if (opcode==ENTER_EXECUTOR) {
@@ -603,30 +609,21 @@ translate_bytecode_to_trace(
603609
/* Special case the first instruction,
604610
* so that we can guarantee forward progress */
605611
if (progress_needed) {
606-
progress_needed= false;
607-
if (opcode==JUMP_BACKWARD||opcode==JUMP_BACKWARD_NO_INTERRUPT) {
608-
instr+=1+_PyOpcode_Caches[opcode]- (int32_t)oparg;
609-
initial_instr=instr;
610-
if (opcode==JUMP_BACKWARD) {
611-
ADD_TO_TRACE(_TIER2_RESUME_CHECK,0,0,target);
612-
}
613-
continue;
614-
}
615-
else {
616-
if (OPCODE_HAS_EXIT(opcode)||OPCODE_HAS_DEOPT(opcode)) {
617-
opcode=_PyOpcode_Deopt[opcode];
618-
}
619-
assert(!OPCODE_HAS_EXIT(opcode));
620-
assert(!OPCODE_HAS_DEOPT(opcode));
612+
if (OPCODE_HAS_EXIT(opcode)||OPCODE_HAS_DEOPT(opcode)) {
613+
opcode=_PyOpcode_Deopt[opcode];
621614
}
615+
assert(!OPCODE_HAS_EXIT(opcode));
616+
assert(!OPCODE_HAS_DEOPT(opcode));
622617
}
623618

624619
if (OPCODE_HAS_EXIT(opcode)) {
625-
// Make space for exit code
620+
// Make space for side exit and final _EXIT_TRACE:
621+
RESERVE_RAW(2,"_EXIT_TRACE");
626622
max_length--;
627623
}
628624
if (OPCODE_HAS_ERROR(opcode)) {
629-
// Make space for error code
625+
// Make space for error stub and final _EXIT_TRACE:
626+
RESERVE_RAW(2,"_ERROR_POP_N");
630627
max_length--;
631628
}
632629
switch (opcode) {
@@ -672,19 +669,18 @@ translate_bytecode_to_trace(
672669
}
673670

674671
caseJUMP_BACKWARD:
672+
ADD_TO_TRACE(_CHECK_PERIODIC,0,0,target);
673+
_Py_FALLTHROUGH;
675674
caseJUMP_BACKWARD_NO_INTERRUPT:
676675
{
677-
_Py_CODEUNIT*target=instr+1+_PyOpcode_Caches[opcode]- (int)oparg;
678-
if (target==initial_instr) {
679-
/* We have looped round to the start */
680-
RESERVE(1);
681-
ADD_TO_TRACE(_JUMP_TO_TOP,0,0,0);
682-
}
683-
else {
676+
instr+=1+_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]- (int)oparg;
677+
if (jump_seen) {
684678
OPT_STAT_INC(inner_loop);
685679
DPRINTF(2,"JUMP_BACKWARD not to top ends trace\n");
680+
gotodone;
686681
}
687-
gotodone;
682+
jump_seen= true;
683+
gototop;
688684
}
689685

690686
caseJUMP_FORWARD:
@@ -904,23 +900,25 @@ translate_bytecode_to_trace(
904900
assert(instr->op.code==POP_TOP);
905901
instr++;
906902
}
903+
top:
904+
// Jump here after _PUSH_FRAME or likely branches.
905+
progress_needed= false;
907906
}// End for (;;)
908907

909908
done:
910909
while (trace_stack_depth>0) {
911910
TRACE_STACK_POP();
912911
}
913912
assert(code==initial_code);
914-
// Skip short traceslike _SET_IP, LOAD_FAST, _SET_IP, _EXIT_TRACE
915-
if (progress_needed||trace_length<5) {
913+
// Skip short traceswhere we can't even translate a single instruction:
914+
if (progress_needed) {
916915
OPT_STAT_INC(trace_too_short);
917916
DPRINTF(2,
918-
"No trace for %s (%s:%d) at byte offset %d (%s)\n",
917+
"No trace for %s (%s:%d) at byte offset %d (no progress)\n",
919918
PyUnicode_AsUTF8(code->co_qualname),
920919
PyUnicode_AsUTF8(code->co_filename),
921920
code->co_firstlineno,
922-
2*INSTR_IP(initial_instr,code),
923-
progress_needed ?"no progress" :"too short");
921+
2*INSTR_IP(initial_instr,code));
924922
return0;
925923
}
926924
if (trace[trace_length-1].opcode!=_JUMP_TO_TOP) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp