-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix memory leaks due to throw expressions #5448
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
Here are some additional considerations on issues we need to deal with if we ever introduce a "block expression" concept, as part of match expressions or otherwise. While not needed right now, we should try to design this in a way that covers that case as well.
Here the
Depending on which catch catches the exception, |
Simple alternative that addresses just the throw expression issue in a minimal way: #5450 |
Thanks for working on this!
Unfortunately we have this issue already in the match expression RFC. function test() {
var_dump([new stdClass(), match(true) {
default => {
return 'test';
'not reached'
}
}]);
}
test();
I think I will probably proceed without block expressions at this point (but with statement lists). Even if we could solve this in time people don't seem very happy with the proposed block syntax. Either way, this probably needs to be solved at some point. It would make sense converting |
@iluuu1994 Yes, converting break/continue/goto to expressions would cause the same issue. We discussed this with @bwoebi on Friday, and our conclusion was basically that this approach would be right for handling of break/continue/return expressions (or them occurring in block expressions), but that this is not the right fix for the throw case. Exception handling should continue to always use live-range based automatic unwinding. One of the reasons is that this issue is not limited to exceptions actually thrown by the
Emitting explicit frees for the So, if we want to solve this in a more general way than #5450, I think we really need to either prevent the live ranges from being dropped in opcache, or make opcache insert explicit frees when they get dropped. |
Closing this one for now. The currently problematic case is fixed bug #5450. We can pick this work up again if and when we convert something like break into an expression. |
Thanks Nikita, makes sense. It doesn't look like the match expression will pass with blocks anyway. |
This introduces accurate tracking in the compiler of all the variables that are currently live. There's some overlap with the loop_var stack, and both can probably be combined (and preferably should be).
This allows us to free all pending variables before compiling a throw expression.
While the tracking here works, the actual freeing is incorrect as-is. The issue is that this just unconditionally frees everything, but of course the throw itself will also free the same variables based on live ranges, if the live ranges are present (without opcache).
I'm not quite sure on how to best handle this yet.