Zend Engine изнутри Дмитрий Стогов. Немного истории Zend Engine была разработана в качестве ядра для PHP 4 Andi Gutmans и Zeev Suraski в 1999 PHP 5.0.

Презентация:



Advertisements
Похожие презентации
1 A + B Операнд 1Операнд 2 Оператор Что такое выражение (expression) ? Что такое инструкция (statement) ? Операторы int max = (a > b) ? a : b;
Advertisements

Язык C++ Лекция 2. Недостатки enumов Засорение namespaceа, в котором находится enum Соответственно, члены enumа должны иметь уникальный префикс.
Unit II Constructor Cont… Destructor Default constructor.
Data Types in C. A Data Type A data type is –A set of values AND –A set of operations on those values A data type is used to –Identify the type of a variable.
Функции с переменным числом аргументов private static int Sum(int a, int b) { return a + b; } static void Main() { int sum = Sum(1, 2); } 1 Функции.
PHP как язык программированияPHP как язык программирования.
Test 9 Вопрос 1. public class A { private String runNow() { return "High"; } static class B extends A { public String runNow() { return "Low"; } } public.
Test 10 Вопрос 1. public class Test implements Iterator { // 1 private List list = new ArrayList (); // 2 public void addList(T... ts) { Collections.addAll(list,
Java Java java ISS, Wuhan University Nov., Java Java java Java Java Java ……
Преобразование типов Макаревич Л. Г.. Операция приведения типов Тип ( выражение ) Тип ( выражение ) (тип) выражение (тип) выражение int a = 5; float b.
Object-Oriented Programming Ramzi Saifan Program Control Slides adapted from Steven Roehrig.
Arrays Dr. Ramzi Saifan Slides adapted from Prof. Steven Roehrig.
1/27 Chapter 9: Template Functions And Template Classes.
1. Классы ООП 1.Наследование 2.Инкапсуляция 3.Полиморфизм.
Статический анализатор для языка ECMA Script 4 Власов В. А. Мат.-мех. Ф-т.
Class Date { private int year = 0; private int month = 0; private int day = 0; public void SetDate (int y, int m, int d) { year = y; month = m; day = d;
Test 20 Вопрос 1. public class Main { public static void var(Integer x, int y){ System.out.println("Integer int"); } public static void var(Object... x)
Test 14 Вопрос 1. class Main { public void method() { static class One { public One() { System.out.println("From one"); } } public static void main(String...
PL/SQL Хранимые процедуры и функции. Процедуры [CREATE [OR REPLACE]] PROCEDURE procedure_name[(parameter[, parameter]...)] {IS | AS} [local declarations]
Test 8 Вопрос 1. class Class1 { Class1(int i) { System.out.println("Class1(int)"); } public class Class2 extends Class1 { Class2(double d) { // 1 this((int)
Транксрипт:

Zend Engine изнутри Дмитрий Стогов

Немного истории Zend Engine была разработана в качестве ядра для PHP 4 Andi Gutmans и Zeev Suraski в 1999 PHP 5.0 основан на Zend Engine 2 с новой объектной моделью PHP 5.1 основан на Zend Engine 2.1 со специализированной VM PHP 5.2 основан на Zend Engine 2.2 с новым менеджером памяти PHP 5.3 основан на Zend Engine 2.3 которая включает большинство улучшений и нововведений из PHP6, за исключением Unicode, (namespace-ы, сборщик мусора, LSB, оператор goto, ленивая инициализация таблиц символов, новый сканнер основанный на re2c) PHP 6 основан на Zend Engine 3 с поддержкой Unicode

Подсистемы ZE Менеджер памяти API для доступа к внутренним структурам данных Компилятор PHP Виртуальная машина PHP API для ресурсов (файлы, DB коннекшены) API для внешних расширений PHP Набор внутренних функций Сборщик мусора (5.3)

Стадии работы PHP

Thread Safe Resource Manager non-ZTS-build (single-thread) ZTS-build (thread-safe) Каждый thread работает со своими глобальными данными ZE использует compiler_globals (CG) и executor_globals (EG) Любое расширение PHP может определить свои глобальные данные, которые должны быть уникальными для разных thread-ов

TSRM макросы void some_function(void) { process(EG(symbol_table)); // compilation error }

TSRM макросы void some_function(void) { int some_local_variable; TSRMLS_FETCH(); process(EG(symbol_table)); } void some_function(TSRMLS_D) { process(EG(symbol_table)); } some_function(TSRMLS_C); void some_function(int some_paremeter TSRMLS_DC) { process(EG(symbol_table)); } some_function(0 TSRMLS_CC);

Менеджер памяти emalloc() efree() erealloc() estrdup() estrndup() ecalloc() $ USE_ZEND_ALLOC=0 valgrind php test.php

Значения (zval-коетейнер) typedef struct _zval_struct { zend_uchar type; zvalue_value value; zend_uchar is_ref; zebd_uint refcount; } zval;

Значения (zval-коетейнер) typedef struct _zval_struct { zend_uchar type; zvalue_value value; zend_uchar is_ref; zebd_uint refcount; } zval; IS_NULL IS_LONG IS_DOUBLE IS_BOOL IS_ARRAY IS_OBJECT IS_STRING IS_RESOURCE IS_CONSTANT IS_CONSTANT_ARRAY

Значения (zval-коетейнер) typedef struct _zval_struct { zend_uchar type; zvalue_value value; zend_uchar is_ref; zebd_uint refcount; } zval; typedef union _zvalue_value { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; zend_object_value obj; } zvalue_value;

Ссылки

Присваивание и копирование при записи

Компилятор Основан на flex/bison based (основан на re2c/bison начиная с 5.3) Однопроходная компиляция (на самом деле два прохода) – AST не создается – Прямая компиляция в байт-кодVM – Быстрая компиляция – Оптимизация практически не выполняется

Глобальные данные компилятора (CG) struct _zend_compiler_globals { … HashTable *function_table; HashTable *class_table; zend_class_entry *active_class_entry; zend_op_array *active_op_array; … }; CG(function_table)

Функции PHP (op_array) typedef struct _zend_op_array { zend_uchar type; char *function_name; zend_class_entry *scope; zend_uint fn_flags; zend_op *opcodes; zend_compiled_variables *vars; zend_uint last, lat_var, T; HashTable *static_variables; … } zend_op_array;

Инструкции VM (zend_op) typedef struct _zend_op { zend_uchar opcode; ulong extended_value; znode op1; znode op2; znode result; uint lineno; opcode_handler_t handler; } zend_op;

Инструкции VM (zend_op) typedef struct _zend_op { zend_uchar opcode; ulong extended_value; znode op1; znode op2; znode result; uint lineno; opcode_handler_t handler; } zend_op; ZEND_NOP ZEND_ADD ZEND_SUB ZEND_IS_EQUAL ZEND_JMP ZEND_JMPZ ZEND_ASSIGN ZEND_DO_FCALL ZEND_RETURN ~150 opcodes in zend_vm_opcodes.h

Инструкции VM (zend_op) typedef struct _zend_op { zend_uchar opcode; ulong extended_value; znode op1; znode op2; znode result; uint lineno; opcode_handler_t handler; } zend_op; typedef struct _znode { int op_type; union { zval constant; zend_uint var; zend_uint opline_num; zend_op *jmp_addr; struct { zend_uint var; zend_uint type; } EA; } u; } znode;

Операнды (znode) typedef struct _znode { int op_type; union { zval constant; zend_uint var; zend_uint opline_num; zend_op *jmp_addr; struct { zend_uint var; zend_uint type; } EA; } u; } znode; IS_CONST IS_CV IS_TMP_VAR IS_VAR IS_UNUSED

Пример компиляции (5.0) // FETCH_WC(a)-> V(0) // ASSIGNV(0), C(Hello) // FETCH_WC(b)-> V(1) // ASSIGNV(1), C(World) // FETCH_RC(a)-> V(2) // CONCATV(2), C( )-> T(3) // FETCH_RC(b)-> V(4) // CONCATT(3), V(4)-> T(5) // ECHOT(5) // RETURNC(NULL)

Пример компиляции (5.1) // // ASSIGNCV(0)[a], C(Hello) // // ASSIGNCV(1)[b], C(World) // // CONCATCV(0)[a], C( )-> T(0) // CONCATT(0), CV(1)[b]-> T(1) // ECHOT(1) // // RETURNC(NULL)

Глобальные данные VM (EG) struct _zend_executor_globals { … HashTable *active_symbol_table; HashTable symbol_table;// $GLOBALS[] HashTable *function_table; HashTable *class_table; HashTable *zend_constants; zval *This; zend_class_entry *scope; zend_op_array *active_op_array; zend_op **opline_ptr; struct _zend_execute_data *current_execute_data; … }; EG(symbol_table)

Switch-threaded Executor (4.*) void execute(zend_op_array *op_array TSRMLS_DC) { zend_execute_data execute_data; // initialization EX(opline) = op_array->opcodes; while (1) { switch (EX(opline)->opcode) { … case ZEND_RETURN; … return; }

Call-threaded Executor (5.*) void execute(zend_op_array *op_array TSRMLS_DC) { zend_execute_data execute_data; // initialization EX(opline) = op_array->opcodes; while (1) { if (EX(opline)->handler(&execute_data TSRMLS_CC)) { return; }

Call-threaded Executor (5.0) int zend_concat_handler(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); concat_function(&EX_T(opline->result.u.var).tmp_var, get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R), get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R)); FREE_OP1(EX(Ts), &opline->op1, EG(free_op1)); FREE_OP2(EX(Ts), &opline->op2, EG(free_op2)); EX(opline)++; return 0; }

Специализация в VM (5.1) ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) { zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; concat_function(&EX_T(opline->result.u.var).tmp_var, GET_OP1_ZVAL_PTR(BP_VAR_R), GET_OP2_ZVAL_PTR(BP_VAR_R)); FREE_OP1(); FREE_OP2(); EX(opline)++; return 0; }

Специализация в VM (5.1) int ZEND_CONCAT_SPEC_CV_CONST_HANDLER( ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); concat_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R), &opline->op2.u.constant); EX(opline)++; return 0; }

Классы typrdef struct _zend_class_entry { char type; char *name; zend_class_entry *parent; zend_uint ce_flags; HashTable function_table; HashTable default_properties; HashTable properties_info; HashTable *static_members; HashTable constants_table; zend_class_entry **interfaces; … } zend_class_entry;

Объекты typedef struct _zend_object_value { zend_uint handle;//Z_OBJ_HANDLE(zval) zend_object_handlers *handlers;//Z_OBJ_HT(zval) } zend_object_value; typedef struct _zend_object { zend_class_entry *ce;//Z_OBJCE(zval) HashTable *properties;//Z_OBJPROP(zval) } zend_object;

Вопросы?