Skip to content

Do not exit to VM when setting undefined prop in constructor #18576

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

arnaud-lb
Copy link
Member

@arnaud-lb arnaud-lb commented May 16, 2025

JIT'ed ASSIGN_OBJ expressions will exit to VM when the prop is undef. However, in a constructor it's very likely the case. Therefore most traces with new expressions will exit to VM:

<?php

class Foo {
    public function __construct(public int $a) {}
}

for ($i = 0; $i < 100; $i++) {
    new Foo($i);
}
---- TRACE 1 start (loop) $main() test.php:7
0007 T1 = IS_SMALLER CV0($i) int(100) ; op1(int)
0008 ;JMPNZ T1 0002
0002 V1 = NEW 1 string("Foo")
     >init Foo::__construct
0003 SEND_VAR CV0($i) 1 ; op1(int)
0004 DO_FCALL
     >enter Foo::__construct
0000  CV0($a) = RECV 1
0001  ASSIGN_OBJ THIS string("a") ; op3(int) val(undef)
0002  ;OP_DATA CV0($a)
0003  RETURN null
     <back test.php
0005 FREE V1 ; op1(object of class Foo)
0006 PRE_INC CV0($i) ; op1(int)
---- TRACE 1 stop (loop)
---- TRACE 1 compiled

     TRACE 1 exit 3 Foo::__construct() test.php:4
     TRACE 1 exit 3 Foo::__construct() test.php:4
     TRACE 1 exit 3 Foo::__construct() test.php:4
     TRACE 1 exit 3 Foo::__construct() test.php:4
     TRACE 1 exit 3 Foo::__construct() test.php:4
     TRACE 1 exit 3 Foo::__construct() test.php:4
     TRACE 1 exit 3 Foo::__construct() test.php:4
     TRACE 1 exit 3 Foo::__construct() test.php:4
     TRACE 1 exit 3 Foo::__construct() test.php:4
---- EXIT 1/3 blacklisted

Here I ensure that we don't need to exit to VM when it's likely that the prop will be undef.

In the function JIT we compile a slow path to handle such properties, but not in the tracing JIT, assumingly to reduce code size. Here I enable compilation of the slow path in the tracing JIT when it's likely the prop will be undef. Quite conveniently we already record the prop type during tracing, so I use that to make the decision.

This results in a 1.20% wall time improvement on the symfony demo benchmark with 20 warmup requests.

@arnaud-lb arnaud-lb marked this pull request as ready for review May 17, 2025 09:10
Copy link
Member

@nielsdos nielsdos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting observation.
I think this is right, we might be generating more code but the speedup you report seems worth it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants