From 16ca097ef2825cbf668a8ea6610e46db5e8df6a7 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 16 May 2025 21:23:15 +0200 Subject: [PATCH] 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 --- ext/opcache/jit/zend_jit_ir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 2a3b9baf28e..1fdb1b9b3af 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -14971,8 +14971,9 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, ZEND_ASSERT(slow_inputs == IR_UNUSED); goto slow_path; } + // 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); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);