-
-
Notifications
You must be signed in to change notification settings - Fork 32k
gh-103615: Use local events for opcode tracing #109472
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Looks good. It could do with some tests beyond the implicit one in #108982. |
The one in #103615 is a bit tricky - it will only reproduce if |
I think it is OK to add as a normal test without using subprocesses. Maybe add it to the monitoring tests, rather than sys_settrace tests? That way it will fail if only test.test_monitoring is run. |
Well if the regression test does not fail on the old code, it does not help that much. If we only run a normal test, then it's doing exactly the same thing as our existing tests for I created the working regression test for this specific case. It needs some extra libraries as it requires a new file to execute in a separate process. However, it's the test we need for this scenario. Let me know if you have suggestions on the test. |
Hi @markshannon , just fixed the conflict, is there anything I should update on this PR? Thanks! |
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.
One style issue, otherwise looks good.
Thanks for doing this |
|
|
* Use local monitoring for opcode trace * Remove f_opcode_trace_set * Add test for setting f_trace_opcodes after settrace
* Use local monitoring for opcode trace * Remove f_opcode_trace_set * Add test for setting f_trace_opcodes after settrace
The opcode tracing of PEP 669 to support legacy tracing is not ideal. I talked about it in #103615 but I'll list the gist here:
f_trace_opcodes
BEFOREsys.settrace()
, which is different than what it used to do (I'd consider this as a bug actually).f_trace_opcodes
is set once, you set it globally and forever. The instruction event callback will ALWAYS trigger on every single instruction when you are tracing, even iff_trace_opcodes
is set toFalse
on that frame. It will stick even if you turn off the trace and back on. (there will be no event because in the callback,f_trace_opcodes
is explicitly checked, but it's a performance hit).The best way to fix this is to use local events for opcode tracing. By nature, opcode tracing is enabled frame by frame, there's no way to enable it globally for every code object from Python, so that's what the underlying structure should do.
There are 4 occasions to enable instrumentation on instruction event on a code object:
frame.f_trace_opcode = True
if trace is enabled alreadyframe.f_trace_opcode
may persist.frame.f_trace_opcode == True
frame.f_trace = True
- this is to trace the current frame before a call.There is only 1 case when we need to disable the instrumentation:
f_trace_opcode == False
f_trace_opcode = False
With this mechanism, we eliminate the global
f_opcode_trace_set
.The performance improvement is significant on cases when opcode events is only needed from a small piece of code:
For the code above, the time saving is about 50%.
Oh, this also fixes #108982.