root/ext/opcache/zend_persist.c

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

DEFINITIONS

This source file includes following definitions.
  1. zend_hash_persist
  2. zend_persist_ast
  3. zend_persist_zval
  4. zend_persist_zval_ptr
  5. zend_protect_zval
  6. zend_persist_op_array_ex
  7. zend_persist_op_array
  8. zend_persist_property_info
  9. zend_persist_class_entry
  10. zend_update_property_info_ce
  11. zend_update_parent_ce
  12. zend_accel_persist_class_table
  13. zend_accel_script_persist
  14. zend_accel_script_persistable

   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_vm.h"
  28 #include "zend_constants.h"
  29 #include "zend_operators.h"
  30 
  31 #define zend_accel_store(p, size) \
  32             (p = _zend_shared_memdup((void*)p, size, 1 TSRMLS_CC))
  33 #define zend_accel_memdup(p, size) \
  34             _zend_shared_memdup((void*)p, size, 0 TSRMLS_CC)
  35 
  36 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
  37 # define zend_accel_memdup_interned_string(str, len) \
  38         IS_INTERNED(str) ? str : zend_accel_memdup(str, len)
  39 
  40 # define zend_accel_store_interned_string(str, len) do { \
  41                 if (!IS_INTERNED(str)) { zend_accel_store(str, len); } \
  42         } while (0)
  43 #else
  44 # define zend_accel_memdup_interned_string(str, len) \
  45         zend_accel_memdup(str, len)
  46 
  47 # define zend_accel_store_interned_string(str, len) \
  48         zend_accel_store(str, len)
  49 #endif
  50 
  51 typedef void (*zend_persist_func_t)(void * TSRMLS_DC);
  52 
  53 static void zend_persist_zval_ptr(zval **zp TSRMLS_DC);
  54 static void zend_persist_zval(zval *z TSRMLS_DC);
  55 
  56 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
  57 static const Bucket *uninitialized_bucket = NULL;
  58 #endif
  59 
  60 static void zend_hash_persist(HashTable *ht, void (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC)
  61 {
  62         Bucket *p = ht->pListHead;
  63         uint i;
  64 
  65         while (p) {
  66                 Bucket *q = p;
  67 
  68                 /* persist bucket and key */
  69 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
  70                 p = zend_accel_memdup(p, sizeof(Bucket));
  71                 if (p->nKeyLength) {
  72                         p->arKey = zend_accel_memdup_interned_string(p->arKey, p->nKeyLength);
  73                 }
  74 #else
  75                 p = zend_accel_memdup(p, sizeof(Bucket) - 1 + p->nKeyLength);
  76 #endif
  77 
  78                 /* persist data pointer in bucket */
  79                 if (!p->pDataPtr) {
  80                         zend_accel_store(p->pData, el_size);
  81                 } else {
  82                         /* Update p->pData to point to the new p->pDataPtr address, after the bucket relocation */
  83                         p->pData = &p->pDataPtr;
  84                 }
  85 
  86                 /* persist the data itself */
  87                 if (pPersistElement) {
  88                         pPersistElement(p->pData TSRMLS_CC);
  89                 }
  90 
  91                 /* update linked lists */
  92                 if (p->pLast) {
  93                         p->pLast->pNext = p;
  94                 }
  95                 if (p->pNext) {
  96                         p->pNext->pLast = p;
  97                 }
  98                 if (p->pListLast) {
  99                         p->pListLast->pListNext = p;
 100                 }
 101                 if (p->pListNext) {
 102                         p->pListNext->pListLast = p;
 103                 }
 104 
 105                 p = p->pListNext;
 106 
 107                 /* delete the old non-persistent bucket */
 108                 efree(q);
 109         }
 110 
 111         /* update linked lists */
 112         if (ht->pListHead) {
 113                 ht->pListHead = zend_shared_alloc_get_xlat_entry(ht->pListHead);
 114         }
 115         if (ht->pListTail) {
 116                 ht->pListTail = zend_shared_alloc_get_xlat_entry(ht->pListTail);
 117         }
 118         if (ht->pInternalPointer) {
 119                 ht->pInternalPointer = zend_shared_alloc_get_xlat_entry(ht->pInternalPointer);
 120         }
 121 
 122 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 123         /* Check if HastTable is initialized */
 124         if (ht->nTableMask) {
 125 #endif
 126                 if (ht->nNumOfElements) {
 127                         /* update hash table */
 128                         for (i = 0; i < ht->nTableSize; i++) {
 129                                 if (ht->arBuckets[i]) {
 130                                         ht->arBuckets[i] = zend_shared_alloc_get_xlat_entry(ht->arBuckets[i]);
 131                                 }
 132                         }
 133                 }
 134                 zend_accel_store(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
 135 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 136         } else {
 137                 ht->arBuckets = (Bucket**)&uninitialized_bucket;
 138         }
 139 #endif
 140 }
 141 
 142 #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
 143 static zend_ast *zend_persist_ast(zend_ast *ast TSRMLS_DC)
 144 {
 145         int i;
 146         zend_ast *node;
 147 
 148         if (ast->kind == ZEND_CONST) {
 149                 node = zend_accel_memdup(ast, sizeof(zend_ast) + sizeof(zval));
 150                 node->u.val = (zval*)(node + 1);
 151                 zend_persist_zval(node->u.val TSRMLS_CC);
 152         } else {
 153                 node = zend_accel_memdup(ast, sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1));
 154                 for (i = 0; i < ast->children; i++) {
 155                         if ((&node->u.child)[i]) {
 156                                 (&node->u.child)[i] = zend_persist_ast((&node->u.child)[i] TSRMLS_CC);
 157                         }
 158                 }
 159         }
 160         efree(ast);
 161         return node;
 162 }
 163 #endif
 164 
 165 static void zend_persist_zval(zval *z TSRMLS_DC)
 166 {
 167 #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
 168         switch (z->type & IS_CONSTANT_TYPE_MASK) {
 169 #else
 170         switch (z->type & ~IS_CONSTANT_INDEX) {
 171 #endif
 172                 case IS_STRING:
 173                 case IS_CONSTANT:
 174                         zend_accel_store_interned_string(z->value.str.val, z->value.str.len + 1);
 175                         break;
 176                 case IS_ARRAY:
 177 #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
 178                 case IS_CONSTANT_ARRAY:
 179 #endif
 180                         zend_accel_store(z->value.ht, sizeof(HashTable));
 181                         zend_hash_persist(z->value.ht, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
 182                         break;
 183 #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
 184                 case IS_CONSTANT_AST:
 185                         Z_AST_P(z) = zend_persist_ast(Z_AST_P(z) TSRMLS_CC);
 186                         break;
 187 #endif
 188         }
 189 }
 190 
 191 static void zend_persist_zval_ptr(zval **zp TSRMLS_DC)
 192 {
 193         zval *new_ptr = zend_shared_alloc_get_xlat_entry(*zp);
 194 
 195         if (new_ptr) {
 196                 *zp = new_ptr;
 197         } else {
 198                 /* Attempt to store only if we didn't store this zval_ptr yet */
 199                 zend_accel_store(*zp, sizeof(zval));
 200                 zend_persist_zval(*zp TSRMLS_CC);
 201         }
 202 }
 203 
 204 static void zend_protect_zval(zval *z TSRMLS_DC)
 205 {
 206         PZ_SET_ISREF_P(z);
 207         PZ_SET_REFCOUNT_P(z, 2);
 208 }
 209 
 210 static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_script* main_persistent_script TSRMLS_DC)
 211 {
 212         zend_op *persist_ptr;
 213 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
 214         int has_jmp = 0;
 215 #endif
 216 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 217         zend_literal *orig_literals = NULL;
 218 #endif
 219 
 220         if (op_array->type != ZEND_USER_FUNCTION) {
 221                 return;
 222         }
 223 
 224 #if ZEND_EXTENSION_API_NO <= PHP_5_3_X_API_NO
 225         op_array->size = op_array->last;
 226 #endif
 227 
 228         if (--(*op_array->refcount) == 0) {
 229                 efree(op_array->refcount);
 230         }
 231         op_array->refcount = NULL;
 232 
 233         if (op_array->filename) {
 234                 /* do not free! PHP has centralized filename storage, compiler will free it */
 235                 op_array->filename = zend_accel_memdup(op_array->filename, strlen(op_array->filename) + 1);
 236         }
 237 
 238         if (main_persistent_script) {
 239                 zend_bool orig_in_execution = EG(in_execution);
 240                 zend_op_array *orig_op_array = EG(active_op_array);
 241                 zval offset;
 242 
 243 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
 244                 main_persistent_script->early_binding = -1;
 245 #endif
 246                 EG(in_execution) = 1;
 247                 EG(active_op_array) = op_array;
 248                 if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &offset TSRMLS_CC)) {
 249                         main_persistent_script->compiler_halt_offset = Z_LVAL(offset);
 250                 }
 251                 EG(active_op_array) = orig_op_array;
 252                 EG(in_execution) = orig_in_execution;
 253         }
 254 
 255 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 256         if (op_array->literals) {
 257                 orig_literals = zend_shared_alloc_get_xlat_entry(op_array->literals);
 258                 if (orig_literals) {
 259                         op_array->literals = orig_literals;
 260                 } else {
 261                         zend_literal *p = zend_accel_memdup(op_array->literals, sizeof(zend_literal) * op_array->last_literal);
 262                         zend_literal *end = p + op_array->last_literal;
 263                         orig_literals = op_array->literals;
 264                         op_array->literals = p;
 265                         while (p < end) {
 266                                 zend_persist_zval(&p->constant TSRMLS_CC);
 267                                 zend_protect_zval(&p->constant TSRMLS_CC);
 268                                 p++;
 269                         }
 270                         efree(orig_literals);
 271                 }
 272         }
 273 #endif
 274 
 275         if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->opcodes))) {
 276                 op_array->opcodes = persist_ptr;
 277         } else {
 278                 zend_op *new_opcodes = zend_accel_memdup(op_array->opcodes, sizeof(zend_op) * op_array->last);
 279                 zend_op *opline = new_opcodes;
 280                 zend_op *end = new_opcodes + op_array->last;
 281                 int offset = 0;
 282 
 283                 for (; opline < end ; opline++, offset++) {
 284                         if (ZEND_OP1_TYPE(opline) == IS_CONST) {
 285 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 286                                 opline->op1.zv = (zval*)((char*)opline->op1.zv + ((char*)op_array->literals - (char*)orig_literals));
 287 #else
 288                                 zend_persist_zval(&opline->op1.u.constant TSRMLS_CC);
 289                                 zend_protect_zval(&opline->op1.u.constant TSRMLS_CC);
 290 #endif
 291                         }
 292                         if (ZEND_OP2_TYPE(opline) == IS_CONST) {
 293 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 294                                 opline->op2.zv = (zval*)((char*)opline->op2.zv + ((char*)op_array->literals - (char*)orig_literals));
 295 #else
 296                                 zend_persist_zval(&opline->op2.u.constant TSRMLS_CC);
 297                                 zend_protect_zval(&opline->op2.u.constant TSRMLS_CC);
 298 #endif
 299                         }
 300 
 301 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
 302                         switch (opline->opcode) {
 303                                 case ZEND_JMP:
 304                                         has_jmp = 1;
 305                                         if (ZEND_DONE_PASS_TWO(op_array)) {
 306                                                 ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes];
 307                                         }
 308                                         break;
 309                                 case ZEND_JMPZ:
 310                                 case ZEND_JMPNZ:
 311                                 case ZEND_JMPZ_EX:
 312                                 case ZEND_JMPNZ_EX:
 313                                         has_jmp = 1;
 314                                         if (ZEND_DONE_PASS_TWO(op_array)) {
 315                                                 ZEND_OP2(opline).jmp_addr = &new_opcodes[ZEND_OP2(opline).jmp_addr - op_array->opcodes];
 316                                         }
 317                                         break;
 318                                 case ZEND_JMPZNZ:
 319                                 case ZEND_BRK:
 320                                 case ZEND_CONT:
 321                                         has_jmp = 1;
 322                                         break;
 323                                 case ZEND_DECLARE_INHERITED_CLASS:
 324                                         if (main_persistent_script && ZCG(accel_directives).inherited_hack) {
 325                                         if (!has_jmp &&
 326                                            ((opline + 2) >= end ||
 327                                             (opline + 1)->opcode != ZEND_FETCH_CLASS ||
 328                                             (opline + 2)->opcode != ZEND_ADD_INTERFACE)) {
 329 
 330                                                 zend_uint *opline_num = &main_persistent_script->early_binding;
 331 
 332                                                 while ((int)*opline_num != -1) {
 333                                                         opline_num = &new_opcodes[*opline_num].result.u.opline_num;
 334                                                 }
 335                                                 *opline_num = opline - new_opcodes;
 336                                                 opline->result.op_type = IS_UNUSED;
 337                                                 opline->result.u.opline_num = -1;
 338                                                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED;
 339                                                 ZEND_VM_SET_OPCODE_HANDLER(opline);
 340                                         }
 341                                         break;
 342                                 }
 343                         }
 344 
 345 #else /* if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO */
 346 
 347                         if (ZEND_DONE_PASS_TWO(op_array)) {
 348                                 /* fix jumps to point to new array */
 349                                 switch (opline->opcode) {
 350                                         case ZEND_JMP:
 351                                         case ZEND_GOTO:
 352 #if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
 353                                         case ZEND_FAST_CALL:
 354 #endif
 355                                                 ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes];
 356                                                 break;
 357                                         case ZEND_JMPZ:
 358                                         case ZEND_JMPNZ:
 359                                         case ZEND_JMPZ_EX:
 360                                         case ZEND_JMPNZ_EX:
 361                                         case ZEND_JMP_SET:
 362 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 363                                         case ZEND_JMP_SET_VAR:
 364 #endif
 365                                                 ZEND_OP2(opline).jmp_addr = &new_opcodes[ZEND_OP2(opline).jmp_addr - op_array->opcodes];
 366                                                 break;
 367                                 }
 368                         }
 369 #endif /* if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO */
 370                 }
 371 
 372                 efree(op_array->opcodes);
 373                 op_array->opcodes = new_opcodes;
 374 
 375 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 376                 if (op_array->run_time_cache) {
 377                         efree(op_array->run_time_cache);
 378                         op_array->run_time_cache = NULL;
 379                 }
 380 #endif
 381         }
 382 
 383         if (op_array->function_name) {
 384                 char *new_name;
 385                 if ((new_name = zend_shared_alloc_get_xlat_entry(op_array->function_name))) {
 386                         op_array->function_name = new_name;
 387                 } else {
 388                         zend_accel_store(op_array->function_name, strlen(op_array->function_name) + 1);
 389                 }
 390         }
 391 
 392         if (op_array->arg_info) {
 393                 zend_arg_info *new_ptr;
 394                 if ((new_ptr = zend_shared_alloc_get_xlat_entry(op_array->arg_info))) {
 395                         op_array->arg_info = new_ptr;
 396                 } else {
 397                         zend_uint i;
 398 
 399                         zend_accel_store(op_array->arg_info, sizeof(zend_arg_info) * op_array->num_args);
 400                         for (i = 0; i < op_array->num_args; i++) {
 401                                 if (op_array->arg_info[i].name) {
 402                                         zend_accel_store_interned_string(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1);
 403                                 }
 404                                 if (op_array->arg_info[i].class_name) {
 405                                         zend_accel_store_interned_string(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1);
 406                                 }
 407                         }
 408                 }
 409         }
 410 
 411         if (op_array->brk_cont_array) {
 412                 zend_accel_store(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont);
 413         }
 414 
 415         if (op_array->static_variables) {
 416                 zend_hash_persist(op_array->static_variables, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
 417                 zend_accel_store(op_array->static_variables, sizeof(HashTable));
 418         }
 419 
 420         if (op_array->scope) {
 421                 op_array->scope = zend_shared_alloc_get_xlat_entry(op_array->scope);
 422         }
 423 
 424         if (op_array->doc_comment) {
 425                 if (ZCG(accel_directives).save_comments) {
 426                         zend_accel_store(op_array->doc_comment, op_array->doc_comment_len + 1);
 427                 } else {
 428                         if (!zend_shared_alloc_get_xlat_entry(op_array->doc_comment)) {
 429                                 zend_shared_alloc_register_xlat_entry(op_array->doc_comment, op_array->doc_comment);
 430                                 efree((char*)op_array->doc_comment);
 431                         }
 432                         op_array->doc_comment = NULL;
 433                         op_array->doc_comment_len = 0;
 434                 }
 435         }
 436 
 437         if (op_array->try_catch_array) {
 438                 zend_accel_store(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch);
 439         }
 440 
 441         if (op_array->vars) {
 442                 if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->vars))) {
 443                         op_array->vars = (zend_compiled_variable*)persist_ptr;
 444                 } else {
 445                         int i;
 446                         zend_accel_store(op_array->vars, sizeof(zend_compiled_variable) * op_array->last_var);
 447                         for (i = 0; i < op_array->last_var; i++) {
 448                                 zend_accel_store_interned_string(op_array->vars[i].name, op_array->vars[i].name_len + 1);
 449                         }
 450                 }
 451         }
 452 
 453         /* "prototype" may be undefined if "scope" isn't set */
 454         if (op_array->scope && op_array->prototype) {
 455                 if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->prototype))) {
 456                         op_array->prototype = (union _zend_function*)persist_ptr;
 457                         /* we use refcount to show that op_array is referenced from several places */
 458                         op_array->prototype->op_array.refcount++;
 459                 }
 460         } else {
 461                 op_array->prototype = NULL;
 462         }
 463 }
 464 
 465 static void zend_persist_op_array(zend_op_array *op_array TSRMLS_DC)
 466 {
 467         zend_persist_op_array_ex(op_array, NULL TSRMLS_CC);
 468 }
 469 
 470 static void zend_persist_property_info(zend_property_info *prop TSRMLS_DC)
 471 {
 472         zend_accel_store_interned_string(prop->name, prop->name_length + 1);
 473         if (prop->doc_comment) {
 474                 if (ZCG(accel_directives).save_comments) {
 475                         zend_accel_store(prop->doc_comment, prop->doc_comment_len + 1);
 476                 } else {
 477                         if (!zend_shared_alloc_get_xlat_entry(prop->doc_comment)) {
 478                                 zend_shared_alloc_register_xlat_entry(prop->doc_comment, prop->doc_comment);
 479                                 efree((char*)prop->doc_comment);
 480                         }
 481                         prop->doc_comment = NULL;
 482                         prop->doc_comment_len = 0;
 483                 }
 484         }
 485 }
 486 
 487 static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC)
 488 {
 489         zend_class_entry *ce = *pce;
 490 
 491         if (ce->type == ZEND_USER_CLASS) {
 492                 *pce = zend_accel_store(ce, sizeof(zend_class_entry));
 493                 zend_accel_store_interned_string(ce->name, ce->name_length + 1);
 494                 zend_hash_persist(&ce->function_table, (zend_persist_func_t) zend_persist_op_array, sizeof(zend_op_array) TSRMLS_CC);
 495 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 496                 if (ce->default_properties_table) {
 497                     int i;
 498 
 499                         zend_accel_store(ce->default_properties_table, sizeof(zval*) * ce->default_properties_count);
 500                         for (i = 0; i < ce->default_properties_count; i++) {
 501                                 if (ce->default_properties_table[i]) {
 502                                         zend_persist_zval_ptr(&ce->default_properties_table[i] TSRMLS_CC);
 503                                 }
 504                         }
 505                 }
 506                 if (ce->default_static_members_table) {
 507                     int i;
 508 
 509                         zend_accel_store(ce->default_static_members_table, sizeof(zval*) * ce->default_static_members_count);
 510                         for (i = 0; i < ce->default_static_members_count; i++) {
 511                                 if (ce->default_static_members_table[i]) {
 512                                         zend_persist_zval_ptr(&ce->default_static_members_table[i] TSRMLS_CC);
 513                                 }
 514                         }
 515                 }
 516                 ce->static_members_table = NULL;
 517 #else
 518                 zend_hash_persist(&ce->default_properties, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
 519                 zend_hash_persist(&ce->default_static_members, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
 520                 ce->static_members = NULL;
 521 #endif
 522                 zend_hash_persist(&ce->constants_table, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
 523 
 524                 if (ZEND_CE_FILENAME(ce)) {
 525                         /* do not free! PHP has centralized filename storage, compiler will free it */
 526                         ZEND_CE_FILENAME(ce) = zend_accel_memdup(ZEND_CE_FILENAME(ce), strlen(ZEND_CE_FILENAME(ce)) + 1);
 527                 }
 528                 if (ZEND_CE_DOC_COMMENT(ce)) {
 529                         if (ZCG(accel_directives).save_comments) {
 530                                 zend_accel_store(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce) + 1);
 531                         } else {
 532                                 if (!zend_shared_alloc_get_xlat_entry(ZEND_CE_DOC_COMMENT(ce))) {
 533                                         zend_shared_alloc_register_xlat_entry(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT(ce));
 534                                         efree((char*)ZEND_CE_DOC_COMMENT(ce));
 535                                 }
 536                                 ZEND_CE_DOC_COMMENT(ce) = NULL;
 537                                 ZEND_CE_DOC_COMMENT_LEN(ce) = 0;
 538                         }
 539                 }
 540                 zend_hash_persist(&ce->properties_info, (zend_persist_func_t) zend_persist_property_info, sizeof(zend_property_info) TSRMLS_CC);
 541                 if (ce->num_interfaces && ce->interfaces) {
 542                         efree(ce->interfaces);
 543                 }
 544                 ce->interfaces = NULL; /* will be filled in on fetch */
 545 
 546 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
 547                 if (ce->num_traits && ce->traits) {
 548                         efree(ce->traits);
 549                 }
 550                 ce->traits = NULL;
 551 
 552                 if (ce->trait_aliases) {
 553                         int i = 0;
 554                         while (ce->trait_aliases[i]) {
 555                                 if (ce->trait_aliases[i]->trait_method) {
 556                                         if (ce->trait_aliases[i]->trait_method->method_name) {
 557                                                 zend_accel_store(ce->trait_aliases[i]->trait_method->method_name,
 558                                                         ce->trait_aliases[i]->trait_method->mname_len + 1);
 559                                         }
 560                                         if (ce->trait_aliases[i]->trait_method->class_name) {
 561                                                 zend_accel_store(ce->trait_aliases[i]->trait_method->class_name,
 562                                                         ce->trait_aliases[i]->trait_method->cname_len + 1);
 563                                         }
 564                                         ce->trait_aliases[i]->trait_method->ce = NULL;
 565                                         zend_accel_store(ce->trait_aliases[i]->trait_method,
 566                                                 sizeof(zend_trait_method_reference));
 567                                 }
 568 
 569                                 if (ce->trait_aliases[i]->alias) {
 570                                         zend_accel_store(ce->trait_aliases[i]->alias,
 571                                                 ce->trait_aliases[i]->alias_len + 1);
 572                                 }
 573 
 574 #if ZEND_EXTENSION_API_NO <= PHP_5_4_X_API_NO
 575                 ce->trait_aliases[i]->function = NULL;
 576 #endif
 577                                 zend_accel_store(ce->trait_aliases[i], sizeof(zend_trait_alias));
 578                                 i++;
 579                         }
 580 
 581                         zend_accel_store(ce->trait_aliases, sizeof(zend_trait_alias*) * (i + 1));
 582                 }
 583 
 584                 if (ce->trait_precedences) {
 585                         int i = 0;
 586 
 587                         while (ce->trait_precedences[i]) {
 588                                 zend_accel_store(ce->trait_precedences[i]->trait_method->method_name,
 589                                         ce->trait_precedences[i]->trait_method->mname_len + 1);
 590                                 zend_accel_store(ce->trait_precedences[i]->trait_method->class_name,
 591                                         ce->trait_precedences[i]->trait_method->cname_len + 1);
 592                                 ce->trait_precedences[i]->trait_method->ce = NULL;
 593                                 zend_accel_store(ce->trait_precedences[i]->trait_method,
 594                                         sizeof(zend_trait_method_reference));
 595 
 596                                 if (ce->trait_precedences[i]->exclude_from_classes) {
 597                                         int j = 0;
 598 
 599                                         while (ce->trait_precedences[i]->exclude_from_classes[j]) {
 600                                                 zend_accel_store(ce->trait_precedences[i]->exclude_from_classes[j],
 601                                                         strlen((char*)ce->trait_precedences[i]->exclude_from_classes[j]) + 1);
 602                                                 j++;
 603                                         }
 604                                         zend_accel_store(ce->trait_precedences[i]->exclude_from_classes,
 605                                                 sizeof(zend_class_entry*) * (j + 1));
 606                                 }
 607 
 608 #if ZEND_EXTENSION_API_NO <= PHP_5_4_X_API_NO
 609                 ce->trait_precedences[i]->function = NULL;
 610 #endif
 611                                 zend_accel_store(ce->trait_precedences[i], sizeof(zend_trait_precedence));
 612                                 i++;
 613                         }
 614                         zend_accel_store(
 615                                 ce->trait_precedences, sizeof(zend_trait_precedence*) * (i + 1));
 616                 }
 617 #endif
 618         }
 619 }
 620 
 621 static int zend_update_property_info_ce(zend_property_info *prop TSRMLS_DC)
 622 {
 623         prop->ce = zend_shared_alloc_get_xlat_entry(prop->ce);
 624         return 0;
 625 }
 626 
 627 static int zend_update_parent_ce(zend_class_entry **pce TSRMLS_DC)
 628 {
 629         zend_class_entry *ce = *pce;
 630 
 631         if (ce->parent) {
 632                 ce->parent = zend_shared_alloc_get_xlat_entry(ce->parent);
 633                 /* We use refcount to show if the class is used as a parent */
 634                 ce->parent->refcount++;
 635         }
 636 
 637         /* update methods */
 638         if (ce->constructor) {
 639                 ce->constructor = zend_shared_alloc_get_xlat_entry(ce->constructor);
 640                 /* we use refcount to show that op_array is referenced from several places */
 641                 ce->constructor->op_array.refcount++;
 642         }
 643         if (ce->destructor) {
 644                 ce->destructor = zend_shared_alloc_get_xlat_entry(ce->destructor);
 645                 ce->destructor->op_array.refcount++;
 646         }
 647         if (ce->clone) {
 648                 ce->clone = zend_shared_alloc_get_xlat_entry(ce->clone);
 649                 ce->clone->op_array.refcount++;
 650         }
 651         if (ce->__get) {
 652                 ce->__get = zend_shared_alloc_get_xlat_entry(ce->__get);
 653                 ce->__get->op_array.refcount++;
 654         }
 655         if (ce->__set) {
 656                 ce->__set = zend_shared_alloc_get_xlat_entry(ce->__set);
 657                 ce->__set->op_array.refcount++;
 658         }
 659         if (ce->__call) {
 660                 ce->__call = zend_shared_alloc_get_xlat_entry(ce->__call);
 661                 ce->__call->op_array.refcount++;
 662         }
 663         if (ce->serialize_func) {
 664                 ce->serialize_func = zend_shared_alloc_get_xlat_entry(ce->serialize_func);
 665                 ce->serialize_func->op_array.refcount++;
 666         }
 667         if (ce->unserialize_func) {
 668                 ce->unserialize_func = zend_shared_alloc_get_xlat_entry(ce->unserialize_func);
 669                 ce->unserialize_func->op_array.refcount++;
 670         }
 671         if (ce->__isset) {
 672                 ce->__isset = zend_shared_alloc_get_xlat_entry(ce->__isset);
 673                 ce->__isset->op_array.refcount++;
 674         }
 675         if (ce->__unset) {
 676                 ce->__unset = zend_shared_alloc_get_xlat_entry(ce->__unset);
 677                 ce->__unset->op_array.refcount++;
 678         }
 679         if (ce->__tostring) {
 680                 ce->__tostring = zend_shared_alloc_get_xlat_entry(ce->__tostring);
 681                 ce->__tostring->op_array.refcount++;
 682         }
 683 #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
 684         if (ce->__callstatic) {
 685                 ce->__callstatic = zend_shared_alloc_get_xlat_entry(ce->__callstatic);
 686                 ce->__callstatic->op_array.refcount++;
 687         }
 688 #endif
 689 #if ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO
 690         if (ce->__debugInfo) {
 691                 ce->__debugInfo = zend_shared_alloc_get_xlat_entry(ce->__debugInfo);
 692                 ce->__debugInfo->op_array.refcount++;
 693         }
 694 #endif
 695         zend_hash_apply(&ce->properties_info, (apply_func_t) zend_update_property_info_ce TSRMLS_CC);
 696         return 0;
 697 }
 698 
 699 static void zend_accel_persist_class_table(HashTable *class_table TSRMLS_DC)
 700 {
 701     zend_hash_persist(class_table, (zend_persist_func_t) zend_persist_class_entry, sizeof(zend_class_entry*) TSRMLS_CC);
 702         zend_hash_apply(class_table, (apply_func_t) zend_update_parent_ce TSRMLS_CC);
 703 }
 704 
 705 zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length TSRMLS_DC)
 706 {
 707         zend_shared_alloc_clear_xlat_table();
 708         zend_hash_persist(&script->function_table, (zend_persist_func_t) zend_persist_op_array, sizeof(zend_op_array) TSRMLS_CC);
 709         zend_accel_persist_class_table(&script->class_table TSRMLS_CC);
 710         zend_persist_op_array_ex(&script->main_op_array, script TSRMLS_CC);
 711         *key = zend_accel_memdup(*key, key_length + 1);
 712         zend_accel_store(script->full_path, script->full_path_len + 1);
 713         zend_accel_store(script, sizeof(zend_persistent_script));
 714 
 715         return script;
 716 }
 717 
 718 int zend_accel_script_persistable(zend_persistent_script *script)
 719 {
 720         return 1;
 721 }

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