root/ext/opcache/Optimizer/optimize_temp_vars_5.c

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

DEFINITIONS

This source file includes following definitions.
  1. optimize_temporary_variables

   1 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
   2 
   3 /* ops that use CLs:
   4 op1:
   5 ZEND_FETCH_CONSTANT:
   6 ZEND_INIT_CTOR_CALL:
   7 ZEND_INIT_STATIC_METHOD_CALL:
   8 ZEND_INIT_METHOD_CALL:
   9 ZEND_IMPORT_CLASS:
  10 ZEND_IMPORT_FUNCTION:
  11 ZEND_IMPORT_CONST:
  12 ZEND_ADD_INTERFACE:
  13 ZEND_VERIFY_ABSTRACT_CLASS:
  14 ZEND_NEW:
  15 ZEND_CATCH:
  16 ZEND_INIT_FCALL_BY_NAME:
  17 
  18 op2:
  19 ZEND_UNSET_VAR:
  20 ZEND_ISSET_ISEMPTY_VAR:
  21 ZEND_FETCH_UNSET:
  22 ZEND_FETCH_IS:
  23 ZEND_FETCH_R:
  24 ZEND_FETCH_W:
  25 ZEND_FETCH_RW:
  26 ZEND_FETCH_FUNC_ARG:
  27 ZEND_ADD_INTERFACE:
  28 ZEND_INSTANCEOF:
  29 
  30 extended_value:
  31 ZEND_DECLARE_INHERITED_CLASS:
  32 
  33 ignore result
  34 INIT_METHOD_CALL:
  35 */
  36 
  37 #define OP1_CONST_IS_CLASS 1
  38 #define OP2_CONST_IS_CLASS 2
  39 #define EXT_CONST_IS_CLASS 4
  40 #define RESULT_IS_UNUSED   8
  41 
  42 static const char op_const_means_class[256]  = {
  43         /* 0 */
  44         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  45         /* 32 */
  46         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
  47         /* 64 */
  48         0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2,
  49         /* 96 */
  50         0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 9, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  51         /* 128 */
  52         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  53         /* 160 */
  54         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  55         /* 192 */
  56         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  57         /* 224 */
  58         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  59 };
  60 #endif
  61 
  62 #define GET_AVAILABLE_T()               \
  63         for (i = 0; i < T; i++) {       \
  64                 if (!taken_T[i]) {              \
  65                         break;                          \
  66                 }                                               \
  67         }                                                       \
  68         taken_T[i] = 1;                         \
  69         if (i > max) {                          \
  70                 max = i;                                \
  71         }
  72 
  73 static void optimize_temporary_variables(zend_op_array *op_array)
  74 {
  75         int T = op_array->T;
  76         char *taken_T;                  /* T index in use */
  77         zend_op **start_of_T;   /* opline where T is first used */
  78         char *valid_T;                  /* Is the map_T valid */
  79         int *map_T;                             /* Map's the T to its new index */
  80         zend_op *opline, *end;
  81         int currT;
  82         int i;
  83         int max = -1;
  84         int var_to_free = -1;
  85 
  86         taken_T = (char *) emalloc(T);
  87         start_of_T = (zend_op **) emalloc(T * sizeof(zend_op *));
  88         valid_T = (char *) emalloc(T);
  89         map_T = (int *) emalloc(T * sizeof(int));
  90 
  91     end = op_array->opcodes;
  92     opline = &op_array->opcodes[op_array->last - 1];
  93 
  94     /* Find T definition points */
  95     while (opline >= end) {
  96 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
  97         if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR | IS_CONST)) {
  98                         if (!(op_const_means_class[opline->opcode] & RESULT_IS_UNUSED)) {
  99                                 start_of_T[VAR_NUM(ZEND_RESULT(opline).var)] = opline;
 100                         }
 101                 }
 102 #else
 103         if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR)) {
 104                         start_of_T[VAR_NUM(ZEND_RESULT(opline).var)] = opline;
 105                 }
 106 #endif
 107                 opline--;
 108         }
 109 
 110         memset(valid_T, 0, T);
 111         memset(taken_T, 0, T);
 112 
 113     end = op_array->opcodes;
 114     opline = &op_array->opcodes[op_array->last - 1];
 115 
 116     while (opline >= end) {
 117                 if ((ZEND_OP1_TYPE(opline) & (IS_VAR | IS_TMP_VAR))
 118 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
 119                         || ((op_const_means_class[opline->opcode] & OP1_CONST_IS_CLASS) && ZEND_OP1_TYPE(opline) == IS_CONST)
 120 #endif
 121                         ) {
 122                         currT = VAR_NUM(ZEND_OP1(opline).var);
 123                         if (!valid_T[currT]) {
 124                                 GET_AVAILABLE_T();
 125                                 map_T[currT] = i;
 126                                 valid_T[currT] = 1;
 127                         }
 128                         ZEND_OP1(opline).var = NUM_VAR(map_T[currT]);
 129                 }
 130 
 131                 /* Skip OP_DATA */
 132                 if (opline->opcode == ZEND_OP_DATA &&
 133                     (opline-1)->opcode == ZEND_ASSIGN_DIM) {
 134                     opline--;
 135                     continue;
 136                 }
 137 
 138                 if ((ZEND_OP2_TYPE(opline) & (IS_VAR | IS_TMP_VAR))
 139 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
 140                         || ((op_const_means_class[opline->opcode] & OP2_CONST_IS_CLASS) && ZEND_OP2_TYPE(opline) == IS_CONST)
 141 #endif
 142                    ) {
 143                         currT = VAR_NUM(ZEND_OP2(opline).var);
 144                         if (!valid_T[currT]) {
 145                                 GET_AVAILABLE_T();
 146                                 map_T[currT] = i;
 147                                 valid_T[currT] = 1;
 148                         }
 149                         ZEND_OP2(opline).var = NUM_VAR(map_T[currT]);
 150                 }
 151 
 152 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
 153                 if ((op_const_means_class[opline->opcode] & EXT_CONST_IS_CLASS)) {
 154 #else
 155                 if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS ||
 156             opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) {
 157 #endif
 158                         currT = VAR_NUM(opline->extended_value);
 159                         if (!valid_T[currT]) {
 160                                 GET_AVAILABLE_T();
 161                                 map_T[currT] = i;
 162                                 valid_T[currT] = 1;
 163                         }
 164                         opline->extended_value = NUM_VAR(map_T[currT]);
 165                 }
 166 
 167                 /* Allocate OP_DATA->op2 after "operands", but before "result" */
 168                 if (opline->opcode == ZEND_ASSIGN_DIM &&
 169                     (opline + 1)->opcode == ZEND_OP_DATA &&
 170                     ZEND_OP2_TYPE(opline + 1) & (IS_VAR | IS_TMP_VAR)) {
 171                         currT = VAR_NUM(ZEND_OP2(opline + 1).var);
 172                         GET_AVAILABLE_T();
 173                         map_T[currT] = i;
 174                         valid_T[currT] = 1;
 175                         taken_T[i] = 0;
 176                         ZEND_OP2(opline + 1).var = NUM_VAR(i);
 177                         var_to_free = i;
 178                 }
 179 
 180 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
 181                 if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR | IS_CONST)) {
 182                         if (!(op_const_means_class[opline->opcode] & RESULT_IS_UNUSED)) {
 183 #else
 184                 if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR)) {
 185 #endif
 186                                 currT = VAR_NUM(ZEND_RESULT(opline).var);
 187                                 if (valid_T[currT]) {
 188                                         if (start_of_T[currT] == opline) {
 189                                                 taken_T[map_T[currT]] = 0;
 190                                         }
 191                                         ZEND_RESULT(opline).var = NUM_VAR(map_T[currT]);
 192                                 } else { /* Au still needs to be assigned a T which is a bit dumb. Should consider changing Zend */
 193                                         GET_AVAILABLE_T();
 194 
 195                                         if (RESULT_UNUSED(opline)) {
 196                                                 taken_T[i] = 0;
 197                                         } else {
 198                                                 /* Code which gets here is using a wrongly built opcode such as RECV() */
 199                                                 map_T[currT] = i;
 200                                                 valid_T[currT] = 1;
 201                                         }
 202                                         ZEND_RESULT(opline).var = NUM_VAR(i);
 203                                 }
 204 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
 205                         }
 206 #endif
 207                 }
 208 
 209                 if (var_to_free >= 0) {
 210                         taken_T[var_to_free] = 0;
 211                         var_to_free = -1;
 212                 }
 213 
 214                 opline--;
 215         }
 216 
 217         efree(taken_T);
 218         efree(start_of_T);
 219         efree(valid_T);
 220         efree(map_T);
 221         op_array->T = max + 1;
 222 }

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