phpng-int
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
phpng-int [2014/05/05 18:56] – dmitry | phpng-int [2017/09/22 13:28] – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== PHPNG Implementation Details ====== | ||
+ | |||
+ | This page provides technical information about PHPNG internals. The general information about PHPNG might be found at [[phpng]], information for extension maintainers at [[phpng-upgrading]]. | ||
+ | |||
===== Value Representation ===== | ===== Value Representation ===== | ||
- | All values in existing Zend Engine implementation were allocated on heap and they are subject for reference counting and garbage collection. Zend engine mostly | + | All values in existing Zend Engine implementation were allocated on heap and they were subject for reference counting and garbage collection. Zend engine mostly |
- | The new implementation operates by zval structures their selves (not pointers). It stores new zval structures directly on stack, in HashTable buckets, and property slots. It dramatically reduces number of heap allocations/ | + | The new implementation operates by zval structures their selves (not pointers). It stores new zval structures directly on VM stack, in HashTable buckets, and property slots. It dramatically reduces number of heap allocations/ |
- | The new implementation uses more VM stack space (instead of heap), because now it keeps there zval structures instead of pointers. Anyway, the overall memory usage is reduced. In some cases new approach assumes full zval copying instead of copy-on write implemented before, but it doesn' | + | The new implementation uses more VM stack space (instead of heap), because now it keeps there zval structures instead of pointers. Anyway, the overall memory usage is reduced. In some cases new approach assumes full zval copying instead of copy-on-write implemented before, but it doesn' |
==== CELL Format (zval) ==== | ==== CELL Format (zval) ==== | ||
Line 19: | Line 23: | ||
The value cell represented as two 64-bit words. The first word contains actual value (it's defined as a union of possible value types), the second contains type tag and some flags. The type and flags may be accessed together as a single 32-bit world for efficiency. The “unused” space actually may be reused for different purposes when cell are embedded into other structures. (e.g. for hash collision list when the value embedded into HashTable) | The value cell represented as two 64-bit words. The first word contains actual value (it's defined as a union of possible value types), the second contains type tag and some flags. The type and flags may be accessed together as a single 32-bit world for efficiency. The “unused” space actually may be reused for different purposes when cell are embedded into other structures. (e.g. for hash collision list when the value embedded into HashTable) | ||
- | The re-factored engine defines the following data types most of that are well known from the exiting | + | The re-factored engine defines the following data types. Most of them are well known from PHP-5 engine: |
* IS_UNDEF – we use a special type for undefined variables | * IS_UNDEF – we use a special type for undefined variables | ||
Line 27: | Line 31: | ||
* IS_LONG | * IS_LONG | ||
* IS_DOUBLE | * IS_DOUBLE | ||
- | * IS_STRING – interned | + | * IS_STRING – regular |
- | * IS_ARRAY | + | * IS_ARRAY |
* IS_OBJECT | * IS_OBJECT | ||
* IS_RESOURCE | * IS_RESOURCE | ||
- | * IS_REFERENCE – a separate type for references (t'll be explained later) | + | * IS_REFERENCE – a separate type for references (it'll be explained later) |
* IS_CONSTANT – named constant | * IS_CONSTANT – named constant | ||
- | * IS_CONSTANT_ARRAY – array with constants | ||
* IS_CONSTANT_AST – constant expression | * IS_CONSTANT_AST – constant expression | ||
Line 46: | Line 49: | ||
Except for types itself, the engine defines few type flags to uniform handling of different data types with similar behavior. | Except for types itself, the engine defines few type flags to uniform handling of different data types with similar behavior. | ||
- | * IS_TYPE_CONSTANT – the type is a constant (IS_CONSTANT, IS_CONSTANT_ARRAY, IS_CONSTANT_AST) | + | * IS_TYPE_CONSTANT – the type is a constant (IS_CONSTANT, |
- | * IS_TYPE_REFCOUNTED – the type is a subject for reference counting (IS_STRING excluding interned srings, IS_ARRAY, IS_OBJECT, IS_RESOURCE, | + | * IS_TYPE_REFCOUNTED – the type is a subject for reference counting (IS_STRING excluding interned srings, IS_ARRAY |
* IS_TYPE_COLLECTABLE – the type may be a root of unreferenced cycle and it's a subject for Garbage Collection (IS_ARRAY, IS_OBJECT). | * IS_TYPE_COLLECTABLE – the type may be a root of unreferenced cycle and it's a subject for Garbage Collection (IS_ARRAY, IS_OBJECT). | ||
* IS_TYPE_COPYABLE – the type has to be duplicated using zval_copy_ctor() on assignment or copy on write (IS_STRING excluding interned strings, IS_ARRAY) | * IS_TYPE_COPYABLE – the type has to be duplicated using zval_copy_ctor() on assignment or copy on write (IS_STRING excluding interned strings, IS_ARRAY) | ||
+ | * IS_TYPE_IMMUTABLE - the type can't be changed directly, but may be copied on write. Used by immutable arrays to avoid unnecessary array duplication. | ||
- | Few constants | + | Few constants flags are used as modifiers for IS_CONSTANT. Their meaning kept exactly |
- | The type may be read using Z_TYPE() or Z_TYPE_P() macros, type flags using Z_TYPE_FLAGS() or Z_TYPE_FLAGS_P(), | + | * IS_CONSTANT_UNQUALIFIED |
+ | * IS_LEXICAL_VAR | ||
+ | * IS_LEXICAL_REF | ||
+ | * IS_CONSTANT_IN_NAMESPACE | ||
+ | |||
+ | The type of zval may be read using Z_TYPE() or Z_TYPE_P() macros, type flags using Z_TYPE_FLAGS() or Z_TYPE_FLAGS_P(), | ||
==== IS_UNDEF ==== | ==== IS_UNDEF ==== | ||
Line 110: | Line 119: | ||
| DOUBLE VALUE (64-bit) | | DOUBLE VALUE (64-bit) | ||
+--------------------------+-------------+-------------+-------------+-------------+ | +--------------------------+-------------+-------------+-------------+-------------+ | ||
- | | UNUSED (32-bit) | + | | UNUSED (32-bit) |
+--------------------------+-------------+-------------+-------------+-------------+ | +--------------------------+-------------+-------------+-------------+-------------+ | ||
| | ||
Line 197: | Line 206: | ||
+----------------------------------------------------------------------------------+ | +----------------------------------------------------------------------------------+ | ||
| key - pointer to zend_string (NULL for numeric indexes) (64-bit or 32-bit) | | key - pointer to zend_string (NULL for numeric indexes) (64-bit or 32-bit) | ||
- | +----------------------------------------------------------------------------------+ | + | +----------------------------------------------------------------------------------+ |
- | | VALUE (64-bit) | + | | VALUE (64-bit) |
- | +--------------------------+-------------+-------------+-------------+-------------+ | + | +--------------------------+-------------+-------------+-------------+-------------+ |
- | | next- hash collision list| UNUSED | + | | next- hash collision list| UNUSED |
- | +--------------------------+-------------+-------------+-------------+-------------+ | + | +--------------------------+-------------+-------------+-------------+-------------+ |
| | ||
</ | </ | ||
Line 309: | Line 318: | ||
The check if the value is a reference might be done using Z_ISREF() macro, the reference value read using Z_REF() and Z_REFVAL() macros. They may be constructed using ZVAL_REF(), ZVAL_NEW_REF() and ZVAL_NEW_PERSISTENT_REF(). | The check if the value is a reference might be done using Z_ISREF() macro, the reference value read using Z_REF() and Z_REFVAL() macros. They may be constructed using ZVAL_REF(), ZVAL_NEW_REF() and ZVAL_NEW_PERSISTENT_REF(). | ||
- | ==== IS_CONSTANT, IS_CONSTANT_ARRAY | + | ==== IS_CONSTANT and IS_CONSTANT_AST ==== |
- | IS_CONSTANT actually points to zend_string structure, IS_CONSTANT_ARRAY to zend_array. They are handled a bit differently from regular strings and arrays. | + | IS_CONSTANT actually points to zend_string structure. They are handled a bit differently from regular strings and arrays. |
==== IS_INDIRECT ==== | ==== IS_INDIRECT ==== | ||
Line 331: | Line 340: | ||
Also, IS_INDIRECT pointers are used in VM during execution to pass address of variables between opcode handlers. | Also, IS_INDIRECT pointers are used in VM during execution to pass address of variables between opcode handlers. | ||
+ | ==== IS_STR_OFFSET (used internally in VM) ==== | ||
+ | < | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | POINTER to string value (zval*) (64-bit or 32-bit) | ||
+ | +--------------------------+-------------+-------------+-------------+-------------+ | ||
+ | | offset (32-bit) | ||
+ | +--------------------------+-------------+-------------+-------------+-------------+ | ||
+ | | ||
+ | </ | ||
+ | This is another type used only in run-time to pass address of string element between opcodes. | ||
- | [TO BE CONTINUED] | + | ==== IS_PTR (used internally by the Engine) ==== |
+ | < | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | POINTER to internal entity (64-bit or 32-bit) | ||
+ | +--------------------------+-------------+-------------+-------------+-------------+ | ||
+ | | UNUSED (32-bit) | ||
+ | +--------------------------+-------------+-------------+-------------+-------------+ | ||
+ | | ||
+ | </ | ||
+ | This type might be used to reuse the new HashTable implementation for some internal entities, not related to PHP values. (e.g. each zend_class_entry has to keep a HashTable of methods). | ||
+ | |||
+ | |||
+ | ===== VM Changes ===== | ||
+ | |||
+ | With new zval implementation IS_TMP_VAR, IS_VAR and IS_CV operands are handled in very similar way. All three operands jut refer to certain slot of the current function stack frame. Such slots are allocated on segmented VM stack together with frame header (zend_execute_data). The first slots correspond to CV variables and the following to IS_TMP_VAR and IS_VAR. Except for local and temporary variables we also allocate space for syntactically nested function calls and actual parameters, that this function may push. | ||
+ | |||
+ | ==== Function Stack Frame (zend_execute_data) ==== | ||
+ | < | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | opline – instruction pointer (64/ | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | op_array – current function (64/ | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | function_state.function – currently calling function (64/ | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | function_state.arguments – arguments of the currently calling function (64/32-bit| | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | object – current $this | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | scope – static scope of the current function (class where it's defined) | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | called_scope – called scope of the function | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | symbol_table – current symbol table | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | run_time_cache – current run-time cache | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | prev_execute_data – pointer to the previous function call frame | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | return_value – pointer to the zval where this function has return to | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | frame_kind – top or nested, function or eval/ | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | ... FIXME | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | Embedded CELL for the first local variable value (128-bit) | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | ... | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | Embedded CELL for the last local variable value (128-bit) | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | Embedded CELL for the first temporary variable value (128-bit) | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | ... | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | Embedded CELL for the last temporary variable value (128-bit) | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | Syntactically nested call slot (first) FIXME | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | ... FIXME | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | Syntactically nested call slot (last) FIXME | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | Embedded CELL for the first actual argument value (128-bit) | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | ... | | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | | Embedded CELL for the last actual argument value (128-bit) | ||
+ | +----------------------------------------------------------------------------------+ | ||
+ | </ | ||
+ | |||
+ | [TO BE CONTINUED] |
phpng-int.txt · Last modified: 2018/01/09 16:34 by kelunik