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 - zend_persist_calc.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 135 205 65.9 %
Date: 2015-07-05 Functions: 8 9 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend OPcache                                                         |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2015 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             : #include "zend.h"
      23             : #include "ZendAccelerator.h"
      24             : #include "zend_persist.h"
      25             : #include "zend_extensions.h"
      26             : #include "zend_shared_alloc.h"
      27             : #include "zend_operators.h"
      28             : 
      29             : #define ADD_DUP_SIZE(m,s)  ZCG(current_persistent_script)->size += zend_shared_memdup_size((void*)m, s)
      30             : #define ADD_SIZE(m)        ZCG(current_persistent_script)->size += ZEND_ALIGNED_SIZE(m)
      31             : 
      32             : #define ADD_ARENA_SIZE(m)        ZCG(current_persistent_script)->arena_size += ZEND_ALIGNED_SIZE(m)
      33             : 
      34             : # define ADD_STRING(str) \
      35             :                 ADD_DUP_SIZE((str), _STR_HEADER_SIZE + (str)->len + 1)
      36             : # define ADD_INTERNED_STRING(str, do_free) do { \
      37             :                 if (!IS_ACCEL_INTERNED(str)) { \
      38             :                         zend_string *tmp = accel_new_interned_string(str); \
      39             :                         if (tmp != (str)) { \
      40             :                                 if (do_free) { \
      41             :                                         /*zend_string_release(str);*/ \
      42             :                                 } \
      43             :                                 (str) = tmp; \
      44             :                         } else { \
      45             :                                 ADD_STRING(str); \
      46             :                         } \
      47             :                 } \
      48             :         } while (0)
      49             : 
      50             : static void zend_persist_zval_calc(zval *z);
      51             : 
      52         962 : static void zend_hash_persist_calc(HashTable *ht, void (*pPersistElement)(zval *pElement))
      53             : {
      54             :         uint idx;
      55             :         Bucket *p;
      56             : 
      57         962 :         if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) {
      58         466 :                 return;
      59             :         }
      60             : 
      61         976 :         if (!(ht->u.flags & HASH_FLAG_PACKED) && ht->nNumUsed < -(int32_t)ht->nTableMask / 2) {
      62             :                 /* compact table */
      63         480 :                 int32_t hash_size = -(int32_t)ht->nTableMask;
      64             : 
      65        6160 :                 while (hash_size >> 1 > ht->nNumUsed) {
      66        5200 :                         hash_size >>= 1;
      67             :                 }
      68         480 :                 ADD_SIZE(hash_size * sizeof(uint32_t) + ht->nNumUsed * sizeof(Bucket));
      69             :         } else {
      70          16 :                 ADD_SIZE(HT_USED_SIZE(ht));
      71             :         }
      72             : 
      73         681 :         for (idx = 0; idx < ht->nNumUsed; idx++) {
      74         185 :                 p = ht->arData + idx;
      75         370 :                 if (Z_TYPE(p->val) == IS_UNDEF) continue;
      76             : 
      77             :                 /* persist bucket and key */
      78         178 :                 if (p->key) {
      79         141 :                         zend_uchar flags = GC_FLAGS(p->key) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT);
      80         141 :                         ADD_INTERNED_STRING(p->key, 1);
      81         141 :                         GC_FLAGS(p->key) |= flags;
      82             :                 }
      83             : 
      84         178 :                 pPersistElement(&p->val);
      85             :         }
      86             : }
      87             : 
      88           0 : static void zend_persist_ast_calc(zend_ast *ast)
      89             : {
      90             :         uint32_t i;
      91             : 
      92           0 :         if (ast->kind == ZEND_AST_ZVAL) {
      93           0 :                 ADD_SIZE(sizeof(zend_ast_zval));
      94           0 :                 zend_persist_zval_calc(zend_ast_get_zval(ast));
      95           0 :         } else if (zend_ast_is_list(ast)) {
      96           0 :                 zend_ast_list *list = zend_ast_get_list(ast);
      97           0 :                 ADD_SIZE(sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
      98           0 :                 for (i = 0; i < list->children; i++) {
      99           0 :                         if (list->child[i]) {
     100           0 :                                 zend_persist_ast_calc(list->child[i]);
     101             :                         }
     102             :                 }
     103             :         } else {
     104           0 :                 uint32_t children = zend_ast_get_num_children(ast);
     105           0 :                 ADD_SIZE(sizeof(zend_ast) - sizeof(zend_ast *) + sizeof(zend_ast *) * children);
     106           0 :                 for (i = 0; i < children; i++) {
     107           0 :                         if (ast->child[i]) {
     108           0 :                                 zend_persist_ast_calc(ast->child[i]);
     109             :                         }
     110             :                 }
     111             :         }
     112           0 : }
     113             : 
     114        3139 : static void zend_persist_zval_calc(zval *z)
     115             : {
     116             :         zend_uchar flags;
     117             :         uint size;
     118             : 
     119        3139 :         switch (Z_TYPE_P(z)) {
     120             :                 case IS_STRING:
     121             :                 case IS_CONSTANT:
     122        2424 :                         flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT);
     123        2424 :                         ADD_INTERNED_STRING(Z_STR_P(z), 0);
     124        2424 :                         if (!Z_REFCOUNTED_P(z)) {
     125           0 :                                 Z_TYPE_FLAGS_P(z) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
     126             :                         }
     127        2424 :                         Z_GC_FLAGS_P(z) |= flags;
     128        2424 :                         break;
     129             :                 case IS_ARRAY:
     130          74 :                         size = zend_shared_memdup_size(Z_ARR_P(z), sizeof(zend_array));
     131          74 :                         if (size) {
     132          74 :                                 ADD_SIZE(size);
     133          74 :                                 zend_hash_persist_calc(Z_ARRVAL_P(z), zend_persist_zval_calc);
     134             :                         }
     135          74 :                         break;
     136             :                 case IS_REFERENCE:
     137           0 :                         size = zend_shared_memdup_size(Z_REF_P(z), sizeof(zend_reference));
     138           0 :                         if (size) {
     139           0 :                                 ADD_SIZE(size);
     140           0 :                                 zend_persist_zval_calc(Z_REFVAL_P(z));
     141             :                         }
     142           0 :                         break;
     143             :                 case IS_CONSTANT_AST:
     144           0 :                         size = zend_shared_memdup_size(Z_AST_P(z), sizeof(zend_ast_ref));
     145           0 :                         if (size) {
     146           0 :                                 ADD_SIZE(size);
     147           0 :                                 zend_persist_ast_calc(Z_ASTVAL_P(z));
     148             :                         }
     149             :                         break;
     150             :         }
     151        3139 : }
     152             : 
     153         460 : static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
     154             : {
     155         460 :         if (op_array->type != ZEND_USER_FUNCTION) {
     156           0 :                 return;
     157             :         }
     158             : 
     159         460 :         if (op_array->static_variables) {
     160          13 :                 if (!zend_shared_alloc_get_xlat_entry(op_array->static_variables)) {
     161          13 :                         HashTable *old = op_array->static_variables;
     162             : 
     163          13 :                         ADD_DUP_SIZE(op_array->static_variables, sizeof(HashTable));
     164          13 :                         zend_hash_persist_calc(op_array->static_variables, zend_persist_zval_calc);
     165          13 :                         zend_shared_alloc_register_xlat_entry(old, op_array->static_variables);
     166             :                 }
     167             :         }
     168             : 
     169         460 :         if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) {
     170             :                 /* already stored */
     171           0 :                 if (op_array->function_name) {
     172           0 :                         zend_string *new_name = zend_shared_alloc_get_xlat_entry(op_array->function_name);
     173           0 :                         if (IS_ACCEL_INTERNED(new_name)) {
     174           0 :                                 op_array->function_name = new_name;
     175             :                         }
     176             :                 }
     177           0 :                 return;
     178             :         }
     179             : 
     180         460 :         if (op_array->literals) {
     181         460 :                 zval *p = op_array->literals;
     182         460 :                 zval *end = p + op_array->last_literal;
     183         460 :                 ADD_DUP_SIZE(op_array->literals, sizeof(zval) * op_array->last_literal);
     184        3921 :                 while (p < end) {
     185        3001 :                         zend_persist_zval_calc(p);
     186        3001 :                         p++;
     187             :                 }
     188             :         }
     189             : 
     190         460 :         ADD_DUP_SIZE(op_array->opcodes, sizeof(zend_op) * op_array->last);
     191             : 
     192         460 :         if (op_array->function_name) {
     193          33 :                 zend_string *old_name = op_array->function_name;
     194          33 :                 zend_string *new_name = zend_shared_alloc_get_xlat_entry(old_name);
     195             : 
     196          33 :                 if (new_name) {
     197           0 :                         op_array->function_name = new_name;
     198             :                 } else {
     199          33 :                         ADD_INTERNED_STRING(op_array->function_name, 0);
     200          33 :                         zend_shared_alloc_register_xlat_entry(old_name, op_array->function_name);
     201             :                 }
     202             :     }
     203             : 
     204         460 :         if (op_array->filename) {
     205         460 :                 ADD_STRING(op_array->filename);
     206             :         }
     207             : 
     208         460 :         if (op_array->arg_info) {
     209          29 :                 zend_arg_info *arg_info = op_array->arg_info;
     210          29 :                 uint32_t num_args = op_array->num_args;
     211             :                 uint32_t i;
     212             : 
     213          29 :                 num_args = op_array->num_args;
     214          29 :                 if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
     215           0 :                         num_args++;
     216             :                 }
     217          29 :                 if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
     218           4 :                         arg_info--;
     219           4 :                         num_args++;
     220             :                 }
     221          29 :                 ADD_DUP_SIZE(arg_info, sizeof(zend_arg_info) * num_args);
     222          63 :                 for (i = 0; i < num_args; i++) {
     223          34 :                         if (arg_info[i].name) {
     224          30 :                                 ADD_INTERNED_STRING(arg_info[i].name, 1);
     225             :                         }
     226          34 :                         if (arg_info[i].class_name) {
     227           4 :                                 ADD_INTERNED_STRING(arg_info[i].class_name, 1);
     228             :                         }
     229             :                 }
     230             :         }
     231             : 
     232         460 :         if (op_array->brk_cont_array) {
     233          17 :                 ADD_DUP_SIZE(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont);
     234             :         }
     235             : 
     236         460 :         if (ZCG(accel_directives).save_comments && op_array->doc_comment) {
     237           0 :                 ADD_STRING(op_array->doc_comment);
     238             :         }
     239             : 
     240         460 :         if (op_array->try_catch_array) {
     241           8 :                 ADD_DUP_SIZE(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch);
     242             :         }
     243             : 
     244         460 :         if (op_array->vars) {
     245             :                 int i;
     246             : 
     247          72 :                 ADD_DUP_SIZE(op_array->vars, sizeof(zend_string*) * op_array->last_var);
     248         241 :                 for (i = 0; i < op_array->last_var; i++) {
     249         169 :                         ADD_INTERNED_STRING(op_array->vars[i], 0);
     250             :                 }
     251             :         }
     252             : }
     253             : 
     254          33 : static void zend_persist_op_array_calc(zval *zv)
     255             : {
     256          33 :         zend_op_array *op_array = Z_PTR_P(zv);
     257             : 
     258          33 :         if (op_array->type == ZEND_USER_FUNCTION/* &&
     259             :             (!op_array->refcount || *(op_array->refcount) > 1)*/) {
     260          33 :                 zend_op_array *old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
     261          33 :                 if (old_op_array) {
     262           0 :                         Z_PTR_P(zv) = old_op_array;
     263             :                 } else {
     264          33 :                         ADD_ARENA_SIZE(sizeof(zend_op_array));
     265          33 :                         zend_persist_op_array_calc_ex(Z_PTR_P(zv));
     266          33 :                         zend_shared_alloc_register_xlat_entry(op_array, Z_PTR_P(zv));
     267             :                 }
     268             :         } else {
     269           0 :                 ADD_ARENA_SIZE(sizeof(zend_op_array));
     270           0 :                 zend_persist_op_array_calc_ex(Z_PTR_P(zv));
     271             :         }
     272          33 : }
     273             : 
     274           2 : static void zend_persist_property_info_calc(zval *zv)
     275             : {
     276           2 :         zend_property_info *prop = Z_PTR_P(zv);
     277             : 
     278           2 :         if (!zend_shared_alloc_get_xlat_entry(prop)) {
     279           2 :                 zend_shared_alloc_register_xlat_entry(prop, prop);
     280           2 :                 ADD_ARENA_SIZE(sizeof(zend_property_info));
     281           2 :                 ADD_INTERNED_STRING(prop->name, 0);
     282           2 :                 if (ZCG(accel_directives).save_comments && prop->doc_comment) {
     283           0 :                         ADD_STRING(prop->doc_comment);
     284             :                 }
     285             :         }
     286           2 : }
     287             : 
     288           7 : static void zend_persist_class_entry_calc(zval *zv)
     289             : {
     290           7 :         zend_class_entry *ce = Z_PTR_P(zv);
     291             : 
     292           7 :         if (ce->type == ZEND_USER_CLASS) {
     293           7 :                 ADD_ARENA_SIZE(sizeof(zend_class_entry));
     294           7 :                 ADD_INTERNED_STRING(ce->name, 0);
     295           7 :                 zend_hash_persist_calc(&ce->function_table, zend_persist_op_array_calc);
     296           7 :                 if (ce->default_properties_table) {
     297             :                     int i;
     298             : 
     299           0 :                         ADD_SIZE(sizeof(zval) * ce->default_properties_count);
     300           0 :                         for (i = 0; i < ce->default_properties_count; i++) {
     301           0 :                                 zend_persist_zval_calc(&ce->default_properties_table[i]);
     302             :                         }
     303             :                 }
     304           7 :                 if (ce->default_static_members_table) {
     305             :                     int i;
     306             : 
     307           1 :                         ADD_SIZE(sizeof(zval) * ce->default_static_members_count);
     308           3 :                         for (i = 0; i < ce->default_static_members_count; i++) {
     309           2 :                                 zend_persist_zval_calc(&ce->default_static_members_table[i]);
     310             :                         }
     311             :                 }
     312           7 :                 zend_hash_persist_calc(&ce->constants_table, zend_persist_zval_calc);
     313             : 
     314           7 :                 if (ZEND_CE_FILENAME(ce)) {
     315           7 :                         ADD_STRING(ZEND_CE_FILENAME(ce));
     316             :                 }
     317           7 :                 if (ZCG(accel_directives).save_comments && ZEND_CE_DOC_COMMENT(ce)) {
     318           0 :                         ADD_STRING(ZEND_CE_DOC_COMMENT(ce));
     319             :                 }
     320             : 
     321           7 :                 zend_hash_persist_calc(&ce->properties_info, zend_persist_property_info_calc);
     322             : 
     323           7 :                 if (ce->trait_aliases) {
     324           0 :                         int i = 0;
     325           0 :                         while (ce->trait_aliases[i]) {
     326           0 :                                 if (ce->trait_aliases[i]->trait_method) {
     327           0 :                                         if (ce->trait_aliases[i]->trait_method->method_name) {
     328           0 :                                                 ADD_INTERNED_STRING(ce->trait_aliases[i]->trait_method->method_name, 0);
     329             :                                         }
     330           0 :                                         if (ce->trait_aliases[i]->trait_method->class_name) {
     331           0 :                                                 ADD_INTERNED_STRING(ce->trait_aliases[i]->trait_method->class_name, 0);
     332             :                                         }
     333           0 :                                         ADD_SIZE(sizeof(zend_trait_method_reference));
     334             :                                 }
     335             : 
     336           0 :                                 if (ce->trait_aliases[i]->alias) {
     337           0 :                                         ADD_INTERNED_STRING(ce->trait_aliases[i]->alias, 0);
     338             :                                 }
     339           0 :                                 ADD_SIZE(sizeof(zend_trait_alias));
     340           0 :                                 i++;
     341             :                         }
     342           0 :                         ADD_SIZE(sizeof(zend_trait_alias*) * (i + 1));
     343             :                 }
     344             : 
     345           7 :                 if (ce->trait_precedences) {
     346           0 :                         int i = 0;
     347             : 
     348           0 :                         while (ce->trait_precedences[i]) {
     349           0 :                                 ADD_INTERNED_STRING(ce->trait_precedences[i]->trait_method->method_name, 0);
     350           0 :                                 ADD_INTERNED_STRING(ce->trait_precedences[i]->trait_method->class_name, 0);
     351           0 :                                 ADD_SIZE(sizeof(zend_trait_method_reference));
     352             : 
     353           0 :                                 if (ce->trait_precedences[i]->exclude_from_classes) {
     354           0 :                                         int j = 0;
     355             : 
     356           0 :                                         while (ce->trait_precedences[i]->exclude_from_classes[j].class_name) {
     357           0 :                                                 ADD_INTERNED_STRING(ce->trait_precedences[i]->exclude_from_classes[j].class_name, 0);
     358           0 :                                                 j++;
     359             :                                         }
     360           0 :                                         ADD_SIZE(sizeof(zend_class_entry*) * (j + 1));
     361             :                                 }
     362           0 :                                 ADD_SIZE(sizeof(zend_trait_precedence));
     363           0 :                                 i++;
     364             :                         }
     365           0 :                         ADD_SIZE(sizeof(zend_trait_precedence*) * (i + 1));
     366             :                 }
     367             :         }
     368           7 : }
     369             : 
     370         427 : static void zend_accel_persist_class_table_calc(HashTable *class_table)
     371             : {
     372         427 :         zend_hash_persist_calc(class_table, zend_persist_class_entry_calc);
     373         427 : }
     374             : 
     375         427 : uint zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, char *key, unsigned int key_length)
     376             : {
     377         427 :         new_persistent_script->mem = NULL;
     378         427 :         new_persistent_script->size = 0;
     379         427 :         new_persistent_script->arena_mem = NULL;
     380         427 :         new_persistent_script->arena_size = 0;
     381         427 :         ZCG(current_persistent_script) = new_persistent_script;
     382             : 
     383         427 :         ADD_DUP_SIZE(new_persistent_script, sizeof(zend_persistent_script));
     384         427 :         if (key) {
     385         427 :                 ADD_DUP_SIZE(key, key_length + 1);
     386             :         }
     387         427 :         ADD_STRING(new_persistent_script->full_path);
     388             : 
     389             : #ifdef __SSE2__
     390             :         /* Align size to 64-byte boundary */
     391         427 :         new_persistent_script->size = (new_persistent_script->size + 63) & ~63;
     392             : #endif
     393             : 
     394         427 :         zend_accel_persist_class_table_calc(&new_persistent_script->class_table);
     395         427 :         zend_hash_persist_calc(&new_persistent_script->function_table, zend_persist_op_array_calc);
     396         427 :         zend_persist_op_array_calc_ex(&new_persistent_script->main_op_array);
     397             : 
     398             : #ifdef __SSE2__
     399             :         /* Align size to 64-byte boundary */
     400         427 :         new_persistent_script->arena_size = (new_persistent_script->arena_size + 63) & ~63;
     401             : #endif
     402             : 
     403         427 :         new_persistent_script->size += new_persistent_script->arena_size;
     404             : 
     405         427 :         ZCG(current_persistent_script) = NULL;
     406             : 
     407         427 :         return new_persistent_script->size;
     408             : }

Generated by: LCOV version 1.10

Generated at Sun, 05 Jul 2015 15:44:51 +0000 (28 hours ago)

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