Conversation
|
This PR seems to be related with #10782, can it fix it? |
|
@mvorisek I don't think this will fix the mentioned problem. It is related to run_time_cache per closure, this only slightly tweaks the opcodes of the closure. |
024095f to
e7830f3
Compare
|
Does this change improve closure performance? |
|
It seems so. class C {
public function test() {
$c = function () {
for ($i = 0; $i < 100000000; $i++) {
$this->foo();
}
};
$c();
}
private function foo() {}
}
$c = new C();
$c->test();Before: After: But this is highly synthetic, so take it with a grain of salt. I'm not sure whether it improves real-life performance. |
|
I like the patch, and in general everything looks right. Can you investigate this please. (I suppose, JIT have some CLOSURE specific optimization that stopped work after your patch). |
|
This demonstrates the worse JIT code generated for FETCH_DIM_R. <?php
class Foo {
public $a = 42;
public function test() {
return function() {
return $this->a;
};
}
}
$obj = new Foo();
$fn = $obj->test();
for ($i = 0; $i < 100; $i++) {
$fn();
}
?>The degradation is caused by call to It's possible that we have similar degradation for other related instructions. (ASSIGN_OBJ, INIT_METHOD_CALL, etc) It looks like the following extension to the tracer fixes all degradation. May be it should record $this class only for closures. (I'm not sure). diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c
index 7df2cd5b902..4d055ac2ece 100644
--- a/ext/opcache/jit/zend_jit_vm_helpers.c
+++ b/ext/opcache/jit/zend_jit_vm_helpers.c
@@ -692,6 +692,25 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
}
}
op1_type |= flags;
+ } else if (opline->op1_type == IS_UNUSED
+ && (opline->opcode == ZEND_FETCH_OBJ_R
+ || opline->opcode == ZEND_FETCH_OBJ_W
+ || opline->opcode == ZEND_FETCH_OBJ_RW
+ || opline->opcode == ZEND_FETCH_OBJ_IS
+ || opline->opcode == ZEND_FETCH_OBJ_FUNC_ARG
+ || opline->opcode == ZEND_FETCH_OBJ_UNSET
+ || opline->opcode == ZEND_ASSIGN_OBJ
+ || opline->opcode == ZEND_ASSIGN_OBJ_REF
+ || opline->opcode == ZEND_ASSIGN_OBJ_OP
+ || opline->opcode == ZEND_PRE_INC_OBJ
+ || opline->opcode == ZEND_PRE_DEC_OBJ
+ || opline->opcode == ZEND_POST_INC_OBJ
+ || opline->opcode == ZEND_POST_DEC_OBJ
+ || opline->opcode == ZEND_ISSET_ISEMPTY_PROP_OBJ
+ || opline->opcode == ZEND_UNSET_OBJ
+ || opline->opcode == ZEND_INIT_METHOD_CALL
+ || opline->opcode == ZEND_CLONE)) {
+ ce1 = Z_OBJCE(EX(This));
}
if (opline->op2_type & (IS_TMP_VAR|IS_VAR|IS_CV)
&& opline->opcode != ZEND_INSTANCEOF@iluuu1994 Please finalize this. |
e7830f3 to
7135a60
Compare
Non-static closures are guaranteed to have $this. The existing comment highlights this, but fails to handle it correctly.
81df7c5 to
3b8b9f0
Compare
Non-static closures declared in non-static methods are guaranteed to have $this. The existing comment highlights this, but fails to handle it correctly.