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 - lcov_data/ext/opcache/Optimizer - pass2.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 57 99 57.6 %
Date: 2014-08-04 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* pass 2:
       2             :  * - convert non-numeric constants to numeric constants in numeric operators
       3             :  * - optimize constant conditional JMPs
       4             :  * - optimize static BRKs and CONTs
       5             :  */
       6             : 
       7         451 : if (ZEND_OPTIMIZER_PASS_2 & OPTIMIZATION_LEVEL) {
       8             :         zend_op *opline;
       9         451 :         zend_op *end = op_array->opcodes + op_array->last;
      10             : 
      11         451 :         opline = op_array->opcodes;
      12        7766 :         while (opline < end) {
      13        6864 :                 switch (opline->opcode) {
      14             :                         case ZEND_ADD:
      15             :                         case ZEND_SUB:
      16             :                         case ZEND_MUL:
      17             :                         case ZEND_DIV:
      18          12 :                                 if (ZEND_OP1_TYPE(opline) == IS_CONST) {
      19           3 :                                         if (ZEND_OP1_LITERAL(opline).type == IS_STRING) {
      20           0 :                                                 convert_scalar_to_number(&ZEND_OP1_LITERAL(opline) TSRMLS_CC);
      21             :                                         }
      22             :                                 }
      23             :                                 /* break missing *intentionally* - the assign_op's may only optimize op2 */
      24             :                         case ZEND_ASSIGN_ADD:
      25             :                         case ZEND_ASSIGN_SUB:
      26             :                         case ZEND_ASSIGN_MUL:
      27             :                         case ZEND_ASSIGN_DIV:
      28          17 :                                 if (opline->extended_value != 0) {
      29             :                                         /* object tristate op - don't attempt to optimize it! */
      30           0 :                                         break;
      31             :                                 }
      32          17 :                                 if (ZEND_OP2_TYPE(opline) == IS_CONST) {
      33           6 :                                         if (ZEND_OP2_LITERAL(opline).type == IS_STRING) {
      34           0 :                                                 convert_scalar_to_number(&ZEND_OP2_LITERAL(opline) TSRMLS_CC);
      35             :                                         }
      36             :                                 }
      37          17 :                                 break;
      38             : 
      39             :                         case ZEND_MOD:
      40             :                         case ZEND_SL:
      41             :                         case ZEND_SR:
      42           0 :                                 if (ZEND_OP1_TYPE(opline) == IS_CONST) {
      43           0 :                                         if (ZEND_OP1_LITERAL(opline).type != IS_LONG) {
      44           0 :                                                 convert_to_long(&ZEND_OP1_LITERAL(opline));
      45             :                                         }
      46             :                                 }
      47             :                                 /* break missing *intentionally - the assign_op's may only optimize op2 */
      48             :                         case ZEND_ASSIGN_MOD:
      49             :                         case ZEND_ASSIGN_SL:
      50             :                         case ZEND_ASSIGN_SR:
      51           0 :                                 if (opline->extended_value != 0) {
      52             :                                         /* object tristate op - don't attempt to optimize it! */
      53           0 :                                         break;
      54             :                                 }
      55           0 :                                 if (ZEND_OP2_TYPE(opline) == IS_CONST) {
      56           0 :                                         if (ZEND_OP2_LITERAL(opline).type != IS_LONG) {
      57           0 :                                                 convert_to_long(&ZEND_OP2_LITERAL(opline));
      58             :                                         }
      59             :                                 }
      60           0 :                                 break;
      61             : 
      62             :                         case ZEND_CONCAT:
      63          87 :                                 if (ZEND_OP1_TYPE(opline) == IS_CONST) {
      64          29 :                                         if (ZEND_OP1_LITERAL(opline).type != IS_STRING) {
      65           0 :                                                 convert_to_string(&ZEND_OP1_LITERAL(opline));
      66             :                                         }
      67             :                                 }
      68             :                                 /* break missing *intentionally - the assign_op's may only optimize op2 */
      69             :                         case ZEND_ASSIGN_CONCAT:
      70          91 :                                 if (opline->extended_value != 0) {
      71             :                                         /* object tristate op - don't attempt to optimize it! */
      72           0 :                                         break;
      73             :                                 }
      74          91 :                                 if (ZEND_OP2_TYPE(opline) == IS_CONST) {
      75          45 :                                         if (ZEND_OP2_LITERAL(opline).type != IS_STRING) {
      76           0 :                                                 convert_to_string(&ZEND_OP2_LITERAL(opline));
      77             :                                         }
      78             :                                 }
      79          91 :                                 break;
      80             : 
      81             :                         case ZEND_JMPZ_EX:
      82             :                         case ZEND_JMPNZ_EX:
      83             :                                 /* convert Ti = JMPZ_EX(Ti, L) to JMPZ(Ti, L) */
      84          48 :                                 if (0 && /* FIXME: temporary disable unsafe pattern */
      85             :                                     ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
      86             :                                     ZEND_RESULT_TYPE(opline) == IS_TMP_VAR &&
      87             :                                     ZEND_OP1(opline).var == ZEND_RESULT(opline).var) {
      88             :                                         opline->opcode -= 3;
      89             :                                 /* convert Ti = JMPZ_EX(C, L) => Ti = QM_ASSIGN(C)
      90             :                                    in case we know it wouldn't jump */
      91          48 :                                 } else if (ZEND_OP1_TYPE(opline) == IS_CONST) {
      92             : #if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO
      93          21 :                                         int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline) TSRMLS_CC);
      94             : #else
      95             :                                         int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
      96             : #endif
      97          21 :                                         if (opline->opcode == ZEND_JMPZ_EX) {
      98          13 :                                                 should_jmp = !should_jmp;
      99             :                                         }
     100          21 :                                         if (!should_jmp) {
     101           1 :                                                 opline->opcode = ZEND_QM_ASSIGN;
     102           1 :                                                 SET_UNUSED(opline->op2);
     103             :                                         }
     104             :                                 }
     105          48 :                                 break;
     106             : 
     107             :                         case ZEND_JMPZ:
     108             :                         case ZEND_JMPNZ:
     109         338 :                                 if (ZEND_OP1_TYPE(opline) == IS_CONST) {
     110             : #if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO
     111         164 :                                         int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline) TSRMLS_CC);
     112             : #else
     113             :                                         int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
     114             : #endif
     115             : 
     116         164 :                                         if (opline->opcode == ZEND_JMPZ) {
     117         164 :                                                 should_jmp = !should_jmp;
     118             :                                         }
     119         328 :                                         literal_dtor(&ZEND_OP1_LITERAL(opline));
     120         164 :                                         ZEND_OP1_TYPE(opline) = IS_UNUSED;
     121         164 :                                         if (should_jmp) {
     122         159 :                                                 opline->opcode = ZEND_JMP;
     123         159 :                                                 COPY_NODE(opline->op1, opline->op2);
     124             :                                         } else {
     125           5 :                                                 MAKE_NOP(opline);
     126             :                                         }
     127         164 :                                         break;
     128             :                                 }
     129         174 :                                 if ((opline + 1)->opcode == ZEND_JMP) {
     130             :                                         /* JMPZ(X, L1), JMP(L2) => JMPZNZ(X, L1, L2) */
     131             :                                         /* JMPNZ(X, L1), JMP(L2) => JMPZNZ(X, L2, L1) */
     132           0 :                                         if (ZEND_OP2(opline).opline_num == ZEND_OP1(opline + 1).opline_num) {
     133             :                                                 /* JMPZ(X, L1), JMP(L1) => NOP, JMP(L1) */
     134           0 :                                                 MAKE_NOP(opline);
     135             :                                         } else {
     136           0 :                                                 if (opline->opcode == ZEND_JMPZ) {
     137           0 :                                                         opline->extended_value = ZEND_OP1(opline + 1).opline_num;
     138             :                                                 } else {
     139           0 :                                                         opline->extended_value = ZEND_OP2(opline).opline_num;
     140           0 :                                                         COPY_NODE(opline->op2, (opline + 1)->op1);
     141             :                                                 }
     142           0 :                                                 opline->opcode = ZEND_JMPZNZ;
     143             :                                         }
     144             :                                 }
     145         174 :                                 break;
     146             : 
     147             :                         case ZEND_JMPZNZ:
     148           2 :                                 if (ZEND_OP1_TYPE(opline) == IS_CONST) {
     149             :                                         int opline_num;
     150             : #if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO
     151           0 :                                         if (zend_is_true(&ZEND_OP1_LITERAL(opline) TSRMLS_CC)) {
     152             : #else
     153             :                                         if (zend_is_true(&ZEND_OP1_LITERAL(opline))) {
     154             : #endif
     155           0 :                                                 opline_num = opline->extended_value; /* JMPNZ */
     156             :                                         } else {
     157           0 :                                                 opline_num = ZEND_OP2(opline).opline_num; /* JMPZ */
     158             :                                         }
     159           0 :                                         literal_dtor(&ZEND_OP1_LITERAL(opline));
     160           0 :                                         ZEND_OP1(opline).opline_num = opline_num;
     161           0 :                                         ZEND_OP1_TYPE(opline) = IS_UNUSED;
     162           0 :                                         opline->opcode = ZEND_JMP;
     163             :                                 }
     164           2 :                                 break;
     165             : 
     166             :                         case ZEND_BRK:
     167             :                         case ZEND_CONT:
     168             :                                 {
     169             :                                     zend_brk_cont_element *jmp_to;
     170             :                                         int array_offset;
     171             :                                         int nest_levels;
     172           1 :                                         int dont_optimize = 0;
     173             : 
     174           1 :                                         if (ZEND_OP2_TYPE(opline) != IS_CONST) {
     175           0 :                                                 break;
     176             :                                         }
     177           1 :                                         convert_to_long(&ZEND_OP2_LITERAL(opline));
     178           1 :                                         nest_levels = ZEND_OP2_LITERAL(opline).value.lval;
     179             : 
     180           1 :                                         array_offset = ZEND_OP1(opline).opline_num;
     181             :                                         while (1) {
     182           1 :                                                 if (array_offset == -1) {
     183           0 :                                                         dont_optimize = 1; /* don't optimize this bogus break/continue, let the executor shout */
     184           0 :                                                         break;
     185             :                                                 }
     186           1 :                                                 jmp_to = &op_array->brk_cont_array[array_offset];
     187           1 :                                                 array_offset = jmp_to->parent;
     188           1 :                                                 if (--nest_levels > 0) {
     189           0 :                                                         if (opline->opcode == ZEND_BRK &&
     190           0 :                                                             (op_array->opcodes[jmp_to->brk].opcode == ZEND_FREE ||
     191           0 :                                                              op_array->opcodes[jmp_to->brk].opcode == ZEND_SWITCH_FREE)) {
     192           0 :                                                                 dont_optimize = 1;
     193           0 :                                                                 break;
     194             :                                                         }
     195             :                                                 } else {
     196           1 :                                                         break;
     197             :                                                 }
     198           0 :                                         }
     199             : 
     200           1 :                                         if (dont_optimize) {
     201           0 :                                                 break;
     202             :                                         }
     203             : 
     204             :                                         /* optimize - convert to a JMP */
     205           1 :                                         switch (opline->opcode) {
     206             :                                                 case ZEND_BRK:
     207           0 :                                                         MAKE_NOP(opline);
     208           0 :                                                         ZEND_OP1(opline).opline_num = jmp_to->brk;
     209           0 :                                                         break;
     210             :                                                 case ZEND_CONT:
     211           1 :                                                         MAKE_NOP(opline);
     212           1 :                                                         ZEND_OP1(opline).opline_num = jmp_to->cont;
     213             :                                                         break;
     214             :                                         }
     215           1 :                                         opline->opcode = ZEND_JMP;
     216             :                                         /* MAKE_NOP() already set op1 and op2 to IS_UNUSED */
     217             :                                 }
     218             :                                 break;
     219             :                 }
     220        6864 :                 opline++;
     221             :         }
     222             : }

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:18 +0000 (44 days ago)

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