-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add new observer API #5857
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
Add new observer API #5857
Conversation
@beberlei Can you add numbers from your benchmarking? |
Also clean up ext/observer's .end handling
Also add a wrapper to the runtime cache getter
The performance is very close to each other, so much that Zend/bench.php is not reliable because its either one or the other being faster on multiple iterations. Wordpress index.php with 1 post repeated 100 times is also very close at ~3,9 secs for both. Here are the numbers of the test php-src clean (commit before this patch is introduced) vs php with this patch enabled (but no observer registered). The test setup is the same as originally done with phpng Observer:
clean php-src (1c0ee68)
You can see that the patch slightly increases instructions by 1,01% on Zend/bench.php and by 0,3% on Wordpress. Commands
configure
php.ini
|
@dstogov Do you have any concerns with this patch's implementation? According to Ben's benchmarks the overhead when not in use is acceptable. We still need to add tests and get generators working correctly, but I want to check in with you on the implementation and any remaining concerns. |
Thanks! And \o/
Done.
Done.
I refactored the observer runtime cache init and removed
Yes. Sorry about that. I had inadvertently run all the tests in observer mode in CI after the I had to add an observer check to If an observer extension is present, JIT will be disabled. JIT support isn't something we are hoping to get supported for merge, but we might want to add support for it later. Thanks so much for responding to us so promptly Dmitry! My schedule is completely cleared now through EOD Monday to get anything else wrapped up for merge before RC1 if possible. So let me know if there's anything else that needs to be tweaked and I'll get on it straight away. :) |
@SammyK I may spend 1-2 hours on Monday to check this once again (and may be improve something). |
Zend/zend_observer.c
Outdated
ZEND_API void zend_observer_activate(void) { | ||
/* todo: how to size the arena? */ | ||
if (ZEND_OBSERVER_ENABLED) { | ||
fcall_handlers_arena = zend_arena_create(1024); | ||
} | ||
} |
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.
@dstogov Any recommendations on sizing the arena?
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.
(N * 4096) should be friendly for Zend MM.
Zend/zend_observer.c
Outdated
zend_llist_destroy(&handlers_list); | ||
} | ||
|
||
void zend_observe_fcall_begin( |
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.
Do the definitions of zend_observe_fcall_begin
, zend_observer_fcall_call_end_helper
, and zend_observe_fcall_end
need ZEND_API
too? Or is it sufficient for the declaration only? I don't know Windows, which mostly seems to be the only platform this affects.
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.
I don't see a reason to export them at the moment. We can always export them later if there is a need to. That being said, we could probably remove ZEND_API
from the startup/activate and shutdown/deactivate functions. Not sure those should ever be called from a linked lib.
Zend/zend_observer.h
Outdated
void *observer_handlers = ZEND_OBSERVER_HANDLERS(&EX(func)->op_array); | ||
if (!observer_handlers) { | ||
zend_observer_fcall_install((zend_function *)&EX(func)->op_array); | ||
observer_handlers = ZEND_OBSERVER_HANDLERS(&EX(func)->op_array); | ||
} | ||
ZEND_ASSERT(observer_handlers); | ||
if (observer_handlers != ZEND_OBSERVER_NOT_OBSERVED) { | ||
zend_observe_fcall_begin(observer_handlers, execute_data); | ||
} |
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.
Should the body here get extracted into a helper like I did for zend_observer_maybe_fcall_call_end
to reduce code size when inlining? Or should the reverse be done and zend_observer_fcall_call_end_helper
inline into zend_observer_maybe_fcall_call_end
?
The original motivation of the helper was to reduce code size without hurting performance much; the main conditional check would inline but if it's true then the helper body isn't inlined, so it won't hurt code size. Now that these are mostly done in spec handlers, we are probably fine with more aggressive inlining, I would guess?
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.
I don't know what would be better so I don't have any strong opinions on this one.
@dstogov Any issues with merging this one in today to make this part of RC1? :) Once we update a few extensions to use the new API we'll likely have a followup PR in about a month or so to wrap up any additional issues found. |
@SammyK RC1 is not this week's release, so there's no need to rush: https://wiki.php.net/todo/php80#timetable |
Looks good to me. |
Also cleanup zend_observer_maybe_fcall_call_begin
Would this be a blocker for merge? I gave this a shot today to remove the @carusogabriel Ah yes, my mistake: Beta 3. I misread @sgolemon's comment above:
|
This is not a blocker. Just don't forget this. |
@SammyK No problem. I'll wait until EOD today (18:00h CEST) and tag the release. |
I've just merged in the latest master, which had a conflict. Tests passed locally; just waiting on CI to hopefully show there were no surprises and then I will merge it in. |
This supersedes PR #5582. It incorporates some of the design feedback such as:
run_time_cache
of thezend_op_array
to store the handlers.It still uses per-function targeting, rather than a global handler that is always called. This is a design decision that should lower the overhead of observers that only instrument a handful of functions (common for application performance monitoring products) without removing generic capability to observe everything.
I changed the name from "instrumentation" to "observer" to highlight that when using this API the state generally should not be changed, only observed.
To be ready:
zend_test
extension behind a setting so it can be turned on/off..end
handling forrequire/include
(sigsegv)