[php-src] PR #23939: JIT: Fold IS_UNDEF check into dereference of typed property reads for tracing JIT
| From: | ndossche | Date: | Sat, 26 Sep 2026 22:48:15 +0000 |
| Subject: | [php-src] PR #23939: JIT: Fold IS_UNDEF check into dereference of typed property reads for tracing JIT | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-38850@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/23939
Author: ndossche
When the tracing JIT reads a typed property with a known result type into a reg, the value is either
of that type, a reference or IS_UNDEF. Instead of guarding IS_UNDEF separately before making a
decision on the type, exit only if the value is neither of the expected type nor a reference. This
removes a compare and branch from the hot path of, e.g., reads of $this->prop in loops.
Example PHP code:
```php
class Counter {
public int $x = 1;
function sum($n) {
$s = 0;
for ($i = 0; $i < $n; $i++) {
$s += $this->x;
}
return $s;
}
}
var_dump((new Counter)->sum(1000));
```
The loop compiled previously to:
```asm
.L1:
movq (%rdi), %rsi
leaq 8(%rsi), %rdi
.L2:
movq (%rdi), %rsi
movq %rsi, %rdi
addq %rcx, %rdi
jo jit$$trace_exit_5
leaq 1(%rdx), %rdx
movabsq $EG(vm_interrupt), %rcx
movb (%rcx), %cl
testb %cl, %cl
jne jit$$trace_exit_6
movq %rdi, %rcx
.L3:
cmpq %rax, %rdx
jge jit$$trace_exit_3
movq 0x20(%r14), %rsi
leaq 0x28(%rsi), %rdi
movl 0x30(%rsi), %esi
testl %esi, %esi
je jit$$trace_exit_4
cmpl $4, %esi
je .L2
jmp .L1
```
Notice that in
.L3 there's two checks on %esi (the type info): one
for the IS_UNDEF (via testl) and one to check for an int ($4). The new
code moves the check for reference type to the .L1 header and only checks for the int
type in .L3, reducing the code executed in the hot loop:
```asm
.L1:
cmpl $0x30a, %esi
jne jit$$trace_exit_4
movq (%rdi), %rsi
leaq 8(%rsi), %rdi
.L2:
movq (%rdi), %rsi
movq %rsi, %rdi
addq %rcx, %rdi
jo jit$$trace_exit_5
leaq 1(%rdx), %rdx
movabsq $EG(vm_interrupt), %rcx
movb (%rcx), %cl
testb %cl, %cl
jne jit$$trace_exit_6
movq %rdi, %rcx
.L3:
cmpq %rax, %rdx
jge jit$$trace_exit_3
movq 0x20(%r14), %rsi
leaq 0x28(%rsi), %rdi
movl 0x30(%rsi), %esi
cmpl $4, %esi
je .L2
jmp .L1
```