Skip to content

Commit 256100a

Browse files
committed
[ci skip] Join Zend engine docs-alike files to readme
1 parent 29bff93 commit 256100a

File tree

3 files changed

+139
-129
lines changed

3 files changed

+139
-129
lines changed

Zend/README.ZEND_MM

Lines changed: 0 additions & 27 deletions
This file was deleted.

Zend/README.ZEND_VM

Lines changed: 0 additions & 102 deletions
This file was deleted.

Zend/README.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Zend Engine
2+
3+
## Zend memory manager
4+
5+
### General
6+
7+
The goal of the new memory manager (available since PHP 5.2) is to reduce memory
8+
allocation overhead and speedup memory management.
9+
10+
### Debugging
11+
12+
Normal:
13+
14+
```bash
15+
sapi/cli/php -r 'leak();'
16+
```
17+
18+
Zend MM disabled:
19+
20+
```bash
21+
USE_ZEND_ALLOC=0 valgrind --leak-check=full sapi/cli/php -r 'leak();'
22+
```
23+
24+
### Shared extensions
25+
26+
Since PHP 5.3.11 it is possible to prevent shared extensions from unloading so
27+
that valgrind can correctly track the memory leaks in shared extensions. For
28+
this there is the `ZEND_DONT_UNLOAD_MODULES` environment variable. If set, then
29+
`DL_UNLOAD()` is skipped during the shutdown of shared extensions.
30+
31+
## ZEND_VM
32+
33+
`ZEND_VM` architecture allows specializing opcode handlers according to
34+
`op_type` fields and using different execution methods (call threading, switch
35+
threading and direct threading). As a result ZE2 got more than 20% speedup on
36+
raw PHP code execution (with specialized executor and direct threading execution
37+
method). As in most PHP applications raw execution speed isn't the limiting
38+
factor but system calls and database calls are, your mileage with this patch
39+
will vary.
40+
41+
Most parts of the old zend_execute.c go into `zend_vm_def.h`. Here you can find
42+
opcode handlers and helpers. The typical opcode handler template looks like
43+
this:
44+
45+
```c
46+
ZEND_VM_HANDLER(<OPCODE-NUMBER>, <OPCODE>, <OP1_TYPES>, <OP2_TYPES>)
47+
{
48+
<HANDLER'S CODE>
49+
}
50+
```
51+
52+
`<OPCODE-NUMBER>` is a opcode number (0, 1, ...)
53+
`<OPCODE>` is an opcode name (ZEN_NOP, ZEND_ADD, :)
54+
`<OP1_TYPES>` and `<OP2_TYPES>` are masks for allowed operand op_types.
55+
Specializer will generate code only for defined combination of types. You can
56+
use any combination of the following op_types UNUSED, CONST, VAR, TMP and CV
57+
also you can use ANY mask to disable specialization according operand's op_type.
58+
`<HANDLER'S CODE>` is a handler's code itself. For most handlers it stills the
59+
same as in old `zend_execute.c`, but now it uses macros to access opcode
60+
operands and some internal executor data.
61+
62+
You can see the conformity of new macros to old code in the following list:
63+
64+
```c
65+
EXECUTE_DATA
66+
execute_data
67+
ZEND_VM_DISPATCH_TO_HANDLER(<OP>)
68+
return <OP>_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
69+
ZEND_VM_DISPATCH_TO_HELPER(<NAME>)
70+
return <NAME>(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
71+
ZEND_VM_DISPATCH_TO_HELPER_EX(<NAME>,<PARAM>,<VAL>)
72+
return <NAME>(<VAL>, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
73+
ZEND_VM_CONTINUE()
74+
return 0
75+
ZEND_VM_NEXT_OPCODE()
76+
NEXT_OPCODE()
77+
ZEND_VM_SET_OPCODE(<TARGET>
78+
SET_OPCODE(<TARGET>
79+
ZEND_VM_INC_OPCODE()
80+
INC_OPCOD()
81+
ZEND_VM_RETURN_FROM_EXECUTE_LOOP()
82+
RETURN_FROM_EXECUTE_LOOP()
83+
ZEND_VM_C_LABEL(<LABEL>):
84+
<LABEL>:
85+
ZEND_VM_C_GOTO(<LABEL>)
86+
goto <LABEL>
87+
OP<X>_TYPE
88+
opline->op<X>.op_type
89+
GET_OP<X>_ZVAL_PTR(<TYPE>)
90+
get_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
91+
GET_OP<X>_ZVAL_PTR_PTR(<TYPE>)
92+
get_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
93+
GET_OP<X>_OBJ_ZVAL_PTR(<TYPE>)
94+
get_obj_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
95+
GET_OP<X>_OBJ_ZVAL_PTR_PTR(<TYPE>)
96+
get_obj_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
97+
IS_OP<X>_TMP_FREE()
98+
IS_TMP_FREE(free_op<X>)
99+
FREE_OP<X>()
100+
FREE_OP(free_op<X>)
101+
FREE_OP<X>_IF_VAR()
102+
FREE_VAR(free_op<X>)
103+
FREE_OP<X>_VAR_PTR()
104+
FREE_VAR_PTR(free_op<X>)
105+
```
106+
107+
Executor's helpers can be defined without parameters or with one parameter. This
108+
is done with the following constructs:
109+
110+
```c
111+
ZEND_VM_HELPER(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>)
112+
{
113+
<HELPER'S CODE>
114+
}
115+
116+
ZEND_VM_HELPER_EX(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>, <PARAM_SPEC>)
117+
{
118+
<HELPER'S CODE>
119+
}
120+
```
121+
122+
Executor's code is generated by PHP script zend_vm_gen.php it uses
123+
`zend_vm_def.h` and `zend_vm_execute.skl` as input and produces
124+
`zend_vm_opcodes.h` and `zend_vm_execute.h`. The first file is a list of opcode
125+
definitions. It is included from `zend_compile.h`. The second one is an executor
126+
code itself. It is included from `zend_execute.c`.
127+
128+
`zend_vm_gen.php` can produce different kind of executors. You can select
129+
different opcode threading model using `--with-vm-kind=CALL|SWITCH|GOTO`. You
130+
can disable opcode specialization using `--without-specializer`. You can include
131+
or exclude old executor together with specialized one using
132+
`--without-old-executor`. At last you can debug executor using original
133+
`zend_vm_def.h` or generated file `zend_vm_execute.h`. Debugging with original
134+
file requires `--with-lines` option. By default ZE2 uses the following command
135+
to generate executor:
136+
137+
```bash
138+
php zend_vm_gen.php --with-vm-kind=CALL
139+
```

0 commit comments

Comments
 (0)