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: 143 217 65.9 %
Date: 2016-02-09 Functions: 9 10 90.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Tue, 09 Feb 2016 10:48:46 +0000 (17 hours ago)

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