summaryrefslogtreecommitdiff
path: root/ext/opcache/zend_persist.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/opcache/zend_persist.c')
-rw-r--r--ext/opcache/zend_persist.c493
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;