Skip to content

Files

Latest commit

2a859ab · Mar 13, 2025

History

History

Zend

Folders and files

NameName
Last commit message
Last commit date

parent directory

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

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