Description
Originally posted in #15819 (comment)
The following code:
<?phpclass A {
private$_prop;
public$prop {
get => $this->_prop;
}
}
for ($i=0;$i<2;$i++)
echo (newA)->prop;using opcache.jit=1101
Resulted in this output:
But I expected this output instead:
I analysed this and this is a different bug related to a cache slot optimization.
As far as I understand, this happens for when the cache slot satisfies the ZEND_IS_PROPERTY_HOOK_SIMPLE_GET condition. Then we set up a function call frame and re-enter the VM to execute the hook function:
| } elseif (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { |
| zend_function*hook=prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; |
| ZEND_ASSERT(hook->type==ZEND_USER_FUNCTION); |
| ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); |
| |
| uint32_tcall_info=ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; |
| if (OP1_TYPE&IS_CV) { |
| GC_ADDREF(zobj); |
| } |
| if (OP1_TYPE& (IS_CV|IS_VAR|IS_TMP_VAR)) { |
| call_info |= ZEND_CALL_RELEASE_THIS; |
| } |
| zend_execute_data*call=zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); |
| call->prev_execute_data=execute_data; |
| call->call=NULL; |
| call->return_value=EX_VAR(opline->result.var); |
| call->run_time_cache=RUN_TIME_CACHE(&hook->op_array); |
| |
| execute_data=call; |
| EG(current_execute_data) =execute_data; |
| zend_init_cvs(0, hook->op_array.last_varEXECUTE_DATA_CC); |
| |
| #if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND==ZEND_VM_KIND_CALL) || (ZEND_VM_KIND==ZEND_VM_KIND_HYBRID)) |
| opline=hook->op_array.opcodes; |
| #else |
| EX(opline) =hook->op_array.opcodes; |
| #endif |
| LOAD_OPLINE_EX(); |
| ZEND_OBSERVER_SAVE_OPLINE(); |
| ZEND_OBSERVER_FCALL_BEGIN(execute_data); |
| |
| ZEND_VM_ENTER_EX(); |
| } |
This seems incompatible with how the minimal JIT works, getting the property will be skipped.
Indeed if we get rid of ZEND_SET_PROPERTY_HOOK_SIMPLE_GET in zend_object_handlers.c or go to a higher optimization level the problem disappears. I'm not sure yet how to solve that.
PHP Version
master
Operating System
Linux
Description
Originally posted in #15819 (comment)
The following code:
using
opcache.jit=1101Resulted in this output:
But I expected this output instead:
I analysed this and this is a different bug related to a cache slot optimization.
As far as I understand, this happens for when the cache slot satisfies the
ZEND_IS_PROPERTY_HOOK_SIMPLE_GETcondition. Then we set up a function call frame and re-enter the VM to execute the hook function:php-src/Zend/zend_vm_def.h
Lines 2094 to 2126 in 7c2204c
This seems incompatible with how the minimal JIT works, getting the property will be skipped.
Indeed if we get rid of
ZEND_SET_PROPERTY_HOOK_SIMPLE_GETinzend_object_handlers.cor go to a higher optimization level the problem disappears. I'm not sure yet how to solve that.PHP Version
master
Operating System
Linux