PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/opcache/Optimizer - pass3.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 95 185 51.4 %
Date: 2018-07-14 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend OPcache                                                         |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2018 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    |          Stanislav Malyshev <stas@zend.com>                          |
      18             :    |          Dmitry Stogov <dmitry@zend.com>                             |
      19             :    +----------------------------------------------------------------------+
      20             : */
      21             : 
      22             : /* pass 3:
      23             :  * - optimize $i = $i+expr to $i+=expr
      24             :  * - optimize series of JMPs
      25             :  * - change $i++ to ++$i where possible
      26             :  */
      27             : 
      28             : #include "php.h"
      29             : #include "Optimizer/zend_optimizer.h"
      30             : #include "Optimizer/zend_optimizer_internal.h"
      31             : #include "zend_API.h"
      32             : #include "zend_constants.h"
      33             : #include "zend_execute.h"
      34             : #include "zend_vm.h"
      35             : 
      36             : /* compares opcodes with allowing oc1 be _EX of oc2 */
      37             : #define SAME_OPCODE_EX(oc1, oc2) ((oc1 == oc2) || (oc1 == ZEND_JMPZ_EX && oc2 == ZEND_JMPZ) || (oc1 == ZEND_JMPNZ_EX && oc2 == ZEND_JMPNZ))
      38             : 
      39             : /* we use "jmp_hitlist" to avoid infinity loops during jmp optimization */
      40             : #define CHECK_JMP(target, label)                        \
      41             :         for (i=0; i<jmp_hitlist_count; i++) {        \
      42             :                 if (jmp_hitlist[i] == ZEND_OP1_JMP_ADDR(target)) {              \
      43             :                         goto label;                                             \
      44             :                 }                                                                       \
      45             :         }                                                                               \
      46             :         jmp_hitlist[jmp_hitlist_count++] = ZEND_OP1_JMP_ADDR(target);
      47             : 
      48             : #define CHECK_JMP2(target, label)                       \
      49             :         for (i=0; i<jmp_hitlist_count; i++) {        \
      50             :                 if (jmp_hitlist[i] == ZEND_OP2_JMP_ADDR(target)) {              \
      51             :                         goto label;                                             \
      52             :                 }                                                                       \
      53             :         }                                                                               \
      54             :         jmp_hitlist[jmp_hitlist_count++] = ZEND_OP2_JMP_ADDR(target);
      55             : 
      56         729 : void zend_optimizer_pass3(zend_op_array *op_array)
      57             : {
      58             :         zend_op *opline;
      59         729 :         zend_op *end = op_array->opcodes + op_array->last;
      60             :         zend_op **jmp_hitlist;
      61             :         int jmp_hitlist_count;
      62             :         int i;
      63         729 :         uint32_t opline_num = 0;
      64             :         ALLOCA_FLAG(use_heap);
      65             : 
      66         729 :         jmp_hitlist = (zend_op**)do_alloca(sizeof(zend_op*)*op_array->last, use_heap);
      67         729 :         opline = op_array->opcodes;
      68             : 
      69       11937 :         while (opline < end) {
      70       10479 :                 jmp_hitlist_count = 0;
      71             : 
      72       10479 :                 switch (opline->opcode) {
      73         146 :                         case ZEND_ADD:
      74             :                         case ZEND_SUB:
      75             :                         case ZEND_MUL:
      76             :                         case ZEND_DIV:
      77             :                         case ZEND_MOD:
      78             :                         case ZEND_POW:
      79             :                         case ZEND_CONCAT:
      80             :                         case ZEND_SL:
      81             :                         case ZEND_SR:
      82             :                         case ZEND_BW_OR:
      83             :                         case ZEND_BW_AND:
      84             :                         case ZEND_BW_XOR:
      85             :                                 {
      86         146 :                                         zend_op *next_opline = opline + 1;
      87             : 
      88         292 :                                         while (next_opline < end && next_opline->opcode == ZEND_NOP) {
      89           0 :                                                 ++next_opline;
      90             :                                         }
      91             : 
      92         292 :                                         if (next_opline >= end || next_opline->opcode != ZEND_ASSIGN) {
      93             :                                                 break;
      94             :                                         }
      95             : 
      96          10 :                                         if ((ZEND_OP2_TYPE(opline) & (IS_VAR | IS_CV))
      97           1 :                                                 && ZEND_OP2(opline).var == ZEND_OP1(next_opline).var &&
      98           0 :                                                 (opline->opcode == ZEND_ADD ||
      99           0 :                                                  opline->opcode == ZEND_MUL ||
     100           0 :                                                  opline->opcode == ZEND_BW_OR ||
     101           0 :                                                  opline->opcode == ZEND_BW_AND ||
     102           0 :                                                  opline->opcode == ZEND_BW_XOR)) {
     103             :                                                 /* change $i=expr+$i to $i=$i+expr so that the next
     104             :                                                 * optimization works on it
     105             :                                                 */
     106           0 :                                                 zend_uchar tmp_type = opline->op1_type;
     107           0 :                                                 znode_op tmp = opline->op1;
     108             : 
     109           0 :                                                 if (opline->opcode != ZEND_ADD
     110           0 :                                                                 || (ZEND_OP1_TYPE(opline) == IS_CONST
     111           0 :                                                                         && Z_TYPE(ZEND_OP1_LITERAL(opline)) != IS_ARRAY)) {
     112             :                                                         /* protection from array add: $a = array + $a is not commutative! */
     113           0 :                                                         COPY_NODE(opline->op1, opline->op2);
     114           0 :                                                         COPY_NODE(opline->op2, tmp);
     115             :                                                 }
     116             :                                         }
     117          10 :                                         if ((ZEND_OP1_TYPE(opline) & (IS_VAR | IS_CV))
     118           3 :                                                 && ZEND_OP1(opline).var == ZEND_OP1(next_opline).var
     119           0 :                                                 && ZEND_OP1_TYPE(opline) == ZEND_OP1_TYPE(next_opline)) {
     120           0 :                                                 switch (opline->opcode) {
     121           0 :                                                         case ZEND_ADD:
     122           0 :                                                                 opline->opcode = ZEND_ASSIGN_ADD;
     123           0 :                                                                 break;
     124           0 :                                                         case ZEND_SUB:
     125           0 :                                                                 opline->opcode = ZEND_ASSIGN_SUB;
     126           0 :                                                                 break;
     127           0 :                                                         case ZEND_MUL:
     128           0 :                                                                 opline->opcode = ZEND_ASSIGN_MUL;
     129           0 :                                                                 break;
     130           0 :                                                         case ZEND_DIV:
     131           0 :                                                                 opline->opcode = ZEND_ASSIGN_DIV;
     132           0 :                                                                 break;
     133           0 :                                                         case ZEND_MOD:
     134           0 :                                                                 opline->opcode = ZEND_ASSIGN_MOD;
     135           0 :                                                                 break;
     136           0 :                                                         case ZEND_POW:
     137           0 :                                                                 opline->opcode = ZEND_ASSIGN_POW;
     138           0 :                                                                 break;
     139           0 :                                                         case ZEND_CONCAT:
     140           0 :                                                                 opline->opcode = ZEND_ASSIGN_CONCAT;
     141           0 :                                                                 break;
     142           0 :                                                         case ZEND_SL:
     143           0 :                                                                 opline->opcode = ZEND_ASSIGN_SL;
     144           0 :                                                                 break;
     145           0 :                                                         case ZEND_SR:
     146           0 :                                                                 opline->opcode = ZEND_ASSIGN_SR;
     147           0 :                                                                 break;
     148           0 :                                                         case ZEND_BW_OR:
     149           0 :                                                                 opline->opcode = ZEND_ASSIGN_BW_OR;
     150           0 :                                                                 break;
     151           0 :                                                         case ZEND_BW_AND:
     152           0 :                                                                 opline->opcode = ZEND_ASSIGN_BW_AND;
     153           0 :                                                                 break;
     154           0 :                                                         case ZEND_BW_XOR:
     155           0 :                                                                 opline->opcode = ZEND_ASSIGN_BW_XOR;
     156           0 :                                                                 break;
     157             :                                                 }
     158           0 :                                                 COPY_NODE(opline->result, next_opline->result);
     159           0 :                                                 MAKE_NOP(next_opline);
     160           0 :                                                 opline++;
     161           0 :                                                 opline_num++;
     162             :                                         }
     163             :                                 }
     164          10 :                                 break;
     165             : 
     166         341 :                         case ZEND_JMP:
     167         341 :                                 if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
     168           1 :                                         break;
     169             :                                 }
     170             : 
     171             :                                 /* convert L: JMP L+1 to NOP */
     172         340 :                                 if (ZEND_OP1_JMP_ADDR(opline) == opline + 1) {
     173          11 :                                         MAKE_NOP(opline);
     174          11 :                                         goto done_jmp_optimization;
     175             :                                 }
     176             : 
     177             :                                 /* convert JMP L1 ... L1: JMP L2 to JMP L2 .. L1: JMP L2 */
     178         684 :                                 while (ZEND_OP1_JMP_ADDR(opline) < end
     179         355 :                                                 && ZEND_OP1_JMP_ADDR(opline)->opcode == ZEND_JMP) {
     180          26 :                                         zend_op *target = ZEND_OP1_JMP_ADDR(opline);
     181          26 :                                         CHECK_JMP(target, done_jmp_optimization);
     182          26 :                                         ZEND_SET_OP_JMP_ADDR(opline, opline->op1, ZEND_OP1_JMP_ADDR(target));
     183             :                                 }
     184         329 :                                 break;
     185             : 
     186           0 :                         case ZEND_JMP_SET:
     187             :                         case ZEND_COALESCE:
     188           0 :                                 if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
     189           0 :                                         break;
     190             :                                 }
     191             : 
     192           0 :                                 while (ZEND_OP2_JMP_ADDR(opline) < end) {
     193           0 :                                         zend_op *target = ZEND_OP2_JMP_ADDR(opline);
     194           0 :                                         if (target->opcode == ZEND_JMP) {
     195           0 :                                                 ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP1_JMP_ADDR(target));
     196             :                                         } else {
     197           0 :                                                 break;
     198             :                                         }
     199             :                                 }
     200           0 :                                 break;
     201         247 :                         case ZEND_JMPZ:
     202             :                         case ZEND_JMPNZ:
     203         247 :                                 if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
     204           0 :                                         break;
     205             :                                 }
     206             : 
     207         510 :                                 while (ZEND_OP2_JMP_ADDR(opline) < end) {
     208         263 :                                         zend_op *target = ZEND_OP2_JMP_ADDR(opline);
     209             : 
     210         263 :                                         if (target->opcode == ZEND_JMP) {
     211             :                                                 /* plain JMP */
     212             :                                                 /* JMPZ(X,L1), L1: JMP(L2) => JMPZ(X,L2), L1: JMP(L2) */
     213          15 :                                                 CHECK_JMP(target, done_jmp_optimization);
     214          15 :                                                 ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP1_JMP_ADDR(target));
     215         257 :                                         } else if (target->opcode == opline->opcode &&
     216          14 :                                                    SAME_VAR(opline->op1, target->op1)) {
     217             :                                                 /* same opcode and same var as this opcode */
     218             :                                                 /* JMPZ(X,L1), L1: JMPZ(X,L2) => JMPZ(X,L2), L1: JMPZ(X,L2) */
     219           2 :                                                 CHECK_JMP2(target, done_jmp_optimization);
     220           1 :                                                 ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(target));
     221         261 :                                         } else if (target->opcode == opline->opcode + 3 &&
     222          15 :                                                    SAME_VAR(opline->op1, target->op1)) {
     223             :                                                 /* convert JMPZ(X,L1), L1: T JMPZ_EX(X,L2) to
     224             :                                                    T = JMPZ_EX(X, L2) */
     225           0 :                                                 ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(target));
     226           0 :                                                 opline->opcode += 3;
     227           0 :                                                 COPY_NODE(opline->result, target->result);
     228           0 :                                                 break;
     229         246 :                                         } else if (target->opcode == INV_COND(opline->opcode) &&
     230           0 :                                                    SAME_VAR(opline->op1, target->op1)) {
     231             :                                                 /* convert JMPZ(X,L1), L1: JMPNZ(X,L2) to
     232             :                                                    JMPZ(X,L1+1) */
     233           0 :                                                 ZEND_SET_OP_JMP_ADDR(opline, opline->op2, target + 1);
     234           0 :                                                 break;
     235         246 :                                         } else if (target->opcode == INV_COND_EX(opline->opcode) &&
     236           0 :                                                    SAME_VAR(opline->op1, target->op1)) {
     237             :                                                 /* convert JMPZ(X,L1), L1: T = JMPNZ_EX(X,L2) to
     238             :                                                    T = JMPZ_EX(X,L1+1) */
     239           0 :                                                 ZEND_SET_OP_JMP_ADDR(opline, opline->op2, target + 1);
     240           0 :                                                 opline->opcode += 3;
     241           0 :                                                 COPY_NODE(opline->result, target->result);
     242           0 :                                                 break;
     243             :                                         } else {
     244             :                                                 break;
     245             :                                         }
     246             :                                 }
     247         246 :                                 break;
     248             : 
     249          58 :                         case ZEND_JMPZ_EX:
     250             :                         case ZEND_JMPNZ_EX: {
     251          58 :                                         zend_uchar T_type = opline->result_type;
     252          58 :                                         znode_op T = opline->result;
     253             : 
     254          58 :                                         if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
     255          58 :                                                 break;
     256             :                                         }
     257             : 
     258             :                                         /* convert L: T = JMPZ_EX X,L+1 to T = BOOL(X) */
     259             :                                         /* convert L: T = JMPZ_EX T,L+1 to NOP */
     260          58 :                                         if (ZEND_OP2_JMP_ADDR(opline) == opline + 1) {
     261           0 :                                                 if (ZEND_OP1(opline).var == ZEND_RESULT(opline).var) {
     262           0 :                                                         MAKE_NOP(opline);
     263             :                                                 } else {
     264           0 :                                                         opline->opcode = ZEND_BOOL;
     265           0 :                                                         SET_UNUSED(opline->op2);
     266             :                                                 }
     267           0 :                                                 goto done_jmp_optimization;
     268             :                                         }
     269             : 
     270         150 :                                         while (ZEND_OP2_JMP_ADDR(opline) < end) {
     271          92 :                                                 zend_op *target = ZEND_OP2_JMP_ADDR(opline);
     272             : 
     273         126 :                                                 if (SAME_OPCODE_EX(opline->opcode, target->opcode) &&
     274          68 :                                                         SAME_VAR(target->op1, T)) {
     275             :                                                         /* Check for JMPZ_EX to JMPZ[_EX] with the same condition, either with _EX or not */
     276          34 :                                                         if (target->opcode == opline->opcode) {
     277             :                                                                 /* change T only if we have _EX opcode there */
     278           1 :                                                                 COPY_NODE(T, target->result);
     279             :                                                         }
     280          34 :                                                         CHECK_JMP2(target, continue_jmp_ex_optimization);
     281          34 :                                                         ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(target));
     282          58 :                                                 } else if (target->opcode == ZEND_JMPZNZ &&
     283           0 :                                                                   SAME_VAR(target->op1, T)) {
     284             :                                                         /* Check for JMPZNZ with same cond variable */
     285             :                                                         zend_op *new_target;
     286             : 
     287           0 :                                                         CHECK_JMP2(target, continue_jmp_ex_optimization);
     288           0 :                                                         if (opline->opcode == ZEND_JMPZ_EX) {
     289           0 :                                                                 new_target = ZEND_OP2_JMP_ADDR(target);
     290             :                                                         } else {
     291             :                                                                 /* JMPNZ_EX */
     292           0 :                                                                 new_target = ZEND_OFFSET_TO_OPLINE(target, target->extended_value);
     293             :                                                         }
     294           0 :                                                         ZEND_SET_OP_JMP_ADDR(opline, opline->op2, new_target);
     295         116 :                                                 } else if ((target->opcode == INV_EX_COND_EX(opline->opcode) ||
     296          66 :                                                                         target->opcode == INV_EX_COND(opline->opcode)) &&
     297          15 :                                                                         SAME_VAR(opline->op1, target->op1)) {
     298             :                                                    /* convert JMPZ_EX(X,L1), L1: JMPNZ_EX(X,L2) to
     299             :                                                           JMPZ_EX(X,L1+1) */
     300           7 :                                                         ZEND_SET_OP_JMP_ADDR(opline, opline->op2, target + 1);
     301           7 :                                                         break;
     302             :                                                 } else {
     303             :                                                         break;
     304             :                                                 }
     305             :                                         } /* while */
     306          51 : continue_jmp_ex_optimization:
     307          58 :                                         break;
     308             : #if 0
     309             :                                         /* If Ti = JMPZ_EX(X, L) and Ti is not used, convert to JMPZ(X, L) */
     310             :                                         {
     311             :                                                 zend_op *op;
     312             :                                                 for(op = opline+1; op<end; op++) {
     313             :                                                         if(ZEND_RESULT_TYPE(op) == IS_TMP_VAR &&
     314             :                                                            ZEND_RESULT(op).var == ZEND_RESULT(opline).var) {
     315             :                                                                 break; /* can pass to part 2 */
     316             :                                                         }
     317             : 
     318             :                                                         if(op->opcode == ZEND_JMP ||
     319             :                                                            op->opcode == ZEND_JMPZ ||
     320             :                                                            op->opcode == ZEND_JMPZ_EX ||
     321             :                                                            op->opcode == ZEND_JMPNZ ||
     322             :                                                            op->opcode == ZEND_JMPNZ_EX ||
     323             :                                                            op->opcode == ZEND_JMPZNZ ||
     324             :                                                            op->opcode == ZEND_CASE ||
     325             :                                                            op->opcode == ZEND_RETURN ||
     326             :                                                            op->opcode == ZEND_RETURN_BY_REF ||
     327             :                                                            op->opcode == ZEND_FAST_RET ||
     328             :                                                            op->opcode == ZEND_FE_FETCH_R ||
     329             :                                                            op->opcode == ZEND_FE_FETCH_RW ||
     330             :                                                            op->opcode == ZEND_EXIT) {
     331             :                                                                 break;
     332             :                                                         }
     333             : 
     334             :                                                         if(ZEND_OP1_TYPE(op) == IS_TMP_VAR &&
     335             :                                                            ZEND_OP1(op).var == ZEND_RESULT(opline).var) {
     336             :                                                                 goto done_jmp_optimization;
     337             :                                                         }
     338             : 
     339             :                                                         if(ZEND_OP2_TYPE(op) == IS_TMP_VAR &&
     340             :                                                            ZEND_OP2(op).var == ZEND_RESULT(opline).var) {
     341             :                                                                 goto done_jmp_optimization;
     342             :                                                         }
     343             :                                                 } /* for */
     344             : 
     345             :                                                 for(op = &op_array->opcodes[ZEND_OP2(opline).opline_num]; op<end; op++) {
     346             : 
     347             :                                                         if(ZEND_RESULT_TYPE(op) == IS_TMP_VAR &&
     348             :                                                            ZEND_RESULT(op).var == ZEND_RESULT(opline).var) {
     349             :                                                                 break; /* can pass to optimization */
     350             :                                                         }
     351             : 
     352             :                                                         if(op->opcode == ZEND_JMP ||
     353             :                                                            op->opcode == ZEND_JMPZ ||
     354             :                                                            op->opcode == ZEND_JMPZ_EX ||
     355             :                                                            op->opcode == ZEND_JMPNZ ||
     356             :                                                            op->opcode == ZEND_JMPNZ_EX ||
     357             :                                                            op->opcode == ZEND_JMPZNZ ||
     358             :                                                            op->opcode == ZEND_CASE ||
     359             :                                                            op->opcode == ZEND_RETURN ||
     360             :                                                            op->opcode == ZEND_RETURN_BY_REF ||
     361             :                                                            op->opcode == ZEND_FAST_RET ||
     362             :                                                            op->opcode == ZEND_FE_FETCH_R ||
     363             :                                                            op->opcode == ZEND_FE_FETCH_RW ||
     364             :                                                            op->opcode == ZEND_EXIT) {
     365             :                                                                 break;
     366             :                                                         }
     367             : 
     368             :                                                         if(ZEND_OP1_TYPE(op) == IS_TMP_VAR &&
     369             :                                                            ZEND_OP1(op).var == ZEND_RESULT(opline).var) {
     370             :                                                                 goto done_jmp_optimization;
     371             :                                                         }
     372             : 
     373             :                                                         if(ZEND_OP2_TYPE(op) == IS_TMP_VAR &&
     374             :                                                            ZEND_OP2(op).var == ZEND_RESULT(opline).var) {
     375             :                                                                 goto done_jmp_optimization;
     376             :                                                         }
     377             :                                                 }
     378             : 
     379             :                                                 opline->opcode = opline->opcode-3; /* JMP_EX -> JMP */
     380             :                                                 SET_UNUSED(opline->result);
     381             :                                                 break;
     382             :                                         }
     383             : #endif
     384             :                                 }
     385             :                                 break;
     386             : 
     387          16 :                         case ZEND_JMPZNZ:
     388          16 :                                 if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
     389           0 :                                         break;
     390             :                                 }
     391             : 
     392             :                                 /* JMPZNZ(X,L1,L2), L1: JMP(L3) => JMPZNZ(X,L3,L2), L1: JMP(L3) */
     393          42 :                                 while (ZEND_OP2_JMP_ADDR(opline) < end
     394          26 :                                                 && ZEND_OP2_JMP_ADDR(opline)->opcode == ZEND_JMP) {
     395          10 :                                         zend_op *target = ZEND_OP2_JMP_ADDR(opline);
     396          10 :                                         CHECK_JMP(target, continue_jmpznz_optimization);
     397          10 :                                         ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP1_JMP_ADDR(target));
     398             :                                 }
     399          16 : continue_jmpznz_optimization:
     400             :                                 /* JMPZNZ(X,L1,L2), L2: JMP(L3) => JMPZNZ(X,L1,L3), L2: JMP(L3) */
     401          35 :                                 while (ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) < end
     402          19 :                                                 && ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value)->opcode == ZEND_JMP) {
     403           3 :                                         zend_op *target = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value);
     404           3 :                                         CHECK_JMP(target, done_jmp_optimization);
     405           3 :                                         opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, ZEND_OP1_JMP_ADDR(target));
     406             :                                 }
     407          16 :                                 break;
     408             : 
     409          18 :                         case ZEND_POST_INC:
     410             :                         case ZEND_POST_DEC: {
     411             :                                         /* POST_INC, FREE => PRE_INC */
     412          18 :                                         zend_op *next_op = opline + 1;
     413             : 
     414          18 :                                         if (next_op >= end) {
     415           0 :                                                 break;
     416             :                                         }
     417          36 :                                         if (next_op->opcode == ZEND_FREE &&
     418          18 :                                                 ZEND_OP1(next_op).var == ZEND_RESULT(opline).var) {
     419          18 :                                                 MAKE_NOP(next_op);
     420          18 :                                                 opline->opcode -= 2;
     421          18 :                                                 ZEND_RESULT_TYPE(opline) = IS_UNUSED;
     422             :                                         }
     423             :                                 }
     424          18 :                                 break;
     425             :                 }
     426       10615 : done_jmp_optimization:
     427       10479 :                 opline++;
     428       10479 :                 opline_num++;
     429             :         }
     430         729 :         free_alloca(jmp_hitlist, use_heap);
     431         729 : }

Generated by: LCOV version 1.10

Generated at Sun, 15 Jul 2018 02:47:33 +0000 (5 days ago)

Copyright © 2005-2018 The PHP Group
All rights reserved.