Do not exit to VM when setting undefined prop in constructor

JIT'ed ASSIGN_OBJ expressions will exit to VM when the prop is undef. However,
in a constructor it's very likely the case. Therefore most traces with `new`
expressions will exit to VM.

Here I ensure that we don't need to exit to VM when it's likely that the
prop will be undef.

In the function JIT we compile a slow path to handle such properties,
but not in the tracing JIT, assumingly to reduce code size. Here I enable
compilation of the slow path in the tracing JIT when it's likely the prop
will be undef. Quite conveniently we already record the prop type during
tracing, so I use that to make the decision.

This results in a 1.20% wall time improvement on the symfony demo benchmark
with 20 warmup requests.

Closes GH-18576
This commit is contained in:
Arnaud Le Blanc 2025-05-16 21:23:15 +02:00
parent 3cd0383d91
commit 16ca097ef2
No known key found for this signature in database

View file

@ -14971,8 +14971,9 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit,
ZEND_ASSERT(slow_inputs == IR_UNUSED); ZEND_ASSERT(slow_inputs == IR_UNUSED);
goto slow_path; goto slow_path;
} }
// Undefined property with potential magic __get()/__set() or lazy object // Undefined property with potential magic __get()/__set() or lazy object
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && prop_type != IS_UNDEF) {
int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);