-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix JIT for overridden properties with added hooks #17395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
--TEST-- | ||
GH-17376: Child classes may add hooks to plain properties | ||
--FILE-- | ||
<?php | ||
|
||
class A { | ||
public $prop = 1; | ||
} | ||
|
||
class B extends A { | ||
public $prop { | ||
get => 2; | ||
} | ||
} | ||
|
||
function test(A $a) { | ||
var_dump($a->prop); | ||
} | ||
|
||
test(new A); | ||
test(new B); | ||
|
||
?> | ||
--EXPECT-- | ||
int(1) | ||
int(2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14291,6 +14291,29 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, | |
} | ||
} | ||
} else { | ||
/* Child classes may add hooks to property. */ | ||
if (ce_is_instanceof && !(prop_info->flags & ZEND_ACC_FINAL)) { | ||
int prop_info_offset = | ||
(((prop_info->offset - (sizeof(zend_object) - sizeof(zval))) / sizeof(zval)) * sizeof(void*)); | ||
ir_ref prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_object, ce))); | ||
prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(prop_info_ref, offsetof(zend_class_entry, properties_info_table))); | ||
prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(prop_info_ref, prop_info_offset)); | ||
ir_ref is_same_prop_info = ir_EQ(prop_info_ref, ir_CONST_ADDR(prop_info)); | ||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ZEND_JIT_EXIT_TO_VM looks too aggressive. Why can't we record another trace with slow-path JIT-ed code. |
||
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); | ||
if (!exit_addr) { | ||
return 0; | ||
} | ||
ir_GUARD(is_same_prop_info, ir_CONST_ADDR(exit_addr)); | ||
} else { | ||
ir_ref if_same_prop_info = ir_IF(is_same_prop_info); | ||
ir_IF_FALSE_cold(if_same_prop_info); | ||
ir_END_list(slow_inputs); | ||
ir_IF_TRUE(if_same_prop_info); | ||
} | ||
} | ||
|
||
prop_ref = ir_ADD_OFFSET(obj_ref, prop_info->offset); | ||
prop_addr = ZEND_ADDR_REF_ZVAL(prop_ref); | ||
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { | ||
|
@@ -14435,7 +14458,7 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, | |
SET_STACK_REG(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE); | ||
} | ||
|
||
if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || !prop_info) { | ||
if (slow_inputs) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could technically be reverted, but seems more logical. |
||
ir_MERGE_list(slow_inputs); | ||
jit_SET_EX_OPLINE(jit, opline); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should move this to a separate PR, but IMO this should still be fixed.