root/ext/opcache/Optimizer/nop_removal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nop_removal

   1 /* pass 10:
   2  * - remove NOPs
   3  */
   4 
   5 static void nop_removal(zend_op_array *op_array)
   6 {
   7         zend_op *end, *opline;
   8         zend_uint new_count, i, shift;
   9         int j;
  10         zend_uint *shiftlist;
  11         ALLOCA_FLAG(use_heap);
  12 
  13         shiftlist = (zend_uint *)DO_ALLOCA(sizeof(zend_uint) * op_array->last);
  14         i = new_count = shift = 0;
  15         end = op_array->opcodes + op_array->last;
  16         for (opline = op_array->opcodes; opline < end; opline++) {
  17 
  18 #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
  19                 /* GOTO target is unresolved yet. We can't optimize. */
  20                 if (opline->opcode == ZEND_GOTO &&
  21                         Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) {
  22                         /* TODO: in general we can avoid this restriction */
  23                         FREE_ALLOCA(shiftlist);
  24                         return;
  25                 }
  26 #endif
  27 
  28                 /* Kill JMP-over-NOP-s */
  29                 if (opline->opcode == ZEND_JMP && ZEND_OP1(opline).opline_num > i) {
  30                         /* check if there are only NOPs under the branch */
  31                         zend_op *target = op_array->opcodes + ZEND_OP1(opline).opline_num - 1;
  32 
  33                         while (target->opcode == ZEND_NOP) {
  34                                 target--;
  35                         }
  36                         if (target == opline) {
  37                                 /* only NOPs */
  38                                 opline->opcode = ZEND_NOP;
  39                         }
  40                 }
  41 
  42                 shiftlist[i++] = shift;
  43                 if (opline->opcode == ZEND_NOP) {
  44                         shift++;
  45                 } else {
  46                         if (shift) {
  47                                 op_array->opcodes[new_count] = *opline;
  48                         }
  49                         new_count++;
  50                 }
  51         }
  52 
  53         if (shift) {
  54                 op_array->last = new_count;
  55                 end = op_array->opcodes + op_array->last;
  56 
  57                 /* update JMPs */
  58                 for (opline = op_array->opcodes; opline<end; opline++) {
  59                         switch (opline->opcode) {
  60                                 case ZEND_JMP:
  61 #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
  62                                 case ZEND_GOTO:
  63 #endif
  64 #if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
  65                                 case ZEND_FAST_CALL:
  66 #endif
  67                                         ZEND_OP1(opline).opline_num -= shiftlist[ZEND_OP1(opline).opline_num];
  68                                         break;
  69                                 case ZEND_JMPZ:
  70                                 case ZEND_JMPNZ:
  71                                 case ZEND_JMPZ_EX:
  72                                 case ZEND_JMPNZ_EX:
  73                                 case ZEND_FE_FETCH:
  74                                 case ZEND_FE_RESET:
  75                                 case ZEND_NEW:
  76 #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
  77                                 case ZEND_JMP_SET:
  78 #endif
  79 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
  80                                 case ZEND_JMP_SET_VAR:
  81 #endif
  82                                         ZEND_OP2(opline).opline_num -= shiftlist[ZEND_OP2(opline).opline_num];
  83                                         break;
  84                                 case ZEND_JMPZNZ:
  85                                         ZEND_OP2(opline).opline_num -= shiftlist[ZEND_OP2(opline).opline_num];
  86                                         opline->extended_value -= shiftlist[opline->extended_value];
  87                                         break;
  88                                 case ZEND_CATCH:
  89                                         opline->extended_value -= shiftlist[opline->extended_value];
  90                                         break;
  91                         }
  92                 }
  93 
  94                 /* update brk/cont array */
  95                 for (j = 0; j < op_array->last_brk_cont; j++) {
  96                         op_array->brk_cont_array[j].brk -= shiftlist[op_array->brk_cont_array[j].brk];
  97                         op_array->brk_cont_array[j].cont -= shiftlist[op_array->brk_cont_array[j].cont];
  98                         op_array->brk_cont_array[j].start -= shiftlist[op_array->brk_cont_array[j].start];
  99                 }
 100 
 101                 /* update try/catch array */
 102                 for (j = 0; j < op_array->last_try_catch; j++) {
 103                         op_array->try_catch_array[j].try_op -= shiftlist[op_array->try_catch_array[j].try_op];
 104                         op_array->try_catch_array[j].catch_op -= shiftlist[op_array->try_catch_array[j].catch_op];
 105 #if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
 106                         if (op_array->try_catch_array[j].finally_op) {
 107                                 op_array->try_catch_array[j].finally_op -= shiftlist[op_array->try_catch_array[j].finally_op];
 108                                 op_array->try_catch_array[j].finally_end -= shiftlist[op_array->try_catch_array[j].finally_end];
 109                         }
 110 #endif
 111                 }
 112 
 113 #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
 114                 /* update early binding list */
 115                 if (op_array->early_binding != (zend_uint)-1) {
 116                         zend_uint *opline_num = &op_array->early_binding;
 117 
 118                         do {
 119                                 *opline_num -= shiftlist[*opline_num];
 120                                 opline_num = &ZEND_RESULT(&op_array->opcodes[*opline_num]).opline_num;
 121                         } while (*opline_num != (zend_uint)-1);
 122                 }
 123 #endif
 124         }
 125         FREE_ALLOCA(shiftlist);
 126 }

/* [<][>][^][v][top][bottom][index][help] */