Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.1k
GH-128375: Better instrument forFOR_ITER
#128445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
GH-128375: Better instrument forFOR_ITER
#128445
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Lib/test/test_code.py Outdated
code_offset_to_line(code, src)-base, | ||
code_offset_to_line(code, left)-base, | ||
code_offset_to_line(code, right)-base |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
code_offset_to_line(code,src)-base, | |
code_offset_to_line(code,left)-base, | |
code_offset_to_line(code,right)-base | |
code_offset_to_line(code,src)-base, | |
code_offset_to_line(code,left)-base, | |
code_offset_to_line(code,right)-base, |
Python/bytecodes.c Outdated
tier1 inst(INSTRUMENTED_END_FOR, (receiver, value -- receiver)) { | ||
/* Need to create a fake StopIteration error here, | ||
* to conform to PEP 380 */ | ||
//* to conform to PEP 380ED_NO*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
?
Python/bytecodes.c Outdated
* This has the benign side effect that if value is | ||
* finalized it will see the location as the FOR_ITER's. | ||
*/ | ||
frame->instr_ptr = prev_instr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Is there a precedent for this? Seems like the kind of thing that can cause confusion/problems later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
The tier 2 code generator doesn't like it either. I think I'll need to add a new annotation "no_saved_ip" to tell the code generator not to updateframe->instr_ptr
.
Any suggestions for a better name than "no_saved_ip"?
I was wondering if we couldn't, instead of putting in |
Trying this PR compared tofa985be, more of my tests fail (on a work-in-progress branch to account for BRANCH_LEFT etc). I'll debug my code, but I wish there were a way to get a concrete plan to work from. |
I think that would be worse overall, for a few reasons:
|
…ave the IP to frame->instr_ptr
nedbat commentedJan 3, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Is this intended? continue.py: foriinrange(10):a=icontinue# 3a=99asserta==9# 5 Disassembled with this branch:
sys.monitoring events usingrun_sysmon.py:
Is it right that the starred line has a BRANCH_RIGHT event from a POP_ITER instruction? |
No. It should be from the |
Two more examples of branch event surprises.run_sysmon.py is used to see the sys.monitoring events. These are using commitcbe6c7c from PR#128445. ifdebug.pyforvaluein [True,False]:ifvalue:if__debug__:x=4else:x=6 Disassembled:
Events:
The starred line is a BRANCH event from a NOT_TAKEN instruction. 1176_async.pyimportasyncioasyncdefasync_gen():yield4asyncdefasync_test():asyncforiinasync_gen():print(i+8)asyncio.run(async_test()) Disassembled:
Events:
Here there are no BRANCH events at all. I would expect some for the |
These examples are really helpful, but I don't think they are relevant to this PR. The |
* the FOR_ITER as the previous instruction. | ||
* This has the benign side effect that if value is | ||
* finalized it will see the location as the FOR_ITER's. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Can't we just teachPOP_ITER
to look atprev_instr-1
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
prev_instr
is the previously executed instruction, which is probably not the previous instruction in the code.
There is no way forPOP_ITER
to tell where the jump came from if we overwriteframe->instr_ptr
f826bec
intopython:mainUh oh!
There was an error while loading.Please reload this page.
FOR_ITER_LIST specialization.
Uh oh!
There was an error while loading.Please reload this page.
This PR:
POP_TOP
and the end of afor
loop toPOP_ITER
(it pops the iterator)NOT_TAKEN
followingFOR_ITER
and instruments theFOR_ITER
andPOP_ITER
insteadEXTENDED_ARGS
inco_branches()
.The last one isn't strictly related to the issue, but came up while fixing the main issue.
Changing the instrumentation pattern has two effects:
NOT_TAKEN
) per iteration, at the cost of one additional dispatch when the loop is exited.DISABLE
d, theFOR_ITER
can be specialized and jitted.Performance is neutral on the standard benchmarks for tier1, as expected.
FOR_ITER
is poor asDISABLE
doesn't remove the instrumentation. #128375