root/ext/opcache/zend_persist_calc.c

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

DEFINITIONS

This source file includes following definitions.
  1. zend_hash_persist_calc
  2. zend_persist_ast_calc
  3. zend_persist_zval_calc
  4. zend_persist_zval_ptr_calc
  5. zend_persist_op_array_calc
  6. zend_persist_property_info_calc
  7. zend_persist_class_entry_calc
  8. zend_accel_persist_class_table_calc
  9. zend_accel_script_persist_calc

   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 START_SIZE()       uint memory_used = 0
  30 #define ADD_DUP_SIZE(m,s)  memory_used += zend_shared_memdup_size((void*)m, s)
  31 #define ADD_SIZE(m)        memory_used += ZEND_ALIGNED_SIZE(m)
  32 #define RETURN_SIZE()      return memory_used
  33 
  34 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
  35 # define ADD_INTERNED_STRING(str, len) do { \
  36                 if (!IS_INTERNED(str)) { \
  37                         const char *tmp = accel_new_interned_string((str), (len), 1 TSRMLS_CC); \
  38                         if (tmp != (str)) { \
  39                                 (str) = (char*)tmp; \
  40                         } else { \
  41                                 ADD_DUP_SIZE((str), (len)); \
  42                         } \
  43                 } \
  44         } while (0)
  45 #else
  46 # define ADD_INTERNED_STRING(str, len) ADD_DUP_SIZE((str), (len))
  47 #endif
  48 
  49 static uint zend_persist_zval_ptr_calc(zval **zp TSRMLS_DC);
  50 static uint zend_persist_zval_calc(zval *z TSRMLS_DC);
  51 
  52 static uint zend_hash_persist_calc(HashTable *ht, int (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC)
  53 {
  54         Bucket *p = ht->pListHead;
  55         START_SIZE();
  56 
  57         while (p) {
  58                 /* persist bucket and key */
  59 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
  60                 ADD_DUP_SIZE(p, sizeof(Bucket));
  61                 if (p->nKeyLength) {
  62                         const char *tmp = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
  63                         if (tmp != p->arKey) {
  64                                 p->arKey = tmp;
  65                         } else {
  66                                 ADD_DUP_SIZE(p->arKey, p->nKeyLength);
  67                         }
  68                 }
  69 #else
  70                 ADD_DUP_SIZE(p, sizeof(Bucket) - 1 + p->nKeyLength);
  71 #endif
  72 
  73                 /* persist data pointer in bucket */
  74                 if (!p->pDataPtr) {
  75                         ADD_DUP_SIZE(p->pData, el_size);
  76                 }
  77 
  78                 /* persist the data itself */
  79                 if (pPersistElement) {
  80                         ADD_SIZE(pPersistElement(p->pData TSRMLS_CC));
  81                 }
  82 
  83                 p = p->pListNext;
  84         }
  85 
  86 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
  87         if (ht->nTableMask) {
  88                 ADD_DUP_SIZE(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
  89         }
  90 #else
  91         ADD_DUP_SIZE(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
  92 #endif
  93 
  94         RETURN_SIZE();
  95 }
  96 
  97 #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
  98 static uint zend_persist_ast_calc(zend_ast *ast TSRMLS_DC)
  99 {
 100         int i;
 101         START_SIZE();
 102 
 103         if (ast->kind == ZEND_CONST) {
 104                 ADD_SIZE(sizeof(zend_ast) + sizeof(zval));
 105                 ADD_SIZE(zend_persist_zval_calc(ast->u.val TSRMLS_CC));
 106         } else {
 107                 ADD_SIZE(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1));
 108                 for (i = 0; i < ast->children; i++) {
 109                         if ((&ast->u.child)[i]) {
 110                                 ADD_SIZE(zend_persist_ast_calc((&ast->u.child)[i] TSRMLS_CC));
 111                         }
 112                 }
 113         }
 114         RETURN_SIZE();
 115 }
 116 #endif
 117 
 118 static uint zend_persist_zval_calc(zval *z TSRMLS_DC)
 119 {
 120         START_SIZE();
 121 
 122 #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
 123         switch (z->type & IS_CONSTANT_TYPE_MASK) {
 124 #else
 125         switch (z->type & ~IS_CONSTANT_INDEX) {
 126 #endif
 127                 case IS_STRING:
 128                 case IS_CONSTANT:
 129                         ADD_INTERNED_STRING(Z_STRVAL_P(z), Z_STRLEN_P(z) + 1);
 130                         break;
 131                 case IS_ARRAY:
 132 #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
 133                 case IS_CONSTANT_ARRAY:
 134 #endif
 135                         ADD_DUP_SIZE(z->value.ht, sizeof(HashTable));
 136                         ADD_SIZE(zend_hash_persist_calc(z->value.ht, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
 137                         break;
 138 #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
 139                 case IS_CONSTANT_AST:
 140                         ADD_SIZE(zend_persist_ast_calc(Z_AST_P(z) TSRMLS_CC));
 141                         break;
 142 #endif
 143         }
 144         RETURN_SIZE();
 145 }
 146 
 147 static uint zend_persist_zval_ptr_calc(zval **zp TSRMLS_DC)
 148 {
 149         START_SIZE();
 150         zval *new_ptr = zend_shared_alloc_get_xlat_entry(*zp);
 151 
 152         if (!new_ptr) {
 153                 ADD_DUP_SIZE(*zp, sizeof(zval));
 154                 ADD_SIZE(zend_persist_zval_calc(*zp TSRMLS_CC));
 155         }
 156         RETURN_SIZE();
 157 }
 158 
 159 static uint zend_persist_op_array_calc(zend_op_array *op_array TSRMLS_DC)
 160 {
 161         START_SIZE();
 162 
 163         if (op_array->type != ZEND_USER_FUNCTION) {
 164                 return 0;
 165         }
 166 
 167         if (op_array->filename) {
 168                 ADD_DUP_SIZE(op_array->filename, strlen(op_array->filename) + 1);
 169         }
 170 
 171 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 172         if (op_array->literals && !zend_shared_alloc_get_xlat_entry(op_array->literals)) {
 173                 zend_literal *p = op_array->literals;
 174                 zend_literal *end = p + op_array->last_literal;
 175                 ADD_DUP_SIZE(op_array->literals, sizeof(zend_literal) * op_array->last_literal);
 176                 while (p < end) {
 177                         ADD_SIZE(zend_persist_zval_calc(&p->constant TSRMLS_CC));
 178                         p++;
 179                 }
 180         }
 181 #endif
 182 
 183         if (!zend_shared_alloc_get_xlat_entry(op_array->opcodes)) {
 184 #if ZEND_EXTENSION_API_NO <= PHP_5_3_X_API_NO
 185                 zend_op *opline = op_array->opcodes;
 186                 zend_op *end = op_array->opcodes + op_array->last;
 187 
 188                 ADD_DUP_SIZE(op_array->opcodes, sizeof(zend_op) * op_array->last);
 189                 while (opline<end) {
 190                         if (opline->op1.op_type == IS_CONST) {
 191                                 ADD_SIZE(zend_persist_zval_calc(&opline->op1.u.constant TSRMLS_CC));
 192                         }
 193                         if (opline->op2.op_type == IS_CONST) {
 194                                 ADD_SIZE(zend_persist_zval_calc(&opline->op2.u.constant TSRMLS_CC));
 195                         }
 196                         opline++;
 197                 }
 198 #else
 199                 ADD_DUP_SIZE(op_array->opcodes, sizeof(zend_op) * op_array->last);
 200 #endif
 201         }
 202 
 203         if (op_array->function_name) {
 204                 ADD_DUP_SIZE(op_array->function_name, strlen(op_array->function_name) + 1);
 205     }
 206 
 207         if (op_array->arg_info &&
 208                 !zend_shared_alloc_get_xlat_entry(op_array->arg_info)) {
 209                 zend_uint i;
 210 
 211                 ADD_DUP_SIZE(op_array->arg_info, sizeof(zend_arg_info) * op_array->num_args);
 212                 for (i = 0; i < op_array->num_args; i++) {
 213                         if (op_array->arg_info[i].name) {
 214                                 ADD_INTERNED_STRING(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1);
 215                         }
 216                         if (op_array->arg_info[i].class_name) {
 217                                 ADD_INTERNED_STRING(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1);
 218                         }
 219 
 220                 }
 221         }
 222 
 223         if (op_array->brk_cont_array) {
 224                 ADD_DUP_SIZE(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont);
 225         }
 226 
 227         if (op_array->static_variables) {
 228                 ADD_DUP_SIZE(op_array->static_variables, sizeof(HashTable));
 229                 ADD_SIZE(zend_hash_persist_calc(op_array->static_variables, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
 230         }
 231 
 232         if (ZCG(accel_directives).save_comments && op_array->doc_comment) {
 233                 ADD_DUP_SIZE(op_array->doc_comment, op_array->doc_comment_len + 1);
 234         }
 235 
 236         if (op_array->try_catch_array) {
 237                 ADD_DUP_SIZE(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch);
 238         }
 239 
 240         if (op_array->vars && !zend_shared_alloc_get_xlat_entry(op_array->vars)) {
 241                 int i;
 242 
 243                 ADD_DUP_SIZE(op_array->vars, sizeof(zend_compiled_variable) * op_array->last_var);
 244                 for (i = 0; i < op_array->last_var; i++) {
 245                         ADD_INTERNED_STRING(op_array->vars[i].name, op_array->vars[i].name_len + 1);
 246                 }
 247         }
 248 
 249         RETURN_SIZE();
 250 }
 251 
 252 static uint zend_persist_property_info_calc(zend_property_info *prop TSRMLS_DC)
 253 {
 254         START_SIZE();
 255         ADD_INTERNED_STRING(prop->name, prop->name_length + 1);
 256         if (ZCG(accel_directives).save_comments && prop->doc_comment) {
 257                 ADD_DUP_SIZE(prop->doc_comment, prop->doc_comment_len + 1);
 258         }
 259         RETURN_SIZE();
 260 }
 261 
 262 static uint zend_persist_class_entry_calc(zend_class_entry **pce TSRMLS_DC)
 263 {
 264         zend_class_entry *ce = *pce;
 265         START_SIZE();
 266 
 267         if (ce->type == ZEND_USER_CLASS) {
 268                 ADD_DUP_SIZE(ce, sizeof(zend_class_entry));
 269                 ADD_INTERNED_STRING(ce->name, ce->name_length + 1);
 270                 ADD_SIZE(zend_hash_persist_calc(&ce->function_table, (int (*)(void* TSRMLS_DC)) zend_persist_op_array_calc, sizeof(zend_op_array) TSRMLS_CC));
 271 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 272                 if (ce->default_properties_table) {
 273                     int i;
 274 
 275                         ADD_SIZE(sizeof(zval*) * ce->default_properties_count);
 276                         for (i = 0; i < ce->default_properties_count; i++) {
 277                                 if (ce->default_properties_table[i]) {
 278                                         ADD_SIZE(zend_persist_zval_ptr_calc(&ce->default_properties_table[i] TSRMLS_CC));
 279                                 }
 280                         }
 281                 }
 282                 if (ce->default_static_members_table) {
 283                     int i;
 284 
 285                         ADD_SIZE(sizeof(zval*) * ce->default_static_members_count);
 286                         for (i = 0; i < ce->default_static_members_count; i++) {
 287                                 if (ce->default_static_members_table[i]) {
 288                                         ADD_SIZE(zend_persist_zval_ptr_calc(&ce->default_static_members_table[i] TSRMLS_CC));
 289                                 }
 290                         }
 291                 }
 292 #else
 293                 ADD_SIZE(zend_hash_persist_calc(&ce->default_properties, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
 294                 ADD_SIZE(zend_hash_persist_calc(&ce->default_static_members, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
 295 #endif
 296                 ADD_SIZE(zend_hash_persist_calc(&ce->constants_table, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
 297 
 298                 if (ZEND_CE_FILENAME(ce)) {
 299                         ADD_DUP_SIZE(ZEND_CE_FILENAME(ce), strlen(ZEND_CE_FILENAME(ce)) + 1);
 300                 }
 301                 if (ZCG(accel_directives).save_comments && ZEND_CE_DOC_COMMENT(ce)) {
 302                         ADD_DUP_SIZE(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce) + 1);
 303                 }
 304 
 305                 ADD_SIZE(zend_hash_persist_calc(&ce->properties_info, (int (*)(void* TSRMLS_DC)) zend_persist_property_info_calc, sizeof(zend_property_info) TSRMLS_CC));
 306 
 307 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 308                 if (ce->trait_aliases) {
 309                         int i = 0;
 310                         while (ce->trait_aliases[i]) {
 311                                 if (ce->trait_aliases[i]->trait_method) {
 312                                         if (ce->trait_aliases[i]->trait_method->method_name) {
 313                                                 ADD_SIZE(ce->trait_aliases[i]->trait_method->mname_len + 1);
 314                                         }
 315                                         if (ce->trait_aliases[i]->trait_method->class_name) {
 316                                                 ADD_SIZE(ce->trait_aliases[i]->trait_method->cname_len + 1);
 317                                         }
 318                                         ADD_SIZE(sizeof(zend_trait_method_reference));
 319                                 }
 320 
 321                                 if (ce->trait_aliases[i]->alias) {
 322                                         ADD_SIZE(ce->trait_aliases[i]->alias_len + 1);
 323                                 }
 324                                 ADD_SIZE(sizeof(zend_trait_alias));
 325                                 i++;
 326                         }
 327                         ADD_SIZE(sizeof(zend_trait_alias*) * (i + 1));
 328                 }
 329 
 330                 if (ce->trait_precedences) {
 331                         int i = 0;
 332 
 333                         while (ce->trait_precedences[i]) {
 334                                 ADD_SIZE(ce->trait_precedences[i]->trait_method->mname_len + 1);
 335                                 ADD_SIZE(ce->trait_precedences[i]->trait_method->cname_len + 1);
 336                                 ADD_SIZE(sizeof(zend_trait_method_reference));
 337 
 338                                 if (ce->trait_precedences[i]->exclude_from_classes) {
 339                                         int j = 0;
 340 
 341                                         while (ce->trait_precedences[i]->exclude_from_classes[j]) {
 342                                                 ADD_SIZE(strlen((char*)ce->trait_precedences[i]->exclude_from_classes[j]) + 1);
 343                                                 j++;
 344                                         }
 345                                         ADD_SIZE(sizeof(zend_class_entry*) * (j + 1));
 346                                 }
 347                                 ADD_SIZE(sizeof(zend_trait_precedence));
 348                                 i++;
 349                         }
 350                         ADD_SIZE(sizeof(zend_trait_precedence*) * (i + 1));
 351                 }
 352 #endif
 353         }
 354         RETURN_SIZE();
 355 }
 356 
 357 static uint zend_accel_persist_class_table_calc(HashTable *class_table TSRMLS_DC)
 358 {
 359         return zend_hash_persist_calc(class_table, (int (*)(void* TSRMLS_DC)) zend_persist_class_entry_calc, sizeof(zend_class_entry*) TSRMLS_CC);
 360 }
 361 
 362 uint zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, char *key, unsigned int key_length TSRMLS_DC)
 363 {
 364         START_SIZE();
 365 
 366         ADD_SIZE(zend_hash_persist_calc(&new_persistent_script->function_table, (int (*)(void* TSRMLS_DC)) zend_persist_op_array_calc, sizeof(zend_op_array) TSRMLS_CC));
 367         ADD_SIZE(zend_accel_persist_class_table_calc(&new_persistent_script->class_table TSRMLS_CC));
 368         ADD_SIZE(zend_persist_op_array_calc(&new_persistent_script->main_op_array TSRMLS_CC));
 369         ADD_DUP_SIZE(key, key_length + 1);
 370         ADD_DUP_SIZE(new_persistent_script->full_path, new_persistent_script->full_path_len + 1);
 371         ADD_DUP_SIZE(new_persistent_script, sizeof(zend_persistent_script));
 372 
 373         RETURN_SIZE();
 374 }

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