Skip to content

Files

Latest commit

eb65ec4 · Jul 21, 2025

History

History
This branch is 8 commits ahead of, 786 commits behind php/php-src:master.

Zend

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Jul 13, 2025
Apr 21, 2025
Jul 21, 2025
Oct 13, 2018
Jun 24, 2024
Feb 8, 2022
Jul 14, 2025
Feb 3, 2020
Feb 3, 2020
Feb 12, 2025
Sep 24, 2024
Jul 17, 2025
Jul 17, 2025
Jun 20, 2025
Jun 19, 2024
Aug 22, 2022
Sep 14, 2023
Jul 7, 2025
Jun 24, 2025
May 30, 2024
May 30, 2024
Apr 29, 2025
Jun 5, 2025
Apr 29, 2025
Apr 29, 2025
Jan 26, 2025
Jan 16, 2023
Jul 17, 2025
May 20, 2024
Jul 17, 2025
Jul 17, 2025
Jan 26, 2025
Jan 20, 2025
Jul 21, 2025
May 20, 2024
Jul 21, 2025
Jul 21, 2025
Jul 17, 2025
Jul 4, 2025
Jan 15, 2025
Jul 7, 2025
Jul 7, 2025
Jun 5, 2025
Jul 15, 2025
Aug 9, 2024
May 24, 2025
Apr 26, 2021
Jun 4, 2021
Jan 30, 2019
Jun 4, 2021
Apr 4, 2025
Sep 17, 2024
Mar 17, 2021
Feb 25, 2024
Sep 18, 2024
Jul 9, 2025
Jul 7, 2025
Feb 8, 2024
Sep 30, 2024
Jul 9, 2025
Apr 29, 2025
Jul 9, 2025
Jan 13, 2025
Sep 24, 2024
Aug 28, 2024
Jul 2, 2024
Jul 19, 2021
Aug 24, 2024
Jan 16, 2023
Sep 24, 2024
Feb 6, 2024
Jun 15, 2024
Mar 21, 2025
Feb 2, 2025
Jun 14, 2024
Aug 28, 2020
Oct 2, 2024
Oct 2, 2024
May 21, 2024
Sep 3, 2024
Jul 9, 2025
May 20, 2024
Apr 24, 2025
Mar 18, 2025
Jul 14, 2024
May 20, 2024
Dec 10, 2024
Feb 5, 2025
Jul 21, 2025
Apr 5, 2025
Feb 5, 2025
Feb 5, 2025
Jul 4, 2025
May 20, 2024
Jul 7, 2025
Mar 30, 2025
Jan 16, 2023
Jul 20, 2021
Sep 3, 2024
Jul 17, 2025
May 20, 2024
Jul 11, 2025
May 20, 2024
Jul 13, 2025
Jul 3, 2025
Jul 3, 2025
Oct 29, 2023
Apr 20, 2023
Jul 16, 2025
May 20, 2024
Jan 16, 2023
Feb 24, 2025
Aug 20, 2024
Oct 24, 2024
Sep 8, 2022
Sep 24, 2024
Jan 10, 2024
May 20, 2024
Feb 14, 2025
Jul 17, 2025
Jul 17, 2025
Jul 17, 2025
Jul 17, 2025
Jun 18, 2025
Jul 7, 2025
Jun 15, 2024
Jun 15, 2024
Jul 15, 2025
Jul 1, 2025
Jun 24, 2025
Jul 20, 2025
Dec 18, 2024
Jul 14, 2024
Jan 16, 2023
May 20, 2024
Feb 3, 2019
May 22, 2024
May 20, 2024
May 16, 2025
Mar 27, 2025
Jun 10, 2024
May 20, 2024
Mar 27, 2025
Jan 16, 2023
Jan 16, 2023
May 20, 2024
Feb 21, 2023
May 20, 2024
Jan 16, 2023
May 20, 2024
Jun 24, 2025
Jul 15, 2025
Nov 8, 2024
Apr 23, 2024
Sep 8, 2024
Sep 4, 2024
May 20, 2024
Nov 2, 2023
Apr 24, 2025
Jan 30, 2025
Jan 30, 2025
Sep 24, 2024
Aug 23, 2024
Nov 29, 2024
May 20, 2024
Jul 17, 2025
Jul 17, 2025
Jul 10, 2025
Jun 9, 2025
May 19, 2025
Apr 29, 2025
Apr 29, 2025
Nov 3, 2021
Jun 9, 2020
Nov 3, 2021
Oct 15, 2024
Oct 14, 2024
Jul 20, 2021
Aug 24, 2024

README.md

Zend Engine

Zend memory manager

General

The goal of the new memory manager (available since PHP 5.2) is to reduce memory allocation overhead and speedup memory management.

Debugging

Normal:

sapi/cli/php -r 'leak();'

Zend MM disabled:

USE_ZEND_ALLOC=0 valgrind --leak-check=full sapi/cli/php -r 'leak();'

Shared extensions

Since PHP 5.3.11 it is possible to prevent shared extensions from unloading so that valgrind can correctly track the memory leaks in shared extensions. For this there is the ZEND_DONT_UNLOAD_MODULES environment variable. If set, then DL_UNLOAD() is skipped during the shutdown of shared extensions.

ZEND_VM

ZEND_VM architecture allows specializing opcode handlers according to op_type fields and using different execution methods (call threading, switch threading and direct threading). As a result ZE2 got more than 20% speedup on raw PHP code execution (with specialized executor and direct threading execution method). As in most PHP applications raw execution speed isn't the limiting factor but system calls and database calls are, your mileage with this patch will vary.

Most parts of the old zend_execute.c go into zend_vm_def.h. Here you can find opcode handlers and helpers. The typical opcode handler template looks like this:

ZEND_VM_HANDLER(<OPCODE-NUMBER>, <OPCODE>, <OP1_TYPES>, <OP2_TYPES>)
{
    <HANDLER'S CODE>
}

<OPCODE-NUMBER> is a opcode number (0, 1, ...) <OPCODE> is an opcode name (ZEN_NOP, ZEND_ADD, :) <OP1_TYPES> and <OP2_TYPES> are masks for allowed operand op_types. Specializer will generate code only for defined combination of types. You can use any combination of the following op_types UNUSED, CONST, VAR, TMP and CV also you can use ANY mask to disable specialization according operand's op_type. <HANDLER'S CODE> is a handler's code itself. For most handlers it stills the same as in old zend_execute.c, but now it uses macros to access opcode operands and some internal executor data.

You can see the conformity of new macros to old code in the following list:

EXECUTE_DATA
    execute_data
ZEND_VM_DISPATCH_TO_HANDLER(<OP>)
    return <OP>_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
ZEND_VM_DISPATCH_TO_HELPER(<NAME>)
    return <NAME>(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
ZEND_VM_DISPATCH_TO_HELPER_EX(<NAME>,<PARAM>,<VAL>)
    return <NAME>(<VAL>, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
ZEND_VM_CONTINUE()
    return 0
ZEND_VM_NEXT_OPCODE()
    NEXT_OPCODE()
ZEND_VM_SET_OPCODE(<TARGET>
    SET_OPCODE(<TARGET>
ZEND_VM_INC_OPCODE()
    INC_OPCOD()
ZEND_VM_RETURN_FROM_EXECUTE_LOOP()
    RETURN_FROM_EXECUTE_LOOP()
ZEND_VM_C_LABEL(<LABEL>):
    <LABEL>:
ZEND_VM_C_GOTO(<LABEL>)
    goto <LABEL>
OP<X>_TYPE
    opline->op<X>.op_type
GET_OP<X>_ZVAL_PTR(<TYPE>)
    get_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
GET_OP<X>_ZVAL_PTR_PTR(<TYPE>)
    get_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
GET_OP<X>_OBJ_ZVAL_PTR(<TYPE>)
    get_obj_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
GET_OP<X>_OBJ_ZVAL_PTR_PTR(<TYPE>)
    get_obj_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
IS_OP<X>_TMP_FREE()
    IS_TMP_FREE(free_op<X>)
FREE_OP<X>()
    FREE_OP(free_op<X>)
FREE_OP<X>_IF_VAR()
    FREE_VAR(free_op<X>)
FREE_OP<X>_VAR_PTR()
    FREE_VAR_PTR(free_op<X>)

Executor's helpers can be defined without parameters or with one parameter. This is done with the following constructs:

ZEND_VM_HELPER(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>)
{
    <HELPER'S CODE>
}

ZEND_VM_HELPER_EX(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>, <PARAM_SPEC>)
{
    <HELPER'S CODE>
}

The executors code is generated by the PHP script zend_vm_gen.php. It uses zend_vm_def.h and zend_vm_execute.skl as input and produces zend_vm_opcodes.h and zend_vm_execute.h. The first file is a list of opcode definitions. It is included from zend_compile.h. The second one is an executor code itself. It is included from zend_execute.c.

zend_vm_gen.php can produce different kind of executors. You can select a different opcode threading model using --with-vm-kind=CALL|SWITCH|GOTO|HYBRID. You can disable opcode specialization using --without-specializer. At last you can debug the executor using the original zend_vm_def.h or the generated zend_vm_execute.h file. Debugging with the original file requires the --with-lines option. By default, Zend Engine uses the following command to generate the executor:

# Default VM kind is HYBRID
php zend_vm_gen.php --with-vm-kind=HYBRID