Skip to content

Conversation

@pull
Copy link

@pull pull bot commented Aug 22, 2025

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.3)

Can you help keep this open source service alive? 💖 Please sponsor : )

alexandre-daubois and others added 9 commits August 22, 2025 16:16
yylen is unsigned int, but len in zend_scan_escape_string() is int, which will
break for string literals >=2GB. yyleng is still limited to 4GB, but we can't
fix this without breaking the ABI.

Partially addresses GH-19542
Closes GH-19545
* PHP-8.3:
  Fix signed int overflow in scanner
* PHP-8.4:
  Fix signed int overflow in scanner
…purposes

Since cbf67e4, the GC needs to find all WeakMaps referencing a weakly
referenced object. Doing so, it treats all ZEND_WEAKREF_TAG_MAP as WeakMap
instances.

However, a ZEND_WEAKREF_TAG_MAP reference may be a bare HashTable when
zend_weakrefs_hash_add() is used.

Introduce a new tag, ZEND_WEAKREF_TAG_BARE_HT, and use this tag when weakly
referencing an object from a bare HashTable. Ignore such references in GC.

Fixes GH-19543
Closes GH-19544

Co-authored-by: Tim Düsterhus <[email protected]>
* PHP-8.3:
  Differenciate WeakMaps from bare HashTables used as weak maps for GC purposes
* PHP-8.4:
  Differenciate WeakMaps from bare HashTables used as weak maps for GC purposes
Introduce the TAILCALL VM, a more efficient variant of the CALL VM:

 * Each opcode handler tailcalls the next opcode handler directly instead of
   returning to the interpreter loop. This eliminates call and interpreter loop
   overhead.
 * Opcode handlers use the preserve_none calling convention to eliminate
   register saving overhead.
 * preserve_none uses non-volatile registers for its first arguments, so
   execute_data and opline are usually kept in these registers and no code is
   required to forward them to the next handlers.

Generated machine code is similar to a direct-threaded VM with register pinning,
like the HYBRID VM.

JIT+TAILCALL VM also benefits from this compared to JIT+CALL VM:

 * JIT uses the registers of the execute_data and opline args as fixed regs,
   eliminating the need to move them in prologue.
 * Traces exit by tailcalling the next handler. No code is needed to forward
   execute_data and opline.
 * No register saving/restoring in epilogue/prologue.

The TAILCALL VM is used when the HYBRID VM is not supported, and the compiler
supports the musttail and preserve_none attributes: The HYBRID VM is used when
compiling with GCC, the TAILCALL VM when compiling with Clang>=19 on x86_64 or
aarch64, and the CALL VM otherwise.

This makes binaries built with Clang>=19 as fast as binaries built with GCC.
Before, these were considerably slower (by 2.8% to 44% depending on benchmark,
and by 5% to 77% before 76d7c61).

Closes GH-17849
Closes GH-18720
@pull pull bot locked and limited conversation to collaborators Aug 22, 2025
@pull pull bot added the ⤵️ pull label Aug 22, 2025
@pull pull bot merged commit 94d0b41 into wudi:master Aug 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants