Description
Originally posted in #15819 (comment)
The following code:
<?php
class A {
private $_prop;
public $prop {
get => $this->_prop;
}
}
for ($i=0;$i<2;$i++)
echo (new A)->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:
|
} else if (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_t call_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_var EXECUTE_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