-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Ignore ZEND_EXIT, ZEND_BEGIN_SILENCE, ZEND_END_SILENCE in JIT check #6640
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
2e175c7
to
8215652
Compare
I think there are general issues with user opcode handlers and JIT. Maybe @dstogov can clarify? |
JIT disables usage of user opcode handlers on purpose. It should be able to inline optimized implementation directly. I don't like this general API, because it'll work only for some opcodes. @twose can you try to hardcode a check for ZEND_EXIT, ZEND_BEGIN_SILENCE, ZEND_END_SILENCE exceptions and verofy if JIT-ed code calls user opcode handlers out of the box and don't trigger any other problems with both -dopcache.jit=function and -d opcache.jit=tracing. |
Some user opcode handler actually gets called when JIT is used, so do not disable JIT even if these user opcode handlers were registered, just ignore them.
8215652
to
a2a8411
Compare
Sorry to have missed the reply... I've updated the code and add a test for it. For all I know, "opcache.jit=function" is the highest level of JIT, so whether we only need to test it with "opcache.jit=function"? |
Correct me if I'm wrong, but this appears as though JIT has some behavior with Otherwise, could the other opcodes in the same case also be excluded? |
I guess zend_jit_tail_handler moved the OPCODE (those will exit the current stack frame) to the tail, so we can jmp to the opcode handler directly instead of calling it and check the exception after it. |
I don't like this, but in general, may commit. Testing with opcache.jit=function should be enough. JIT may benefit from generation very simple code for BEGIN/END_SILENCE and allow register allocation around them. This PR prevents this ability, or at least makes it conditional... @nikic your opinion? I see some test failures, but they look unrelated... |
Could we disable the optimization of a specific opcode only when the user handler of it was registered? This really increases some workload but it seems that nothing remains but to do it in this way... 🥲 |
Yes it's possible. If @nikic won't protest against this, I'll merger this on Monday. |
@twose fell free to commit this. @trowski disabling individual opcodes is not simple, because we should not only disable code generation for them, but also disable code-generation for some patterns that include these opcodes, disable register-allocation for intervals that include these opcodes, and finally break assumptions about opcode behavior and possible side effects. |
There is something wrong with the build at https://dev.azure.com/phpazuredevops/PHP/_build/results?buildId=15718&view=results
|
Sorry for not noticing this failure, and I can't reproduce this failure on my macOS and Ubuntu at all (even I tried using the same build configurations). And I tried to run azure CI on my repo but tasks are always queued. @nikic seems to be solving this problem, so all I can do is wait... |
ref: https://bugs.php.net/bug.php?id=80621
Swoole only replaced
ZEND_EXIT
,ZEND_BEGIN_SILENCE
,ZEND_END_SILENCE
opcode handlers.ZEND_EXIT
can help Swoole to detect exit/die operation and exit from the current coroutine correctly.ZEND_*_SILENCE
can help Swoole to switchEG(error_reporting)
to keep the right behavior when using the error control operator.I don't know much about JIT, but I think that JIT should not break the compatibility of all user opcodes...
And sometimes it is acceptable even if the compatibility was broken, these user opcode handlers are not very important, especially when developers want to enable JIT anyway.