phpng-int
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
phpng-int [2014/05/06 14:54] – - IS_CONSTANT_ARRAY from intro bwoebi | phpng-int [2018/01/09 16:34] (current) – fixed typos kelunik | ||
---|---|---|---|
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 17: | Line 21: | ||
</ | </ | ||
- | 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 | + | 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 |
- | 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 | ||
Line 45: | 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 flags are used as modifiers for IS_CONSTANT. Their meaning kept exactly the same as before. | ||
- | Few constants are flags used as modifiers for IS_CONSTANT. Their meaning kept exacly the same as before. | + | * IS_CONSTANT_UNQUALIFIED |
+ | * IS_LEXICAL_VAR | ||
+ | * IS_LEXICAL_REF | ||
+ | * IS_CONSTANT_IN_NAMESPACE | ||
- | The type may be read using Z_TYPE() or Z_TYPE_P() macros, type flags using Z_TYPE_FLAGS() or Z_TYPE_FLAGS_P(), | + | 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 109: | Line 119: | ||
| DOUBLE VALUE (64-bit) | | DOUBLE VALUE (64-bit) | ||
+--------------------------+-------------+-------------+-------------+-------------+ | +--------------------------+-------------+-------------+-------------+-------------+ | ||
- | | UNUSED (32-bit) | + | | UNUSED (32-bit) |
+--------------------------+-------------+-------------+-------------+-------------+ | +--------------------------+-------------+-------------+-------------+-------------+ | ||
| | ||
Line 196: | 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 324: | Line 334: | ||
New implementation assumes, that we store zval structures (not pointers) in arrays and function stack frames. It must not be a problem for arrays because scalar values are going to be just duplicated, and compound values may point to shared reference-couned structures anyway. However it is a problem for local variables (IS_CV), because they may be referenced through stack frame (by index) and through symbol table (by name). Both must point to the same structure. Values of IS_INDIRECT types are just weak pointers to real values. When we lazily create local symbol tables, we store IS_INDIRECT values in symbol tables and initialize them with the pointers to corresponding CV slots. It means that CV access by index became extremely efficient, as we don't need to perform double or even triple dereferences as before. | New implementation assumes, that we store zval structures (not pointers) in arrays and function stack frames. It must not be a problem for arrays because scalar values are going to be just duplicated, and compound values may point to shared reference-couned structures anyway. However it is a problem for local variables (IS_CV), because they may be referenced through stack frame (by index) and through symbol table (by name). Both must point to the same structure. Values of IS_INDIRECT types are just weak pointers to real values. When we lazily create local symbol tables, we store IS_INDIRECT values in symbol tables and initialize them with the pointers to corresponding CV slots. It means that CV access by index became extremely efficient, as we don't need to perform double or even triple dereferences as before. | ||
- | Global symbol | + | Global symbol |
The same concept is used for object properties access. In case dynamic properties table is required it's first initialized with IS_INDIRECT references to predefined object properties slots. | The same concept is used for object properties access. In case dynamic properties table is required it's first initialized with IS_INDIRECT references to predefined object properties slots. | ||
Line 357: | Line 367: | ||
===== VM Changes ===== | ===== VM Changes ===== | ||
- | With new zval implementation IS_TMP_VAR, IS_VAR and IS_CV operands are handled in very similar way. All three operands | + | With new zval implementation IS_TMP_VAR, IS_VAR and IS_CV operands are handled in very similar way. All three operands |
==== Function Stack Frame (zend_execute_data) ==== | ==== Function Stack Frame (zend_execute_data) ==== | ||
Line 415: | Line 425: | ||
[TO BE CONTINUED] | [TO BE CONTINUED] | ||
- |
phpng-int.1399388076.txt.gz · Last modified: 2017/09/22 13:28 (external edit)