From e806c4d550bc1af8f436ec001ae7fb8de021b29b Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 6 Aug 2024 20:03:17 +0200 Subject: [PATCH] [JIT] Avoid generating fast property assign path for readonly properties readonly properties will usually be IS_UNDEF on assignment, dodging the fast path anyway. The fast path does not handle the readonly scope check. The alternative would be handling scope there, but since there are some many variants that might be more trouble than it's worth. --- ext/opcache/jit/zend_jit_ir.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index b1ab4f423ae6c..2c93c31cd9dfc 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -14435,7 +14435,13 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, } else { prop_ref = ir_ADD_OFFSET(obj_ref, prop_info->offset); prop_addr = ZEND_ADDR_REF_ZVAL(prop_ref); - if (!ce || ce_is_instanceof || !(ce->ce_flags & ZEND_ACC_IMMUTABLE) || ce->__get || ce->__set || (prop_info->flags & ZEND_ACC_READONLY)) { + /* With the exception of __clone(), readonly assignment always happens on IS_UNDEF, doding + * the fast path. Thus, the fast path is not useful. */ + if (prop_info->flags & ZEND_ACC_READONLY) { + ZEND_ASSERT(slow_inputs == IR_UNUSED); + goto slow_path; + } + if (!ce || ce_is_instanceof || !(ce->ce_flags & ZEND_ACC_IMMUTABLE) || ce->__get || ce->__set) { // Undefined property with magic __get()/__set() if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); @@ -14527,6 +14533,8 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, ir_ref arg3, arg5; ir_MERGE_list(slow_inputs); + +slow_path: jit_SET_EX_OPLINE(jit, opline); if (Z_MODE(val_addr) == IS_REG) {