-
Notifications
You must be signed in to change notification settings - Fork 155
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
perf(profiling): remove execute_internal hook #2719
base: master
Are you sure you want to change the base?
Conversation
fb2ae5e
to
de2181c
Compare
1ad5a64
to
2f1f393
Compare
This does some... uh... let's say "clever" things to avoid using the zend_execute_internal hook. In PHP 8.4, that would prevent frameless function call optimizations from being used. Using the hook also has performance costs even on older versions.
2f1f393
to
6d1ae69
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #2719 +/- ##
============================================
+ Coverage 79.24% 79.52% +0.28%
Complexity 2216 2216
============================================
Files 201 201
Lines 22595 22595
============================================
+ Hits 17905 17969 +64
+ Misses 4690 4626 -64
Flags with carried forward coverage won't be shown. Click here to find out more. see 6 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
It took quite a few randomized test runs but I managed to get a crash. Here's the top of the stack:
Basically, the tracer calls the profiler's interrupt function before calling a closure in an end hook. The profiler crashes when looking at the run time cache of the "risky" frame. Havnen't yet identified why the run time cache is invalid. |
PROF-9982
Description
Background and Motivation
For wall- and CPU- time, we walk the call stack in the VM interrupt handler. Unfortunately, if an internal function call is the leaf frame at the time the interrupt was triggered, it gets popped off the call stack before the VM interrupt handler is triggered. To work around this, we add the zend_execute_internal hook and manually call the routine to collect the call stack while the internal frame was still on the call stack.
Using the
zend_execute_internal
hook has performance costs today. These costs are made even worse on the upcoming PHP 8.4 release because it adds a new optimization for frameless calls, and settingzend_execute_internal
disables this optimization.The goal of this task is to avoid installing this
zend_execute_internal
hook, while not regressing on performance, and without losing functionality--we definitely need that leaf frame. A lot of functions show up there, like regular expression and database related functions.Implementation
This does some... uh... let's say "clever" things to avoid using the
zend_execute_internal
hook. In thread B which triggers the interrupt, it also saves the current value of thread A'sEG(current_execute_data)
. Then when thread A handles its interrupt, it compares that againstEG(vm_stack_top)
. If they are equal, then that's used as the top of the stack instead of theexecute_data
passed to the interrupt handler by the engine, and otherwise we just useexecute_data
as normal.Reviewer checklist