-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Omit FETCH_THIS in closures #14181
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
Omit FETCH_THIS in closures #14181
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
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.
Looks Fine!
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.