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 - compact_literals.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 174 210 82.9 %
Date: 2014-07-21 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* pass 11
       2             :  * - compact literals table
       3             :  */
       4             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
       5             : 
       6             : #define DEBUG_COMPACT_LITERALS 0
       7             : 
       8             : #define LITERAL_VALUE                        0x0100
       9             : #define LITERAL_FUNC                         0x0200
      10             : #define LITERAL_CLASS                        0x0300
      11             : #define LITERAL_CONST                        0x0400
      12             : #define LITERAL_CLASS_CONST                  0x0500
      13             : #define LITERAL_STATIC_METHOD                0x0600
      14             : #define LITERAL_STATIC_PROPERTY              0x0700
      15             : #define LITERAL_METHOD                       0x0800
      16             : #define LITERAL_PROPERTY                     0x0900
      17             : 
      18             : #define LITERAL_EX_CLASS                     0x4000
      19             : #define LITERAL_EX_OBJ                       0x2000
      20             : #define LITERAL_MAY_MERGE                    0x1000
      21             : #define LITERAL_KIND_MASK                    0x0f00
      22             : #define LITERAL_NUM_RELATED_MASK             0x000f
      23             : #define LITERAL_NUM_SLOTS_MASK               0x00f0
      24             : #define LITERAL_NUM_SLOTS_SHIFT              4
      25             : 
      26             : #define LITERAL_NUM_RELATED(info) (info & LITERAL_NUM_RELATED_MASK)
      27             : #define LITERAL_NUM_SLOTS(info)   ((info & LITERAL_NUM_SLOTS_MASK) >> LITERAL_NUM_SLOTS_SHIFT)
      28             : 
      29             : typedef struct _literal_info {
      30             :         zend_uint  flags; /* bitmask (see defines above) */
      31             :         union {
      32             :                 int    num;   /* variable number or class name literal number */
      33             :         } u;
      34             : } literal_info;
      35             : 
      36             : #define LITERAL_FLAGS(kind, slots, related) \
      37             :         ((kind) | ((slots) << LITERAL_NUM_SLOTS_SHIFT) | (related))
      38             : 
      39             : #define LITERAL_INFO(n, kind, merge, slots, related) do { \
      40             :                 info[n].flags = (((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \
      41             :         } while (0)
      42             : 
      43             : #define LITERAL_INFO_CLASS(n, kind, merge, slots, related, _num) do { \
      44             :                 info[n].flags = (LITERAL_EX_CLASS | ((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \
      45             :                 info[n].u.num = (_num); \
      46             :         } while (0)
      47             : 
      48             : #define LITERAL_INFO_OBJ(n, kind, merge, slots, related, _num) do { \
      49             :                 info[n].flags = (LITERAL_EX_OBJ | ((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \
      50             :                 info[n].u.num = (_num); \
      51             :         } while (0)
      52             : 
      53          18 : static void optimizer_literal_obj_info(literal_info   *info,
      54             :                                        zend_uchar      op_type,
      55             :                                        znode_op        op,
      56             :                                        int             constant,
      57             :                                        zend_uint       kind,
      58             :                                        zend_uint       slots,
      59             :                                        zend_uint       related,
      60             :                                        zend_op_array  *op_array)
      61             : {
      62             :         /* For now we merge only $this object properties and methods.
      63             :          * In general it's also possible to do it for any CV variable as well,
      64             :          * but it would require complex dataflow and/or type analysis.
      65             :          */
      66          18 :         if (Z_TYPE(op_array->literals[constant].constant) == IS_STRING &&
      67             :             op_type == IS_UNUSED) {
      68           0 :                 LITERAL_INFO_OBJ(constant, kind, 1, slots, related, op_array->this_var);
      69             :         } else {
      70          18 :                 LITERAL_INFO(constant, kind, 0, slots, related);
      71             :         }
      72          18 : }
      73             : 
      74         124 : static void optimizer_literal_class_info(literal_info   *info,
      75             :                                          zend_uchar      op_type,
      76             :                                          znode_op        op,
      77             :                                          int             constant,
      78             :                                          zend_uint       kind,
      79             :                                          zend_uint       slots,
      80             :                                          zend_uint       related,
      81             :                                          zend_op_array  *op_array)
      82             : {
      83         124 :         if (op_type == IS_CONST) {
      84         117 :                 LITERAL_INFO_CLASS(constant, kind, 1, slots, related, op.constant);
      85             :         } else {
      86           7 :                 LITERAL_INFO(constant, kind, 0, slots, related);
      87             :         }
      88         124 : }
      89             : 
      90         451 : static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC)
      91             : {
      92             :         zend_op *opline, *end;
      93             :         int i, j, n, *pos, *map, cache_slots;
      94             :         ulong h;
      95             :         literal_info *info;
      96         451 :         int l_null = -1;
      97         451 :         int l_false = -1;
      98         451 :         int l_true = -1;
      99             :         HashTable hash;
     100             :         char *key;
     101             :         int key_len;
     102             : 
     103         451 :         if (op_array->last_literal) {
     104         451 :                 info = (literal_info*)ecalloc(op_array->last_literal, sizeof(literal_info));
     105             : 
     106             :             /* Mark literals of specific types */
     107         451 :                 opline = op_array->opcodes;
     108         451 :                 end = opline + op_array->last;
     109        5920 :                 while (opline < end) {
     110        5018 :                         switch (opline->opcode) {
     111             :                                 case ZEND_DO_FCALL:
     112         865 :                                         LITERAL_INFO(opline->op1.constant, LITERAL_FUNC, 1, 1, 1);
     113         865 :                                         break;
     114             :                                 case ZEND_INIT_FCALL_BY_NAME:
     115           0 :                                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     116           0 :                                                 LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2);
     117             :                                         }
     118           0 :                                         break;
     119             :                                 case ZEND_INIT_NS_FCALL_BY_NAME:
     120           2 :                                         LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 3);
     121           2 :                                         break;
     122             :                                 case ZEND_INIT_METHOD_CALL:
     123          18 :                                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     124          36 :                                                 optimizer_literal_obj_info(
     125             :                                                         info,
     126          18 :                                                         opline->op1_type,
     127             :                                                         opline->op1,
     128          18 :                                                         opline->op2.constant,
     129             :                                                         LITERAL_METHOD, 2, 2,
     130             :                                                         op_array);
     131             :                                         }
     132          18 :                                         break;
     133             :                                 case ZEND_INIT_STATIC_METHOD_CALL:
     134         116 :                                         if (ZEND_OP1_TYPE(opline) == IS_CONST) {
     135         111 :                                                 LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2);
     136             :                                         }
     137         116 :                                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     138         348 :                                                 optimizer_literal_class_info(
     139             :                                                         info,
     140         116 :                                                         opline->op1_type,
     141             :                                                         opline->op1,
     142         116 :                                                         opline->op2.constant,
     143         116 :                                                         LITERAL_STATIC_METHOD, (ZEND_OP1_TYPE(opline) == IS_CONST) ? 1 : 2, 2,
     144             :                                                         op_array);
     145             :                                         }
     146         116 :                                         break;
     147             :                                 case ZEND_CATCH:
     148           8 :                                         LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2);
     149           8 :                                         break;
     150             :                                 case ZEND_FETCH_CONSTANT:
     151           3 :                                         if (ZEND_OP1_TYPE(opline) == IS_UNUSED) {
     152           0 :                                                 if ((opline->extended_value & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
     153           0 :                                                         LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 5);
     154             :                                                 } else {
     155           0 :                                                         LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 3);
     156             :                                                 }
     157             :                                         } else {
     158           3 :                                                 if (ZEND_OP1_TYPE(opline) == IS_CONST) {
     159           3 :                                                         LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2);
     160             :                                                 }
     161           9 :                                                 optimizer_literal_class_info(
     162             :                                                         info,
     163           3 :                                                         opline->op1_type,
     164             :                                                         opline->op1,
     165           3 :                                                         opline->op2.constant,
     166           3 :                                                         LITERAL_CLASS_CONST, (ZEND_OP1_TYPE(opline) == IS_CONST) ? 1 : 2, 1,
     167             :                                                         op_array);
     168             :                                         }
     169           3 :                                         break;
     170             :                                 case ZEND_FETCH_R:
     171             :                                 case ZEND_FETCH_W:
     172             :                                 case ZEND_FETCH_RW:
     173             :                                 case ZEND_FETCH_IS:
     174             :                                 case ZEND_FETCH_UNSET:
     175             :                                 case ZEND_FETCH_FUNC_ARG:
     176             :                                 case ZEND_UNSET_VAR:
     177             :                                 case ZEND_ISSET_ISEMPTY_VAR:
     178         413 :                                         if (ZEND_OP2_TYPE(opline) == IS_UNUSED) {
     179         408 :                                                 if (ZEND_OP1_TYPE(opline) == IS_CONST) {
     180         408 :                                                         LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1);
     181             :                                                 }
     182             :                                         } else {
     183           5 :                                                 if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     184           3 :                                                         LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2);
     185             :                                                 }
     186           5 :                                                 if (ZEND_OP1_TYPE(opline) == IS_CONST) {
     187          10 :                                                         optimizer_literal_class_info(
     188             :                                                                 info,
     189           5 :                                                                 opline->op2_type,
     190             :                                                                 opline->op2,
     191           5 :                                                                 opline->op1.constant,
     192             :                                                                 LITERAL_STATIC_PROPERTY, 2, 1,
     193             :                                                                 op_array);
     194             :                                                 }
     195             :                                         }
     196         413 :                                         break;
     197             :                                 case ZEND_FETCH_CLASS:
     198             :                                 case ZEND_ADD_INTERFACE:
     199             :                                 case ZEND_ADD_TRAIT:
     200          18 :                                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     201          11 :                                                 LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2);
     202             :                                         }
     203          18 :                                         break;
     204             :                                 case ZEND_ASSIGN_OBJ:
     205             :                                 case ZEND_FETCH_OBJ_R:
     206             :                                 case ZEND_FETCH_OBJ_W:
     207             :                                 case ZEND_FETCH_OBJ_RW:
     208             :                                 case ZEND_FETCH_OBJ_IS:
     209             :                                 case ZEND_FETCH_OBJ_UNSET:
     210             :                                 case ZEND_FETCH_OBJ_FUNC_ARG:
     211             :                                 case ZEND_UNSET_OBJ:
     212             :                                 case ZEND_PRE_INC_OBJ:
     213             :                                 case ZEND_PRE_DEC_OBJ:
     214             :                                 case ZEND_POST_INC_OBJ:
     215             :                                 case ZEND_POST_DEC_OBJ:
     216             :                                 case ZEND_ISSET_ISEMPTY_PROP_OBJ:
     217           0 :                                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     218           0 :                                                 optimizer_literal_obj_info(
     219             :                                                         info,
     220           0 :                                                         opline->op1_type,
     221             :                                                         opline->op1,
     222           0 :                                                         opline->op2.constant,
     223             :                                                         LITERAL_PROPERTY, 2, 1,
     224             :                                                         op_array);
     225             :                                         }
     226           0 :                                         break;
     227             :                                 case ZEND_ASSIGN_ADD:
     228             :                                 case ZEND_ASSIGN_SUB:
     229             :                                 case ZEND_ASSIGN_MUL:
     230             :                                 case ZEND_ASSIGN_DIV:
     231             :                                 case ZEND_ASSIGN_MOD:
     232             :                                 case ZEND_ASSIGN_SL:
     233             :                                 case ZEND_ASSIGN_SR:
     234             :                                 case ZEND_ASSIGN_CONCAT:
     235             :                                 case ZEND_ASSIGN_BW_OR:
     236             :                                 case ZEND_ASSIGN_BW_AND:
     237             :                                 case ZEND_ASSIGN_BW_XOR:
     238          10 :                                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     239           3 :                                                 if (opline->extended_value == ZEND_ASSIGN_OBJ) {
     240           0 :                                                         optimizer_literal_obj_info(
     241             :                                                                 info,
     242           0 :                                                                 opline->op1_type,
     243             :                                                                 opline->op1,
     244           0 :                                                                 opline->op2.constant,
     245             :                                                                 LITERAL_PROPERTY, 2, 1,
     246             :                                                                 op_array);
     247             :                                                 } else {
     248           3 :                                                         LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1, 0, 1);
     249             :                                                 }
     250             :                                         }
     251          10 :                                         break;
     252             :                                 default:
     253        3565 :                                         if (ZEND_OP1_TYPE(opline) == IS_CONST) {
     254        1550 :                                                 LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1);
     255             :                                         }
     256        3565 :                                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     257         474 :                                                 LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1, 0, 1);
     258             :                                         }
     259             :                                         break;
     260             :                         }
     261        5018 :                         opline++;
     262             :                 }
     263             : 
     264             : #if DEBUG_COMPACT_LITERALS
     265             :                 {
     266             :                         int i, use_copy;
     267             :                         fprintf(stderr, "File %s func %s\n", op_array->filename,
     268             :                                         op_array->function_name? op_array->function_name : "main");
     269             :                         fprintf(stderr, "Literlas table size %d\n", op_array->last_literal);
     270             : 
     271             :                         for (i = 0; i < op_array->last_literal; i++) {
     272             :                                 zval zv = op_array->literals[i].constant;
     273             :                                 zend_make_printable_zval(&op_array->literals[i].constant, &zv, &use_copy);
     274             :                                 fprintf(stderr, "Literal %d, val (%d):%s\n", i, Z_STRLEN(zv), Z_STRVAL(zv));
     275             :                                 if (use_copy) {
     276             :                                         zval_dtor(&zv);
     277             :                                 }
     278             :                         }
     279             :                         fflush(stderr);
     280             :                 }
     281             : #endif
     282             : 
     283             :                 /* Merge equal constants */
     284         451 :                 j = 0; cache_slots = 0;
     285         451 :                 zend_hash_init(&hash, 16, NULL, NULL, 0);
     286         451 :                 map = (int*)ecalloc(op_array->last_literal, sizeof(int));
     287        5704 :                 for (i = 0; i < op_array->last_literal; i++) {
     288        5253 :                         if (!info[i].flags) {
     289             :                                 /* unsed literal */
     290        1673 :                                 zval_dtor(&op_array->literals[i].constant);
     291        1673 :                                 continue;
     292             :                         }
     293        3580 :                         switch (Z_TYPE(op_array->literals[i].constant)) {
     294             :                                 case IS_NULL:
     295          54 :                                         if (l_null < 0) {
     296          48 :                                                 l_null = j;
     297          48 :                                                 if (i != j) {
     298          26 :                                                         op_array->literals[j] = op_array->literals[i];
     299          26 :                                                         info[j] = info[i];
     300             :                                                 }
     301          48 :                                                 j++;
     302             :                                         }
     303          54 :                                         map[i] = l_null;
     304          54 :                                         break;
     305             :                                 case IS_BOOL:
     306          44 :                                         if (Z_LVAL(op_array->literals[i].constant)) {
     307          17 :                                                 if (l_true < 0) {
     308          14 :                                                         l_true = j;
     309          14 :                                                         if (i != j) {
     310          11 :                                                                 op_array->literals[j] = op_array->literals[i];
     311          11 :                                                                 info[j] = info[i];
     312             :                                                         }
     313          14 :                                                         j++;
     314             :                                                 }
     315          17 :                                                 map[i] = l_true;
     316             :                                         } else {
     317          27 :                                                 if (l_false < 0) {
     318          24 :                                                         l_false = j;
     319          24 :                                                         if (i != j) {
     320          22 :                                                                 op_array->literals[j] = op_array->literals[i];
     321          22 :                                                                 info[j] = info[i];
     322             :                                                         }
     323          24 :                                                         j++;
     324             :                                                 }
     325          27 :                                                 map[i] = l_false;
     326             :                                         }
     327          44 :                                         break;
     328             :                                 case IS_LONG:
     329         660 :                                         if (zend_hash_index_find(&hash, Z_LVAL(op_array->literals[i].constant), (void**)&pos) == SUCCESS) {
     330         134 :                                                 map[i] = *pos;
     331             :                                         } else {
     332         526 :                                                 map[i] = j;
     333         526 :                                                 zend_hash_index_update(&hash, Z_LVAL(op_array->literals[i].constant), (void**)&j, sizeof(int), NULL);
     334         526 :                                                 if (i != j) {
     335         394 :                                                         op_array->literals[j] = op_array->literals[i];
     336         394 :                                                         info[j] = info[i];
     337             :                                                 }
     338         526 :                                                 j++;
     339             :                                         }
     340         660 :                                         break;
     341             :                                 case IS_DOUBLE:
     342           0 :                                         if (zend_hash_find(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double), (void**)&pos) == SUCCESS) {
     343           0 :                                                 map[i] = *pos;
     344             :                                         } else {
     345           0 :                                                 map[i] = j;
     346           0 :                                                 zend_hash_add(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double), (void**)&j, sizeof(int), NULL);
     347           0 :                                                 if (i != j) {
     348           0 :                                                         op_array->literals[j] = op_array->literals[i];
     349           0 :                                                         info[j] = info[i];
     350             :                                                 }
     351           0 :                                                 j++;
     352             :                                         }
     353           0 :                                         break;
     354             :                                 case IS_STRING:
     355             :                                 case IS_CONSTANT:
     356        2822 :                                         if (info[i].flags & LITERAL_MAY_MERGE) {
     357        2797 :                                                 if (info[i].flags & LITERAL_EX_OBJ) {
     358           0 :                                                         key_len = MAX_LENGTH_OF_LONG + sizeof("->") + Z_STRLEN(op_array->literals[i].constant);
     359           0 :                                                         key = emalloc(key_len);
     360           0 :                                                         key_len = snprintf(key, key_len-1, "%d->%s", info[i].u.num, Z_STRVAL(op_array->literals[i].constant));
     361        2797 :                                                 } else if (info[i].flags & LITERAL_EX_CLASS) {
     362         117 :                                                         zval *class_name = &op_array->literals[(info[i].u.num < i) ? map[info[i].u.num] : info[i].u.num].constant;
     363         117 :                                                         key_len = Z_STRLEN_P(class_name) + sizeof("::") + Z_STRLEN(op_array->literals[i].constant);
     364         117 :                                                         key = emalloc(key_len);
     365         117 :                                                         memcpy(key, Z_STRVAL_P(class_name), Z_STRLEN_P(class_name));
     366         117 :                                                         memcpy(key + Z_STRLEN_P(class_name), "::", sizeof("::") - 1);
     367         234 :                                                         memcpy(key + Z_STRLEN_P(class_name) + sizeof("::") - 1,
     368         117 :                                                                 Z_STRVAL(op_array->literals[i].constant),
     369         117 :                                                                 Z_STRLEN(op_array->literals[i].constant) + 1);
     370             :                                                 } else {
     371        2680 :                                                         key = Z_STRVAL(op_array->literals[i].constant);
     372        2680 :                                                         key_len = Z_STRLEN(op_array->literals[i].constant)+1;
     373             :                                                 }
     374        2797 :                                                 h = zend_hash_func(key, key_len);
     375        2797 :                                                 h += info[i].flags;
     376             :                                         }
     377        7623 :                                         if ((info[i].flags & LITERAL_MAY_MERGE) &&
     378        2797 :                                                 zend_hash_quick_find(&hash, key, key_len, h, (void**)&pos) == SUCCESS &&
     379         668 :                                                 Z_TYPE(op_array->literals[i].constant) == Z_TYPE(op_array->literals[*pos].constant) &&
     380         668 :                                                 info[i].flags == info[*pos].flags) {
     381             : 
     382         668 :                                                 if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) {
     383           3 :                                                         efree(key);
     384             :                                                 }
     385         668 :                                                 map[i] = *pos;
     386         668 :                                                 zval_dtor(&op_array->literals[i].constant);
     387         668 :                                                 n = LITERAL_NUM_RELATED(info[i].flags);
     388        1354 :                                                 while (n > 1) {
     389          18 :                                                         i++;
     390          18 :                                                         zval_dtor(&op_array->literals[i].constant);
     391          18 :                                                         n--;
     392             :                                                 }
     393             :                                         } else {
     394        2154 :                                                 map[i] = j;
     395        2154 :                                                 if (info[i].flags & LITERAL_MAY_MERGE) {
     396        2129 :                                                         zend_hash_quick_add(&hash, key, key_len, h, (void**)&j, sizeof(int), NULL);
     397        2129 :                                                         if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) {
     398         114 :                                                                 efree(key);
     399             :                                                         }
     400             :                                                 }
     401        2154 :                                                 if (i != j) {
     402        1134 :                                                         op_array->literals[j] = op_array->literals[i];
     403        1134 :                                                         info[j] = info[i];
     404             :                                                 }
     405        2154 :                                                 if (!op_array->literals[j].hash_value) {
     406        1066 :                                                         if (IS_INTERNED(Z_STRVAL(op_array->literals[j].constant))) {
     407           0 :                                                                 op_array->literals[j].hash_value = INTERNED_HASH(Z_STRVAL(op_array->literals[j].constant));
     408             :                                                         } else {
     409        1066 :                                                                 op_array->literals[j].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[j].constant), Z_STRLEN(op_array->literals[j].constant)+1);
     410             :                                                         }
     411             :                                                 }
     412        2154 :                                                 if (LITERAL_NUM_SLOTS(info[i].flags)) {
     413         746 :                                                         op_array->literals[j].cache_slot = cache_slots;
     414         746 :                                                         cache_slots += LITERAL_NUM_SLOTS(info[i].flags);
     415             :                                                 }
     416        2154 :                                                 j++;
     417        2154 :                                                 n = LITERAL_NUM_RELATED(info[i].flags);
     418        4564 :                                                 while (n > 1) {
     419         256 :                                                         i++;
     420         256 :                                                         if (i != j) op_array->literals[j] = op_array->literals[i];
     421         256 :                                                         if (!op_array->literals[j].hash_value) {
     422           0 :                                                                 if (IS_INTERNED(Z_STRVAL(op_array->literals[j].constant))) {
     423           0 :                                                                         op_array->literals[j].hash_value = INTERNED_HASH(Z_STRVAL(op_array->literals[j].constant));
     424             :                                                                 } else {
     425           0 :                                                                         op_array->literals[j].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[j].constant), Z_STRLEN(op_array->literals[j].constant)+1);
     426             :                                                                 }
     427             :                                                         }
     428         256 :                                                         j++;
     429         256 :                                                         n--;
     430             :                                                 }
     431             :                                         }
     432        2822 :                                         break;
     433             :                                 default:
     434             :                                         /* don't merge other types */
     435           0 :                                         map[i] = j;
     436           0 :                                         if (i != j) {
     437           0 :                                                 op_array->literals[j] = op_array->literals[i];
     438           0 :                                                 info[j] = info[i];
     439             :                                         }
     440           0 :                                         j++;
     441             :                                         break;
     442             :                         }
     443             :                 }
     444         451 :                 zend_hash_destroy(&hash);
     445         451 :                 op_array->last_literal = j;
     446         451 :                 op_array->last_cache_slot = cache_slots;
     447             : 
     448             :             /* Update opcodes to use new literals table */
     449         451 :                 opline = op_array->opcodes;
     450         451 :                 end = opline + op_array->last;
     451        5920 :                 while (opline < end) {
     452        5018 :                         if (ZEND_OP1_TYPE(opline) == IS_CONST) {
     453        2950 :                                 opline->op1.constant = map[opline->op1.constant];
     454             :                         }
     455        5018 :                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
     456         630 :                                 opline->op2.constant = map[opline->op2.constant];
     457             :                         }
     458        5018 :                         opline++;
     459             :                 }
     460         451 :                 efree(map);
     461         451 :                 efree(info);
     462             : 
     463             : #if DEBUG_COMPACT_LITERALS
     464             :                 {
     465             :                         int i, use_copy;
     466             :                         fprintf(stderr, "Optimized literlas table size %d\n", op_array->last_literal);
     467             : 
     468             :                         for (i = 0; i < op_array->last_literal; i++) {
     469             :                                 zval zv = op_array->literals[i].constant;
     470             :                                 zend_make_printable_zval(&op_array->literals[i].constant, &zv, &use_copy);
     471             :                                 fprintf(stderr, "Literal %d, val (%d):%s\n", i, Z_STRLEN(zv), Z_STRVAL(zv));
     472             :                                 if (use_copy) {
     473             :                                         zval_dtor(&zv);
     474             :                                 }
     475             :                         }
     476             :                         fflush(stderr);
     477             :                 }
     478             : #endif
     479             :         }
     480         451 : }
     481             : #endif

Generated by: LCOV version 1.10

Generated at Tue, 22 Jul 2014 01:33:24 +0000 (6 days ago)

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