How PHP 8 JIT Compiler Works

This article provides a clear and direct explanation of the Just-In-Time (JIT) compiler introduced in PHP 8. You will learn how the JIT compiler integrates with the Zend VM, how it translates PHP bytecode into native machine code at runtime, and how it impacts the performance of different types of PHP applications.

The Traditional PHP Execution Flow

To understand the JIT compiler, it helps to understand how PHP executed code before PHP 8. PHP is an interpreted language. When a script runs, it goes through a multi-step process:

  1. Lexing and Parsing: The PHP engine reads the human-readable PHP code and converts it into an Abstract Syntax Tree (AST).
  2. Compilation: The engine compiles the AST into Zend opcodes (low-level instructions that the Zend Virtual Machine understands).
  3. Execution: The Zend Virtual Machine (VM) interprets these opcodes and translates them into machine code that the CPU can execute.

To speed this up, PHP uses OPcache. OPcache stores the compiled opcodes in shared memory so that PHP does not have to parse and compile the script on every single web request. However, the Zend VM still has to interpret those cached opcodes every time.

How the JIT Compiler Fits In

The JIT compiler in PHP 8 is implemented as an extension of OPcache. Instead of relying solely on the Zend VM to interpret opcodes, the JIT compiler compiles specific opcodes directly into CPU-specific machine code at runtime.

When the JIT-compiled code needs to run, the CPU executes it directly, completely bypassing the Zend VM interpreter. This reduces the overhead of instruction decoding and execution within the VM.

Tracing JIT vs. Function JIT

PHP 8 offers two main compilation strategies for JIT, which control how the engine decides what code to compile:

1. Function JIT

This approach compiles entire functions into machine code. While straightforward, it is often inefficient because it compiles code blocks that might only run once, leading to high memory usage with minimal performance gains.

2. Tracing JIT (Default)

Tracing JIT is much smarter and is the default setting in PHP 8. It looks for “hot paths” (frequently executed code segments, such as loops or repetitive method calls) during runtime.

Why JIT Doesn’t Make Every PHP App Faster

A common misconception is that PHP 8’s JIT compiler will instantly double the speed of all WordPress sites or web APIs. In reality, JIT has a very specific impact depending on the workload: