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

Generated by: LCOV version 1.10

Generated at Sun, 28 Aug 2016 17:10:05 +0000 (32 hours ago)

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