Closed TRowbotham closed 2 weeks ago
@iluuu1994 it seems this is related to property hooks. The assertion occurs because of the following "enter" record.
0107 V12 = FETCH_OBJ_FUNC_ARG (ref) V13 string("content") ; op1(object of class Rowbot\DOM\Element\HTML\HTMLTemplateElement)
>enter Rowbot\DOM\Element\HTML\HTMLTemplateElement::$content::get
0000 T0 = FETCH_OBJ_R THIS string("_content") ; val(object)
Actually, the trace recorder shouldn't continue recording when magic handler is invoked.
For regular __get()
this is done through ZEND_ACC_CALL_VIA_TRAMPOLINE
check and terminating recorder with ZEND_JIT_TRACE_STOP_TRAMPOLINE
.
Something similar should be done for property hooks.
@dstogov Thank you for the hint. Is this what you were suggesting? Since there's no reproducer, I couldn't verify it.
diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h
index ccc86a4834..2007f28e91 100644
--- a/ext/opcache/jit/zend_jit_internal.h
+++ b/ext/opcache/jit/zend_jit_internal.h
@@ -265,6 +265,7 @@ zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key);
_(INNER_LOOP, "inner loop") /* trace it */ \
_(COMPILED_LOOP, "compiled loop") \
_(TRAMPOLINE, "trampoline call") \
+ _(PROP_HOOK_CALL, "property hook call") \
_(BAD_FUNC, "bad function call") \
_(COMPILER_ERROR, "JIT compilation error") \
/* no recoverable error (blacklist immediately) */ \
diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c
index 2a7399c185..e9cdeeab98 100644
--- a/ext/opcache/jit/zend_jit_vm_helpers.c
+++ b/ext/opcache/jit/zend_jit_vm_helpers.c
@@ -503,6 +503,11 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend
/* TODO: Can we continue recording ??? */
return -1;
}
+ /* Function is a property hook. */
+ if (func->common.prop_info) {
+ /* TODO: Can we continue recording ??? */
+ return -1;
+ }
if (func->type == ZEND_INTERNAL_FUNCTION
&& (func->op_array.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE))) {
return -1;
@@ -966,6 +971,12 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
break;
}
+ if (EX(func)->op_array.prop_info) {
+ /* TODO: Can we continue recording ??? */
+ stop = ZEND_JIT_TRACE_STOP_PROP_HOOK_CALL;
+ break;
+ }
+
TRACE_RECORD(ZEND_JIT_TRACE_ENTER,
EX(return_value) != NULL ? ZEND_JIT_TRACE_RETURN_VALUE_USED : 0,
op_array);
@@ -1069,6 +1080,10 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
/* TODO: Can we continue recording ??? */
stop = ZEND_JIT_TRACE_STOP_BAD_FUNC;
break;
+ } else if (EX(call)->func->common.prop_info) {
+ /* TODO: Can we continue recording ??? */
+ stop = ZEND_JIT_TRACE_STOP_PROP_HOOK_CALL;
+ break;
}
func = EX(call)->func;
if (func->type == ZEND_INTERNAL_FUNCTION
@iluuu1994 I tested your patch and it appears to fix the problem for me.
The patch looks right to me. @iluuu1994 could you please merge it.
@dstogov Thank you very much for verifying!
Description
While #15101 is now fixed for me, I am now hitting another assertion
zend_jit_trace_build_tssa: Assertion `&call->func->op_array == op_array'
with the JIT enabled. I was unsuccessful at creating a reduced reproducer for this issue as well, unfortunately.Relevant changed ini settings: opcache.enable_cli=1 opcache.memory_consumption=256 opcache.max_accelerated_files=20000 opcache.jit=1255 opcache.jit_buffer_size=256M
Backtrace
Information about the last complied trace using
-d opcache.jit_debug=0x1ff000
Looking at the trace info, these are the code locations: https://github.com/TRowbotham/PHPDOM/blob/dev/src/Parser/HTML/TreeBuilder.php#L32 https://github.com/TRowbotham/PHPDOM/blob/dev/src/Parser/HTML/InsertionMode/InBodyInsertionMode.php#L55 https://github.com/TRowbotham/PHPDOM/blob/dev/src/Parser/HTML/InsertionMode/InBodyInsertionMode.php#L1589 https://github.com/TRowbotham/PHPDOM/blob/dev/src/Parser/HTML/InsertionMode/AbstractInsertionMode.php#L384 https://github.com/TRowbotham/PHPDOM/blob/dev/src/Parser/HTML/InsertionMode/AbstractInsertionMode.php#L281
I hit this assertion when running
vendor/bin/phpunit tests/dom/nodes/DocumentFragmentGetElementByIdTest.php
PHP Version
master
Operating System
Ubuntu 22.04