php-src/Zend/README.ZEND_VM

109 lines
4.0 KiB
Plaintext
Raw Normal View History

2004-09-10 01:04:12 +08:00
ZEND_VM
=======
ZEND_VM architecture allows specializing opcode handlers according to op_type
fields and using different execution methods (call threading, switch threading
2004-10-28 02:08:56 +08:00
and direct threading). As a result ZE2 got more than 20% speedup on raw PHP
2004-09-10 01:04:12 +08:00
code execution (with specialized executor and direct threading execution
2004-10-28 02:08:56 +08:00
method). As in most PHP applications raw execution speed isn't the limiting
2013-07-13 20:37:04 +08:00
factor but system calls and database calls are, your mileage with this patch
2004-10-28 02:08:56 +08:00
will vary.
2004-09-10 01:04:12 +08:00
2004-10-28 01:58:46 +08:00
Most parts of the old zend_execute.c go into zend_vm_def.h. Here you can
2004-09-10 01:04:12 +08:00
find opcode handlers and helpers. The typical opcode handler template looks
like this:
2004-10-28 01:58:46 +08:00
ZEND_VM_HANDLER(<OPCODE-NUMBER>, <OPCODE>, <OP1_TYPES>, <OP2_TYPES>)
2004-09-10 01:04:12 +08:00
{
<HANDLER'S CODE>
}
2004-10-28 01:58:46 +08:00
<OPCODE-NUMBER> is a opcode number (0, 1, ...)
2004-09-10 01:04:12 +08:00
<OPCODE> is an opcode name (ZEN_NOP, ZEND_ADD, :)
<OP1_TYPES> & <OP2_TYPES> are masks for allowed operand op_types. Specializer
2004-10-28 01:58:46 +08:00
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.
2004-09-10 01:04:12 +08:00
<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
2004-10-28 02:08:56 +08:00
ZEND_VM_NEXT_OPCODE()
2004-09-10 01:04:12 +08:00
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>)
2004-10-28 01:58:46 +08:00
Executor's helpers can be defined without parameters or with one parameter.
This is done with the following constructs:
2004-09-10 01:04:12 +08:00
2004-10-28 01:58:46 +08:00
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>
}
Executor's code is generated by 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
different opcode threading model using --with-vm-kind=CALL|SWITCH|GOTO. You can
disable opcode specialization using --without-specializer. You can include or
exclude old executor together with specialized one using --without-old-executor.
At last you can debug executor using original zend_vm_def.h or generated file
zend_vm_execute.h. Debugging with original file requires --with-lines
2004-10-28 01:58:46 +08:00
option. By default ZE2 uses the following command to generate executor:
2004-09-10 01:04:12 +08:00
$ php zend_vm_gen.php --with-vm-kind=CALL
Zend Engine II currently includes two executors during the build process, one
is the specialized version and the other is the old one non-specialized with
function handlers. By default Zend Engine II uses the specialized one but you
can switch to the old executor at runtime by calling zend_vm_use_old_executor().
2005-08-03 21:29:00 +08:00