Hey Edmond,

On 2.5.2025 10:14:37, Edmond Dantes wrote:
Good day, everyone.

In the neighboring thread Concept: Lightweight error channels, the
topic of exception performance was discussed.

The main issue is the immediate backtrace generation in the
constructor, which can cause up to a 50% performance loss compared to
return (as I understood from the discussion — I may be mistaken).
It basically depends on the stack depth at that point. So it _can_ be more, or less than that.
I have a small idea on how to improve the situation in cases where
exceptions are caught and a backtrace isn't needed.

Let’s assume we delay backtrace generation. In PHP, you can’t just
keep a reference to a stack frame, since it may be destroyed. You
could copy it, of course (which is relatively inexpensive compared to
generating the full backtrace).

Based on that, there are two possible implementations:

* Generate the backtrace at the moment the stack is freed

* Clone the stack frame when the stack is freed (this is roughly what
happens in Python)

This would require changes to the functions
`zend_vm_stack_free_extra_args_ex` and
`zend_vm_stack_free_extra_args`.

What you actually want is, I think, a proper new call_info flag, which you can attach: "frame has associated exceptions to check" (you can stuff that into the same branch than ZEND_CALL_FREE_EXTRA_ARGS in leave_helper though).

There can be many exceptions referencing the same (and different) stack frames in flight. So you effectively will have to manage a weakmap of next-stack-frame to exception objects.

This certainly seems doable.


Of note is also that $trace and $string are actually private properties. So access via reflection works there. And it might be changed too. It possibly should be converted to a property hook then, which materializes on first access.


But otherwise, I think, this is mostly a matter of implementation. If you're interested in providing a patch, you're definitely welcome.


Bob

Reply via email to