Annotation of embedaddon/php/Zend/README.ZEND_VM, revision 1.1

1.1     ! misho       1: ZEND_VM
        !             2: =======
        !             3: 
        !             4: ZEND_VM architecture allows specializing opcode handlers according to op_type
        !             5: fields and using different execution methods (call threading, switch threading
        !             6: and direct threading). As a result ZE2 got more than 20% speedup on raw PHP
        !             7: code execution (with specialized executor and direct threading execution
        !             8: method). As in most PHP applications raw execution speed isn't the limiting
        !             9: factor but system calls and database callls are, your mileage with this patch
        !            10: will vary.
        !            11: 
        !            12: Most parts of the old zend_execute.c go into zend_vm_def.h. Here you can
        !            13: find opcode handlers and helpers. The typical opcode handler template looks
        !            14: like this:
        !            15: 
        !            16: ZEND_VM_HANDLER(<OPCODE-NUMBER>, <OPCODE>, <OP1_TYPES>, <OP2_TYPES>)
        !            17: {
        !            18:        <HANDLER'S CODE>
        !            19: }
        !            20: 
        !            21: <OPCODE-NUMBER> is a opcode number (0, 1, ...)
        !            22: <OPCODE> is an opcode name (ZEN_NOP, ZEND_ADD, :)
        !            23: <OP1_TYPES> & <OP2_TYPES> are masks for allowed operand op_types. Specializer
        !            24: will generate code only for defined combination of types. You can use any 
        !            25: combination of the following op_types UNUSED, CONST, VAR, TMP and  CV also
        !            26: you can use ANY mask to disable specialization according operand's op_type.
        !            27: <HANDLER'S CODE> is a handler's code itself. For most handlers it stills the
        !            28: same as in old zend_execute.c, but now it uses macros to access opcode operands
        !            29: and some internal executor data.
        !            30: 
        !            31: You can see the conformity of new macros to old code in the following list:
        !            32: 
        !            33: EXECUTE_DATA
        !            34:        execute_data
        !            35: ZEND_VM_DISPATCH_TO_HANDLER(<OP>)
        !            36:        return <OP>_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
        !            37: ZEND_VM_DISPATCH_TO_HELPER(<NAME>) 
        !            38:        return <NAME>(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
        !            39: ZEND_VM_DISPATCH_TO_HELPER_EX(<NAME>,<PARAM>,<VAL>) 
        !            40:        return <NAME>(<VAL>, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
        !            41: ZEND_VM_CONTINUE()
        !            42:        return 0
        !            43: ZEND_VM_NEXT_OPCODE()
        !            44:        NEXT_OPCODE()
        !            45: ZEND_VM_SET_OPCODE(<TARGET>
        !            46:        SET_OPCODE(<TARGET>
        !            47: ZEND_VM_INC_OPCODE()
        !            48:        INC_OPCOD()
        !            49: ZEND_VM_RETURN_FROM_EXECUTE_LOOP()
        !            50:        RETURN_FROM_EXECUTE_LOOP()
        !            51: ZEND_VM_C_LABEL(<LABEL>):
        !            52:        <LABEL>:
        !            53: ZEND_VM_C_GOTO(<LABEL>)
        !            54:        goto <LABEL>
        !            55: OP<X>_TYPE
        !            56:        opline->op<X>.op_type
        !            57: GET_OP<X>_ZVAL_PTR(<TYPE>)
        !            58:        get_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
        !            59: GET_OP<X>_ZVAL_PTR_PTR(<TYPE>)
        !            60:        get_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
        !            61: GET_OP<X>_OBJ_ZVAL_PTR(<TYPE>)
        !            62:        get_obj_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
        !            63: GET_OP<X>_OBJ_ZVAL_PTR_PTR(<TYPE>)
        !            64:        get_obj_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
        !            65: IS_OP<X>_TMP_FREE()
        !            66:        IS_TMP_FREE(free_op<X>)
        !            67: FREE_OP<X>()
        !            68:        FREE_OP(free_op<X>)
        !            69: FREE_OP<X>_IF_VAR()
        !            70:        FREE_VAR(free_op<X>)
        !            71: FREE_OP<X>_VAR_PTR()
        !            72:        FREE_VAR_PTR(free_op<X>)
        !            73: 
        !            74: 
        !            75: Executor's helpers can be defined without parameters or with one parameter. 
        !            76: This is done with the following constructs:
        !            77: 
        !            78: ZEND_VM_HELPER(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>)
        !            79: {
        !            80:        <HELPER'S CODE>
        !            81: }
        !            82: 
        !            83: ZEND_VM_HELPER_EX(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>, <PARAM_SPEC>)
        !            84: {
        !            85:        <HELPER'S CODE>
        !            86: }
        !            87: 
        !            88: Executor's code is generated by PHP script zend_vm_gen.php it uses zend_vm_def.h
        !            89: and zend_vm_execute.skl as input and produces zend_vm_opcodes.h and 
        !            90: zend_vm_execute.h. The first file is a list of opcode definitions. It is 
        !            91: included from zend_compile.h. The second one is an executor code itself. It is
        !            92: included from zend_execute.c.
        !            93: 
        !            94: zend_vm_gen.php can produce different kind of executors. You can select 
        !            95: different opcode threading model using --with-vm-kind=CALL|SWITCH|GOTO. You can 
        !            96: disable opcode specialization using --without-specializer. You can include or
        !            97: exclude old executor together with specialized one using --without-old-executor.
        !            98: At last you can debug executor using original zend_vm_def.h or generated file
        !            99: zend_vm_execute.h. Debugging with original file requires --with-lines
        !           100: option. By default ZE2 uses the following command to generate executor:
        !           101: 
        !           102: $ php zend_vm_gen.php --with-vm-kind=CALL
        !           103: 
        !           104: Zend Engine II currently includes two executors during the build process, one
        !           105: is the specialized version and the other is the old one non-specialized with
        !           106: function handlers. By default Zend Engine II uses the specialized one but you
        !           107: can switch to the old executor at runtime by calling zend_vm_use_old_executor().
        !           108: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>