]> granicus.if.org Git - php/commitdiff
Optimized JMPZNZ to avoid multiplication at runtime (may be it makes sense to use...
authorDmitry Stogov <dmitry@zend.com>
Wed, 30 Apr 2014 07:23:19 +0000 (11:23 +0400)
committerDmitry Stogov <dmitry@zend.com>
Wed, 30 Apr 2014 07:23:19 +0000 (11:23 +0400)
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_opcode.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/zend_persist.c

index 22acd4e9609d4d1ee22138f77004fe95759ac66b..8b3ea40eb6d7242bbeb0722f1fce85d6b0bbdbe3 100644 (file)
@@ -1731,6 +1731,10 @@ static zend_always_inline zval *zend_vm_stack_push_args(int count TSRMLS_DC) /*
        CHECK_SYMBOL_TABLES() \
        OPLINE = new_op
 
+#define ZEND_VM_SET_RELATIVE_OPCODE(opline, offset) \
+       CHECK_SYMBOL_TABLES() \
+       OPLINE = ((zend_op*)(((char*)opline)+(offset)))
+
 #define ZEND_VM_JMP(new_op) \
        if (EXPECTED(!EG(exception))) { \
                ZEND_VM_SET_OPCODE(new_op); \
index 03f763ea2167c7c0d1043cf88435f8f454b929a8..a7d7a948a5152e18f7c1015f0de9687cf8cd8493 100644 (file)
@@ -1301,6 +1301,10 @@ void execute_new_code(TSRMLS_D) /* {{{ */
                        case ZEND_JMP:
                                opline->op1.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.opline_num];
                                break;
+                       case ZEND_JMPZNZ:
+                               /* absolute index to relative offset */
+                               opline->extended_value = (char*)(CG(active_op_array)->opcodes + opline->extended_value) - (char*)opline;
+                               /* break omitted intentionally */
                        case ZEND_JMPZ:
                        case ZEND_JMPNZ:
                        case ZEND_JMPZ_EX:
index e38a32a851e19d22f4e41d38d801f60f52fa72dd..d1c4e681e14dbcd70f6eab63c29aebeec830f617 100644 (file)
@@ -683,6 +683,10 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
                        case ZEND_FAST_CALL:
                                opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num];
                                break;
+                       case ZEND_JMPZNZ:
+                               /* absolute index to relative offset */
+                               opline->extended_value = (char*)(op_array->opcodes + opline->extended_value) - (char*)opline;
+                               /* break omitted intentionally */
                        case ZEND_JMPZ:
                        case ZEND_JMPNZ:
                        case ZEND_JMPZ_EX:
index 1cfd7650c829775945bfa769b68c9526f8094060..4c4115b76162e3f7055aabde663904b2f61bd9c1 100644 (file)
@@ -2180,13 +2180,13 @@ ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMP|VAR|CV, ANY)
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on true to %d\n", opline->extended_value);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+               ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        } else {
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on false to %d\n", opline->op2.opline_num);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+               ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        }
 }
index 4e10970798182d555d903ba1bf7b3599b7a2f6de..41b907e8028a0be0f2b9afb2584644c30708a378 100644 (file)
@@ -2464,13 +2464,13 @@ static int ZEND_FASTCALL  ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on true to %d\n", opline->extended_value);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+               ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        } else {
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on false to %d\n", opline->op2.opline_num);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+               ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        }
 }
@@ -7564,13 +7564,13 @@ static int ZEND_FASTCALL  ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on true to %d\n", opline->extended_value);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+               ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        } else {
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on false to %d\n", opline->op2.opline_num);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+               ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        }
 }
@@ -12603,13 +12603,13 @@ static int ZEND_FASTCALL  ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on true to %d\n", opline->extended_value);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+               ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        } else {
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on false to %d\n", opline->op2.opline_num);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+               ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        }
 }
@@ -29533,13 +29533,13 @@ static int ZEND_FASTCALL  ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on true to %d\n", opline->extended_value);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+               ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        } else {
 #if DEBUG_ZEND>=2
                printf("Conditional jmp on false to %d\n", opline->op2.opline_num);
 #endif
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+               ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
                ZEND_VM_CONTINUE(); /* CHECK_ME */
        }
 }
index 39f7b01eead51ca4cf065b327161f2a8e0f76a7a..2b6b07ca82a259a38025b20d353892d9c9ac5a44 100644 (file)
@@ -497,6 +497,10 @@ static void zend_accel_optimize(zend_op_array           *op_array,
 #endif
                                ZEND_OP1(opline).opline_num = ZEND_OP1(opline).jmp_addr - op_array->opcodes;
                                break;
+                       case ZEND_JMPZNZ:
+                               /* relative offset into absolute index */
+                               opline->extended_value = (zend_op*)(((char*)opline) + opline->extended_value) - op_array->opcodes;
+                               /* break omitted intentionally */
                        case ZEND_JMPZ:
                        case ZEND_JMPNZ:
                        case ZEND_JMPZ_EX:
@@ -538,6 +542,10 @@ static void zend_accel_optimize(zend_op_array           *op_array,
 #endif
                                ZEND_OP1(opline).jmp_addr = &op_array->opcodes[ZEND_OP1(opline).opline_num];
                                break;
+                       case ZEND_JMPZNZ:
+                               /* absolute index to relative offset */
+                               opline->extended_value = (char*)(op_array->opcodes + opline->extended_value) - (char*)opline;
+                               /* break omitted intentionally */
                        case ZEND_JMPZ:
                        case ZEND_JMPNZ:
                        case ZEND_JMPZ_EX:
index 0130e12d075b35719aedd32d980fa9bd1a5ad58d..601849b012358777370fe51b2b54089723e2cf9c 100644 (file)
@@ -275,6 +275,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
                                                ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes];
                                        }
                                        break;
+                               case ZEND_JMPZNZ:
+                                       /* relative extended_value don't have to be changed */
+                                       /* break omitted intentionally */
                                case ZEND_JMPZ:
                                case ZEND_JMPNZ:
                                case ZEND_JMPZ_EX:
@@ -284,7 +287,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
                                                ZEND_OP2(opline).jmp_addr = &new_opcodes[ZEND_OP2(opline).jmp_addr - op_array->opcodes];
                                        }
                                        break;
-                               case ZEND_JMPZNZ:
                                case ZEND_BRK:
                                case ZEND_CONT:
                                        has_jmp = 1;
@@ -323,6 +325,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
 #endif
                                                ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes];
                                                break;
+                                       case ZEND_JMPZNZ:
+                                               /* relative extended_value don't have to be changed */
+                                               /* break omitted intentionally */
                                        case ZEND_JMPZ:
                                        case ZEND_JMPNZ:
                                        case ZEND_JMPZ_EX: