From ee732d3a60bbda1b5ed4ad109015e5a17f95e652 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 18 Apr 2025 15:22:32 +0200 Subject: [PATCH] Provide script to TSSA build in tracing JIT For the following script: ```php final class Foo { public $prop = 0; } function test(Foo $obj) { $obj->prop=1; } $foo = new Foo; for ($i=0;$i<3;$i++) { test($foo); } ``` When comparing the TSSA (via opcache.jit_debug) vs the opcache SSA (via opcache.opt_debug_level=0x400000) we note that in TSSA, the RECV op for `test` does not infer the type of the argument to be class `Foo`. This is because the optimizer uses the `script` pointer to figure out known classes but TSSA always sets `script` to NULL. This in turn generates suboptimal assembly because `zend_may_throw` returns 1 due to the unknown CE in the TSSA, resulting in an extra exception check in the assembly code. --- ext/opcache/jit/zend_jit_trace.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 68c096d9d3df2..077ab8e871271 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4117,6 +4117,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par checkpoint = zend_arena_checkpoint(CG(arena)); + zend_accel_hash_entry *accel_h_entry = zend_accel_hash_find_entry(&ZCSG(hash), trace_buffer->op_array->filename); + if (accel_h_entry) { + zend_persistent_script *persistent_script = (zend_persistent_script *) accel_h_entry->data; + if (!persistent_script->corrupted) { + script = &persistent_script->script; + } + } + ssa = zend_jit_trace_build_tssa(trace_buffer, parent_trace, exit_num, script, op_arrays, &num_op_arrays); if (!ssa) {