diff options
Diffstat (limited to 'ext/opcache/zend_persist.c')
-rw-r--r-- | ext/opcache/zend_persist.c | 493 |
1 files changed, 299 insertions, 194 deletions
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index fdc21d6c5d..070d77670b 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -34,109 +34,119 @@ _zend_shared_memdup((void*)p, size, 0 TSRMLS_CC) #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO -# define zend_accel_memdup_interned_string(str, len) \ - IS_INTERNED(str) ? str : zend_accel_memdup(str, len) - -# define zend_accel_store_interned_string(str, len) do { \ - if (!IS_INTERNED(str)) { zend_accel_store(str, len); } \ +# define zend_accel_store_string(str) do { \ + zend_string *new_str = zend_shared_alloc_get_xlat_entry(str); \ + if (new_str) { \ + STR_RELEASE(str); \ + str = new_str; \ + } else { \ + new_str = zend_accel_memdup((void*)str, _STR_HEADER_SIZE + (str)->len + 1); \ + STR_RELEASE(str); \ + str = new_str; \ + STR_HASH_VAL(str); \ + GC_FLAGS(str) = IS_STR_INTERNED | IS_STR_PERMANENT; \ + } \ + } while (0) +# define zend_accel_memdup_string(str) do { \ + str = zend_accel_memdup(str, _STR_HEADER_SIZE + (str)->len + 1); \ + STR_HASH_VAL(str); \ + GC_FLAGS(str) = IS_STR_INTERNED | IS_STR_PERMANENT; \ + } while (0) +# define zend_accel_store_interned_string(str) do { \ + if (!IS_ACCEL_INTERNED(str)) { \ + zend_accel_store_string(str); \ + } \ + } while (0) +# define zend_accel_memdup_interned_string(str) do { \ + if (!IS_ACCEL_INTERNED(str)) { \ + zend_accel_memdup_string(str); \ + } \ } while (0) #else -# define zend_accel_memdup_interned_string(str, len) \ - zend_accel_memdup(str, len) - # define zend_accel_store_interned_string(str, len) \ zend_accel_store(str, len) #endif -typedef void (*zend_persist_func_t)(void * TSRMLS_DC); +typedef void (*zend_persist_func_t)(zval* TSRMLS_DC); -static void zend_persist_zval_ptr(zval **zp TSRMLS_DC); static void zend_persist_zval(zval *z TSRMLS_DC); +static void zend_persist_zval_const(zval *z TSRMLS_DC); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO -static const Bucket *uninitialized_bucket = NULL; +static const zend_uint uninitialized_bucket = {INVALID_IDX}; #endif -static void zend_hash_persist(HashTable *ht, void (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC) +static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement TSRMLS_DC) { - Bucket *p = ht->pListHead; - uint i; + uint idx; + Bucket *p; - while (p) { - Bucket *q = p; + if (!ht->nTableMask) { + ht->arHash = (zend_uint*)&uninitialized_bucket; + return; + } + if (ht->u.flags & HASH_FLAG_PACKED) { + zend_accel_store(ht->arData, sizeof(Bucket) * ht->nNumUsed); + ht->arHash = (zend_uint*)&uninitialized_bucket; + } else { + Bucket *d = (Bucket*)ZCG(mem); + zend_uint *h = (zend_uint*)(d + ht->nNumUsed); - /* persist bucket and key */ -#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - p = zend_accel_memdup(p, sizeof(Bucket)); - if (p->nKeyLength) { - p->arKey = zend_accel_memdup_interned_string(p->arKey, p->nKeyLength); - } -#else - p = zend_accel_memdup(p, sizeof(Bucket) - 1 + p->nKeyLength); -#endif + ZCG(mem) = (void*)(h + ht->nTableSize); + memcpy(d, ht->arData, sizeof(Bucket) * ht->nNumUsed); + memcpy(h, ht->arHash, sizeof(zend_uint) * ht->nTableSize); + efree(ht->arData); + ht->arData = d; + ht->arHash = h; + } + for (idx = 0; idx < ht->nNumUsed; idx++) { + p = ht->arData + idx; + if (Z_TYPE(p->val) == IS_UNDEF) continue; - /* persist data pointer in bucket */ - if (!p->pDataPtr) { - zend_accel_store(p->pData, el_size); - } else { - /* Update p->pData to point to the new p->pDataPtr address, after the bucket relocation */ - p->pData = &p->pDataPtr; + /* persist bucket and key */ + if (p->key) { + zend_accel_store_interned_string(p->key); } /* persist the data itself */ - if (pPersistElement) { - pPersistElement(p->pData TSRMLS_CC); - } - - /* update linked lists */ - if (p->pLast) { - p->pLast->pNext = p; - } - if (p->pNext) { - p->pNext->pLast = p; - } - if (p->pListLast) { - p->pListLast->pListNext = p; - } - if (p->pListNext) { - p->pListNext->pListLast = p; - } + pPersistElement(&p->val TSRMLS_CC); + } +} - p = p->pListNext; +static void zend_hash_persist_immutable(HashTable *ht TSRMLS_DC) +{ + uint idx; + Bucket *p; - /* delete the old non-persistent bucket */ - efree(q); + if (!ht->nTableMask) { + ht->arHash = (zend_uint*)&uninitialized_bucket; + return; } + if (ht->u.flags & HASH_FLAG_PACKED) { + ht->arData = zend_accel_memdup(ht->arData, sizeof(Bucket) * ht->nNumUsed); + ht->arHash = (zend_uint*)&uninitialized_bucket; + } else { + Bucket *d = (Bucket*)ZCG(mem); + zend_uint *h = (zend_uint*)(d + ht->nNumUsed); - /* update linked lists */ - if (ht->pListHead) { - ht->pListHead = zend_shared_alloc_get_xlat_entry(ht->pListHead); - } - if (ht->pListTail) { - ht->pListTail = zend_shared_alloc_get_xlat_entry(ht->pListTail); - } - if (ht->pInternalPointer) { - ht->pInternalPointer = zend_shared_alloc_get_xlat_entry(ht->pInternalPointer); + ZCG(mem) = (void*)(h + ht->nTableSize); + memcpy(d, ht->arData, sizeof(Bucket) * ht->nNumUsed); + memcpy(h, ht->arHash, sizeof(zend_uint) * ht->nTableSize); + ht->arData = d; + ht->arHash = h; } + for (idx = 0; idx < ht->nNumUsed; idx++) { + p = ht->arData + idx; + if (Z_TYPE(p->val) == IS_UNDEF) continue; -#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - /* Check if HastTable is initialized */ - if (ht->nTableMask) { -#endif - if (ht->nNumOfElements) { - /* update hash table */ - for (i = 0; i < ht->nTableSize; i++) { - if (ht->arBuckets[i]) { - ht->arBuckets[i] = zend_shared_alloc_get_xlat_entry(ht->arBuckets[i]); - } - } + /* persist bucket and key */ + if (p->key) { + zend_accel_memdup_interned_string(p->key); } - zend_accel_store(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize); -#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - } else { - ht->arBuckets = (Bucket**)&uninitialized_bucket; + + /* persist the data itself */ + zend_persist_zval_const(&p->val TSRMLS_CC); } -#endif } #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO @@ -146,9 +156,8 @@ static zend_ast *zend_persist_ast(zend_ast *ast TSRMLS_DC) zend_ast *node; if (ast->kind == ZEND_CONST) { - node = zend_accel_memdup(ast, sizeof(zend_ast) + sizeof(zval)); - node->u.val = (zval*)(node + 1); - zend_persist_zval(node->u.val TSRMLS_CC); + node = zend_accel_memdup(ast, sizeof(zend_ast)); + zend_persist_zval(&node->u.val TSRMLS_CC); } else { node = zend_accel_memdup(ast, sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); for (i = 0; i < ast->children; i++) { @@ -164,59 +173,139 @@ static zend_ast *zend_persist_ast(zend_ast *ast TSRMLS_DC) static void zend_persist_zval(zval *z TSRMLS_DC) { + zend_uchar flags; + void *new_ptr; + #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO - switch (z->type & IS_CONSTANT_TYPE_MASK) { + switch (Z_TYPE_P(z)) { #else - switch (z->type & ~IS_CONSTANT_INDEX) { + switch (Z_TYPE_P(z)) { #endif case IS_STRING: case IS_CONSTANT: - zend_accel_store_interned_string(z->value.str.val, z->value.str.len + 1); + flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT); + zend_accel_store_interned_string(Z_STR_P(z)); + Z_GC_FLAGS_P(z) |= flags; + Z_TYPE_FLAGS_P(z) &= ~(IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); break; case IS_ARRAY: #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO case IS_CONSTANT_ARRAY: #endif - zend_accel_store(z->value.ht, sizeof(HashTable)); - zend_hash_persist(z->value.ht, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC); + new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z)); + if (new_ptr) { + Z_ARR_P(z) = new_ptr; + Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; + } else { + if (Z_IMMUTABLE_P(z)) { + Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array)); + zend_hash_persist_immutable(Z_ARRVAL_P(z) TSRMLS_CC); + } else { + zend_accel_store(Z_ARR_P(z), sizeof(zend_array)); + zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval TSRMLS_CC); + /* make immutable array */ + Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; + GC_REFCOUNT(Z_COUNTED_P(z)) = 2; + Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; + } + } break; #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO + case IS_REFERENCE: + new_ptr = zend_shared_alloc_get_xlat_entry(Z_REF_P(z)); + if (new_ptr) { + Z_REF_P(z) = new_ptr; + } else { + zend_accel_store(Z_REF_P(z), sizeof(zend_reference)); + zend_persist_zval(Z_REFVAL_P(z) TSRMLS_CC); + } + break; case IS_CONSTANT_AST: - Z_AST_P(z) = zend_persist_ast(Z_AST_P(z) TSRMLS_CC); + new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z)); + if (new_ptr) { + Z_AST_P(z) = new_ptr; + } else { + zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref)); + Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z) TSRMLS_CC); + } break; #endif } } -static void zend_persist_zval_ptr(zval **zp TSRMLS_DC) +static void zend_persist_zval_const(zval *z TSRMLS_DC) { - zval *new_ptr = zend_shared_alloc_get_xlat_entry(*zp); + zend_uchar flags; + void *new_ptr; - if (new_ptr) { - *zp = new_ptr; - } else { - /* Attempt to store only if we didn't store this zval_ptr yet */ - zend_accel_store(*zp, sizeof(zval)); - zend_persist_zval(*zp TSRMLS_CC); +#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO + switch (Z_TYPE_P(z)) { +#else + switch (Z_TYPE_P(z)) { +#endif + case IS_STRING: + case IS_CONSTANT: + flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT); + zend_accel_memdup_interned_string(Z_STR_P(z)); + Z_GC_FLAGS_P(z) |= flags; + Z_TYPE_FLAGS_P(z) &= ~(IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); + break; + case IS_ARRAY: +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: +#endif + new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z)); + if (new_ptr) { + Z_ARR_P(z) = new_ptr; + Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; + } else { + if (Z_IMMUTABLE_P(z)) { + Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array)); + zend_hash_persist_immutable(Z_ARRVAL_P(z) TSRMLS_CC); + } else { + zend_accel_store(Z_ARR_P(z), sizeof(zend_array)); + zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval TSRMLS_CC); + /* make immutable array */ + Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; + GC_REFCOUNT(Z_COUNTED_P(z)) = 2; + Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; + } + } + break; +#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO + case IS_REFERENCE: + new_ptr = zend_shared_alloc_get_xlat_entry(Z_REF_P(z)); + if (new_ptr) { + Z_REF_P(z) = new_ptr; + } else { + zend_accel_store(Z_REF_P(z), sizeof(zend_reference)); + zend_persist_zval(Z_REFVAL_P(z) TSRMLS_CC); + } + break; + case IS_CONSTANT_AST: + new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z)); + if (new_ptr) { + Z_AST_P(z) = new_ptr; + } else { + zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref)); + Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z) TSRMLS_CC); + } + break; +#endif } } -static void zend_protect_zval(zval *z TSRMLS_DC) -{ - PZ_SET_ISREF_P(z); - PZ_SET_REFCOUNT_P(z, 2); -} - static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_script* main_persistent_script TSRMLS_DC) { + int already_stored = 0; zend_op *persist_ptr; #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO int has_jmp = 0; #endif #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - zend_literal *orig_literals = NULL; + zval *orig_literals = NULL; #endif - + if (op_array->type != ZEND_USER_FUNCTION) { return; } @@ -230,41 +319,45 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } op_array->refcount = NULL; - if (op_array->filename) { - /* do not free! PHP has centralized filename storage, compiler will free it */ - op_array->filename = zend_accel_memdup(op_array->filename, strlen(op_array->filename) + 1); - } - if (main_persistent_script) { - zend_bool orig_in_execution = EG(in_execution); - zend_op_array *orig_op_array = EG(active_op_array); - zval offset; + zend_execute_data *orig_execute_data = EG(current_execute_data); + zend_execute_data fake_execute_data; + zval *offset; #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO main_persistent_script->early_binding = -1; #endif - EG(in_execution) = 1; - EG(active_op_array) = op_array; - if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &offset TSRMLS_CC)) { - main_persistent_script->compiler_halt_offset = Z_LVAL(offset); + memset(&fake_execute_data, 0, sizeof(fake_execute_data)); + fake_execute_data.func = (zend_function*)op_array; + EG(current_execute_data) = &fake_execute_data; + if ((offset = zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1 TSRMLS_CC)) != NULL) { + main_persistent_script->compiler_halt_offset = Z_LVAL_P(offset); } - EG(active_op_array) = orig_op_array; - EG(in_execution) = orig_in_execution; + EG(current_execute_data) = orig_execute_data; + } + + if (op_array->static_variables) { + zend_hash_persist(op_array->static_variables, zend_persist_zval TSRMLS_CC); + zend_accel_store(op_array->static_variables, sizeof(HashTable)); + } + + if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) { + already_stored = 1; } #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (op_array->literals) { - orig_literals = zend_shared_alloc_get_xlat_entry(op_array->literals); - if (orig_literals) { + if (already_stored) { + orig_literals = zend_shared_alloc_get_xlat_entry(op_array->literals); + ZEND_ASSERT(orig_literals != NULL); op_array->literals = orig_literals; } else { - zend_literal *p = zend_accel_memdup(op_array->literals, sizeof(zend_literal) * op_array->last_literal); - zend_literal *end = p + op_array->last_literal; + zval *p = zend_accel_memdup(op_array->literals, sizeof(zval) * op_array->last_literal); + zval *end = p + op_array->last_literal; orig_literals = op_array->literals; op_array->literals = p; while (p < end) { - zend_persist_zval(&p->constant TSRMLS_CC); - zend_protect_zval(&p->constant TSRMLS_CC); + zend_persist_zval(p TSRMLS_CC); p++; } efree(orig_literals); @@ -272,7 +365,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } #endif - if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->opcodes))) { + if (already_stored) { + persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->opcodes); + ZEND_ASSERT(persist_ptr != NULL); op_array->opcodes = persist_ptr; } else { zend_op *new_opcodes = zend_accel_memdup(op_array->opcodes, sizeof(zend_op) * op_array->last); @@ -286,7 +381,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc opline->op1.zv = (zval*)((char*)opline->op1.zv + ((char*)op_array->literals - (char*)orig_literals)); #else zend_persist_zval(&opline->op1.u.constant TSRMLS_CC); - zend_protect_zval(&opline->op1.u.constant TSRMLS_CC); #endif } if (ZEND_OP2_TYPE(opline) == IS_CONST) { @@ -294,7 +388,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc opline->op2.zv = (zval*)((char*)opline->op2.zv + ((char*)op_array->literals - (char*)orig_literals)); #else zend_persist_zval(&opline->op2.u.constant TSRMLS_CC); - zend_protect_zval(&opline->op2.u.constant TSRMLS_CC); #endif } @@ -306,6 +399,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes]; } break; + case ZEND_JMPZNZ: + /* relative extended_value don't have to be changed */ + /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -315,7 +411,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc ZEND_OP2(opline).jmp_addr = &new_opcodes[ZEND_OP2(opline).jmp_addr - op_array->opcodes]; } break; - case ZEND_JMPZNZ: case ZEND_BRK: case ZEND_CONT: has_jmp = 1; @@ -354,6 +449,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc #endif ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes]; break; + case ZEND_JMPZNZ: + /* relative extended_value don't have to be changed */ + /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -362,6 +460,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO case ZEND_JMP_SET_VAR: #endif + case ZEND_NEW: + case ZEND_FE_RESET: + case ZEND_FE_FETCH: ZEND_OP2(opline).jmp_addr = &new_opcodes[ZEND_OP2(opline).jmp_addr - op_array->opcodes]; break; } @@ -380,18 +481,26 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc #endif } - if (op_array->function_name) { - char *new_name; - if ((new_name = zend_shared_alloc_get_xlat_entry(op_array->function_name))) { + if (op_array->function_name && !IS_ACCEL_INTERNED(op_array->function_name)) { + zend_string *new_name; + if (already_stored) { + new_name = zend_shared_alloc_get_xlat_entry(op_array->function_name); + ZEND_ASSERT(new_name != NULL); op_array->function_name = new_name; } else { - zend_accel_store(op_array->function_name, strlen(op_array->function_name) + 1); + zend_accel_store_string(op_array->function_name); } } + if (op_array->filename) { + /* do not free! PHP has centralized filename storage, compiler will free it */ + zend_accel_memdup_string(op_array->filename); + } + if (op_array->arg_info) { - zend_arg_info *new_ptr; - if ((new_ptr = zend_shared_alloc_get_xlat_entry(op_array->arg_info))) { + if (already_stored) { + zend_arg_info *new_ptr = zend_shared_alloc_get_xlat_entry(op_array->arg_info); + ZEND_ASSERT(new_ptr != NULL); op_array->arg_info = new_ptr; } else { zend_uint i; @@ -399,10 +508,12 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc zend_accel_store(op_array->arg_info, sizeof(zend_arg_info) * op_array->num_args); for (i = 0; i < op_array->num_args; i++) { if (op_array->arg_info[i].name) { - zend_accel_store_interned_string(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1); +//??? zend_accel_store_interned_string(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1); + zend_accel_store(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1); } if (op_array->arg_info[i].class_name) { - zend_accel_store_interned_string(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1); +//??? zend_accel_store_interned_string(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1); + zend_accel_store(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1); } } } @@ -412,25 +523,23 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc zend_accel_store(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont); } - if (op_array->static_variables) { - zend_hash_persist(op_array->static_variables, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC); - zend_accel_store(op_array->static_variables, sizeof(HashTable)); - } - if (op_array->scope) { op_array->scope = zend_shared_alloc_get_xlat_entry(op_array->scope); } if (op_array->doc_comment) { if (ZCG(accel_directives).save_comments) { - zend_accel_store(op_array->doc_comment, op_array->doc_comment_len + 1); + if (already_stored) { + op_array->doc_comment = zend_shared_alloc_get_xlat_entry(op_array->doc_comment); + ZEND_ASSERT(op_array->doc_comment != NULL); + } else { + zend_accel_store_string(op_array->doc_comment); + } } else { - if (!zend_shared_alloc_get_xlat_entry(op_array->doc_comment)) { - zend_shared_alloc_register_xlat_entry(op_array->doc_comment, op_array->doc_comment); - efree((char*)op_array->doc_comment); + if (!already_stored) { + STR_RELEASE(op_array->doc_comment); } op_array->doc_comment = NULL; - op_array->doc_comment_len = 0; } } @@ -439,13 +548,15 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } if (op_array->vars) { - if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->vars))) { - op_array->vars = (zend_compiled_variable*)persist_ptr; + if (already_stored) { + persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->vars); + ZEND_ASSERT(persist_ptr != NULL); + op_array->vars = (zend_string**)persist_ptr; } else { int i; - zend_accel_store(op_array->vars, sizeof(zend_compiled_variable) * op_array->last_var); + zend_accel_store(op_array->vars, sizeof(zend_string*) * op_array->last_var); for (i = 0; i < op_array->last_var; i++) { - zend_accel_store_interned_string(op_array->vars[i].name, op_array->vars[i].name_len + 1); + zend_accel_store_interned_string(op_array->vars[i]); } } } @@ -462,82 +573,80 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } } -static void zend_persist_op_array(zend_op_array *op_array TSRMLS_DC) +static void zend_persist_op_array(zval *zv TSRMLS_DC) { - zend_persist_op_array_ex(op_array, NULL TSRMLS_CC); + Z_PTR_P(zv) = zend_accel_memdup(Z_PTR_P(zv), sizeof(zend_op_array)); + zend_persist_op_array_ex(Z_PTR_P(zv), NULL TSRMLS_CC); } -static void zend_persist_property_info(zend_property_info *prop TSRMLS_DC) +static void zend_persist_property_info(zval *zv TSRMLS_DC) { - zend_accel_store_interned_string(prop->name, prop->name_length + 1); + zend_property_info *prop; + + prop = Z_PTR_P(zv) = zend_accel_memdup(Z_PTR_P(zv), sizeof(zend_property_info)); + zend_accel_store_interned_string(prop->name); if (prop->doc_comment) { if (ZCG(accel_directives).save_comments) { - zend_accel_store(prop->doc_comment, prop->doc_comment_len + 1); + zend_accel_store_string(prop->doc_comment); } else { if (!zend_shared_alloc_get_xlat_entry(prop->doc_comment)) { zend_shared_alloc_register_xlat_entry(prop->doc_comment, prop->doc_comment); - efree((char*)prop->doc_comment); } + STR_RELEASE(prop->doc_comment); prop->doc_comment = NULL; - prop->doc_comment_len = 0; } } } -static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC) +static void zend_persist_class_entry(zval *zv TSRMLS_DC) { - zend_class_entry *ce = *pce; + zend_class_entry *ce = Z_PTR_P(zv); if (ce->type == ZEND_USER_CLASS) { - *pce = zend_accel_store(ce, sizeof(zend_class_entry)); - zend_accel_store_interned_string(ce->name, ce->name_length + 1); - zend_hash_persist(&ce->function_table, (zend_persist_func_t) zend_persist_op_array, sizeof(zend_op_array) TSRMLS_CC); + ce = Z_PTR_P(zv) = zend_accel_memdup(ce, sizeof(zend_class_entry)); + zend_accel_store_interned_string(ce->name); + zend_hash_persist(&ce->function_table, zend_persist_op_array TSRMLS_CC); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (ce->default_properties_table) { int i; - zend_accel_store(ce->default_properties_table, sizeof(zval*) * ce->default_properties_count); + zend_accel_store(ce->default_properties_table, sizeof(zval) * ce->default_properties_count); for (i = 0; i < ce->default_properties_count; i++) { - if (ce->default_properties_table[i]) { - zend_persist_zval_ptr(&ce->default_properties_table[i] TSRMLS_CC); - } + zend_persist_zval(&ce->default_properties_table[i] TSRMLS_CC); } } if (ce->default_static_members_table) { int i; - zend_accel_store(ce->default_static_members_table, sizeof(zval*) * ce->default_static_members_count); + zend_accel_store(ce->default_static_members_table, sizeof(zval) * ce->default_static_members_count); for (i = 0; i < ce->default_static_members_count; i++) { - if (ce->default_static_members_table[i]) { - zend_persist_zval_ptr(&ce->default_static_members_table[i] TSRMLS_CC); - } + zend_persist_zval(&ce->default_static_members_table[i] TSRMLS_CC); } } ce->static_members_table = NULL; #else - zend_hash_persist(&ce->default_properties, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC); - zend_hash_persist(&ce->default_static_members, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC); + zend_hash_persist(&ce->default_properties, zend_persist_zval TSRMLS_CC); + zend_hash_persist(&ce->default_static_members, zend_persist_zval TSRMLS_CC); ce->static_members = NULL; #endif - zend_hash_persist(&ce->constants_table, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC); + zend_hash_persist(&ce->constants_table, zend_persist_zval TSRMLS_CC); if (ZEND_CE_FILENAME(ce)) { /* do not free! PHP has centralized filename storage, compiler will free it */ - ZEND_CE_FILENAME(ce) = zend_accel_memdup(ZEND_CE_FILENAME(ce), strlen(ZEND_CE_FILENAME(ce)) + 1); + zend_accel_memdup_string(ZEND_CE_FILENAME(ce)); } if (ZEND_CE_DOC_COMMENT(ce)) { if (ZCG(accel_directives).save_comments) { - zend_accel_store(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce) + 1); + zend_accel_store_string(ZEND_CE_DOC_COMMENT(ce)); } else { if (!zend_shared_alloc_get_xlat_entry(ZEND_CE_DOC_COMMENT(ce))) { zend_shared_alloc_register_xlat_entry(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT(ce)); - efree((char*)ZEND_CE_DOC_COMMENT(ce)); + STR_RELEASE(ZEND_CE_DOC_COMMENT(ce)); } ZEND_CE_DOC_COMMENT(ce) = NULL; - ZEND_CE_DOC_COMMENT_LEN(ce) = 0; } } - zend_hash_persist(&ce->properties_info, (zend_persist_func_t) zend_persist_property_info, sizeof(zend_property_info) TSRMLS_CC); + zend_hash_persist(&ce->properties_info, zend_persist_property_info TSRMLS_CC); if (ce->num_interfaces && ce->interfaces) { efree(ce->interfaces); } @@ -554,12 +663,10 @@ static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC) while (ce->trait_aliases[i]) { if (ce->trait_aliases[i]->trait_method) { if (ce->trait_aliases[i]->trait_method->method_name) { - zend_accel_store(ce->trait_aliases[i]->trait_method->method_name, - ce->trait_aliases[i]->trait_method->mname_len + 1); + zend_accel_store_interned_string(ce->trait_aliases[i]->trait_method->method_name); } if (ce->trait_aliases[i]->trait_method->class_name) { - zend_accel_store(ce->trait_aliases[i]->trait_method->class_name, - ce->trait_aliases[i]->trait_method->cname_len + 1); + zend_accel_store_interned_string(ce->trait_aliases[i]->trait_method->class_name); } ce->trait_aliases[i]->trait_method->ce = NULL; zend_accel_store(ce->trait_aliases[i]->trait_method, @@ -567,8 +674,7 @@ static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC) } if (ce->trait_aliases[i]->alias) { - zend_accel_store(ce->trait_aliases[i]->alias, - ce->trait_aliases[i]->alias_len + 1); + zend_accel_store_interned_string(ce->trait_aliases[i]->alias); } #if ZEND_EXTENSION_API_NO <= PHP_5_4_X_API_NO @@ -585,10 +691,8 @@ static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC) int i = 0; while (ce->trait_precedences[i]) { - zend_accel_store(ce->trait_precedences[i]->trait_method->method_name, - ce->trait_precedences[i]->trait_method->mname_len + 1); - zend_accel_store(ce->trait_precedences[i]->trait_method->class_name, - ce->trait_precedences[i]->trait_method->cname_len + 1); + zend_accel_store_interned_string(ce->trait_precedences[i]->trait_method->method_name); + zend_accel_store_interned_string(ce->trait_precedences[i]->trait_method->class_name); ce->trait_precedences[i]->trait_method->ce = NULL; zend_accel_store(ce->trait_precedences[i]->trait_method, sizeof(zend_trait_method_reference)); @@ -596,9 +700,8 @@ static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC) if (ce->trait_precedences[i]->exclude_from_classes) { int j = 0; - while (ce->trait_precedences[i]->exclude_from_classes[j]) { - zend_accel_store(ce->trait_precedences[i]->exclude_from_classes[j], - strlen((char*)ce->trait_precedences[i]->exclude_from_classes[j]) + 1); + while (ce->trait_precedences[i]->exclude_from_classes[j].class_name) { + zend_accel_store_interned_string(ce->trait_precedences[i]->exclude_from_classes[j].class_name); j++; } zend_accel_store(ce->trait_precedences[i]->exclude_from_classes, @@ -618,15 +721,17 @@ static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC) } } -static int zend_update_property_info_ce(zend_property_info *prop TSRMLS_DC) +static int zend_update_property_info_ce(zval *zv TSRMLS_DC) { + zend_property_info *prop = Z_PTR_P(zv); + prop->ce = zend_shared_alloc_get_xlat_entry(prop->ce); return 0; } -static int zend_update_parent_ce(zend_class_entry **pce TSRMLS_DC) +static int zend_update_parent_ce(zval *zv TSRMLS_DC) { - zend_class_entry *ce = *pce; + zend_class_entry *ce = Z_PTR_P(zv); if (ce->parent) { ce->parent = zend_shared_alloc_get_xlat_entry(ce->parent); @@ -698,18 +803,18 @@ static int zend_update_parent_ce(zend_class_entry **pce TSRMLS_DC) static void zend_accel_persist_class_table(HashTable *class_table TSRMLS_DC) { - zend_hash_persist(class_table, (zend_persist_func_t) zend_persist_class_entry, sizeof(zend_class_entry*) TSRMLS_CC); + zend_hash_persist(class_table, zend_persist_class_entry TSRMLS_CC); zend_hash_apply(class_table, (apply_func_t) zend_update_parent_ce TSRMLS_CC); } zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length TSRMLS_DC) { zend_shared_alloc_clear_xlat_table(); - zend_hash_persist(&script->function_table, (zend_persist_func_t) zend_persist_op_array, sizeof(zend_op_array) TSRMLS_CC); + zend_hash_persist(&script->function_table, zend_persist_op_array TSRMLS_CC); zend_accel_persist_class_table(&script->class_table TSRMLS_CC); zend_persist_op_array_ex(&script->main_op_array, script TSRMLS_CC); *key = zend_accel_memdup(*key, key_length + 1); - zend_accel_store(script->full_path, script->full_path_len + 1); + zend_accel_store_string(script->full_path); zend_accel_store(script, sizeof(zend_persistent_script)); return script; |