diff options
Diffstat (limited to 'ext/opcache/zend_persist.c')
-rw-r--r-- | ext/opcache/zend_persist.c | 214 |
1 files changed, 68 insertions, 146 deletions
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 2a34300f77..24a3d21ca2 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -65,7 +65,6 @@ typedef void (*zend_persist_func_t)(zval*); static void zend_persist_zval(zval *z); -static void zend_persist_zval_const(zval *z); static const uint32_t uninitialized_bucket[-HT_MIN_MASK] = {HT_INVALID_IDX, HT_INVALID_IDX}; @@ -90,21 +89,21 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement void *data = HT_GET_DATA_ADDR(ht); zend_accel_store(data, HT_USED_SIZE(ht)); HT_SET_DATA_ADDR(ht, data); - } else if (ht->nNumUsed < -(int32_t)ht->nTableMask / 2) { + } else if (ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 2) { /* compact table */ void *old_data = HT_GET_DATA_ADDR(ht); Bucket *old_buckets = ht->arData; - int32_t hash_size; + uint32_t hash_size; if (ht->nNumUsed <= HT_MIN_SIZE) { hash_size = HT_MIN_SIZE; } else { - hash_size = -(int32_t)ht->nTableMask; + hash_size = (uint32_t)(-(int32_t)ht->nTableMask); while (hash_size >> 1 > ht->nNumUsed) { hash_size >>= 1; } } - ht->nTableMask = -hash_size; + ht->nTableMask = (uint32_t)(-(int32_t)hash_size); ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ HT_SET_DATA_ADDR(ht, ZCG(mem)); ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE((hash_size * sizeof(uint32_t)) + (ht->nNumUsed * sizeof(Bucket)))); @@ -172,21 +171,21 @@ static void zend_hash_persist_immutable(HashTable *ht) } if (ht->u.flags & HASH_FLAG_PACKED) { HT_SET_DATA_ADDR(ht, zend_accel_memdup(HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht))); - } else if (ht->nNumUsed < -(int32_t)ht->nTableMask / 2) { + } else if (ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 2) { /* compact table */ void *old_data = HT_GET_DATA_ADDR(ht); Bucket *old_buckets = ht->arData; - int32_t hash_size; + uint32_t hash_size; if (ht->nNumUsed <= HT_MIN_SIZE) { hash_size = HT_MIN_SIZE; } else { - hash_size = -(int32_t)ht->nTableMask; + hash_size = (uint32_t)(-(int32_t)ht->nTableMask); while (hash_size >> 1 > ht->nNumUsed) { hash_size >>= 1; } } - ht->nTableMask = -hash_size; + ht->nTableMask = (uint32_t)(-(int32_t)hash_size); ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ HT_SET_DATA_ADDR(ht, ZCG(mem)); ZCG(mem) = (void*)((char*)ZCG(mem) + (hash_size * sizeof(uint32_t)) + (ht->nNumUsed * sizeof(Bucket))); @@ -204,7 +203,7 @@ static void zend_hash_persist_immutable(HashTable *ht) } /* persist the data itself */ - zend_persist_zval_const(&p->val); + zend_persist_zval(&p->val); nIndex = p->h | ht->nTableMask; Z_NEXT(p->val) = HT_HASH(ht, nIndex); @@ -229,7 +228,7 @@ static void zend_hash_persist_immutable(HashTable *ht) } /* persist the data itself */ - zend_persist_zval_const(&p->val); + zend_persist_zval(&p->val); } } @@ -278,63 +277,10 @@ static void zend_persist_zval(zval *z) 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: - 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)); - } else { - GC_REMOVE_FROM_BUFFER(Z_ARR_P(z)); - zend_accel_store(Z_ARR_P(z), sizeof(zend_array)); - zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval); - /* make immutable array */ - Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; - GC_REFCOUNT(Z_COUNTED_P(z)) = 2; - GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE; - Z_ARRVAL_P(z)->u.flags |= HASH_FLAG_STATIC_KEYS; - Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; - } - } - break; - 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)); + if (Z_TYPE_P(z) == IS_CONSTANT) { + Z_TYPE_FLAGS_P(z) |= IS_TYPE_IMMUTABLE; } 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)); - } - break; - } -} - -static void zend_persist_zval_static(zval *z) -{ - zend_uchar flags; - void *new_ptr; - - switch (Z_TYPE_P(z)) { - case IS_STRING: - case IS_CONSTANT: - 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: new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z)); if (new_ptr) { @@ -381,62 +327,6 @@ static void zend_persist_zval_static(zval *z) } } -static void zend_persist_zval_const(zval *z) -{ - zend_uchar flags; - void *new_ptr; - - switch (Z_TYPE_P(z)) { - 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: - 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)); - } else { - GC_REMOVE_FROM_BUFFER(Z_ARR_P(z)); - zend_accel_store(Z_ARR_P(z), sizeof(zend_array)); - zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval); - /* make immutable array */ - Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; - GC_REFCOUNT(Z_COUNTED_P(z)) = 2; - GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE; - Z_ARRVAL_P(z)->u.flags |= HASH_FLAG_STATIC_KEYS; - Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; - } - } - break; - 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)); - } - 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)); - } - break; - } -} - static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_script* main_persistent_script) { int already_stored = 0; @@ -472,7 +362,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc if (stored) { op_array->static_variables = stored; } else { - zend_hash_persist(op_array->static_variables, zend_persist_zval_static); + zend_hash_persist(op_array->static_variables, zend_persist_zval); zend_accel_store(op_array->static_variables, sizeof(HashTable)); /* make immutable array */ GC_REFCOUNT(op_array->static_variables) = 2; @@ -517,22 +407,20 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc for (; opline < end ; opline++, offset++) { # if ZEND_USE_ABS_CONST_ADDR - if (ZEND_OP1_TYPE(opline) == IS_CONST) { + if (opline->op1_type == IS_CONST) { opline->op1.zv = (zval*)((char*)opline->op1.zv + ((char*)op_array->literals - (char*)orig_literals)); } - if (ZEND_OP2_TYPE(opline) == IS_CONST) { + if (opline->op2_type == IS_CONST) { opline->op2.zv = (zval*)((char*)opline->op2.zv + ((char*)op_array->literals - (char*)orig_literals)); } # endif # if ZEND_USE_ABS_JMP_ADDR - if (ZEND_DONE_PASS_TWO(op_array)) { + if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) { /* fix jumps to point to new array */ switch (opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: - case ZEND_DECLARE_ANON_CLASS: - case ZEND_DECLARE_ANON_INHERITED_CLASS: - ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes]; + opline->op1.jmp_addr = &new_opcodes[opline->op1.jmp_addr - op_array->opcodes]; break; case ZEND_JMPZNZ: /* relative extended_value don't have to be changed */ @@ -543,12 +431,13 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: - case ZEND_NEW: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: - ZEND_OP2(opline).jmp_addr = &new_opcodes[ZEND_OP2(opline).jmp_addr - op_array->opcodes]; + opline->op2.jmp_addr = &new_opcodes[opline->op2.jmp_addr - op_array->opcodes]; break; + case ZEND_DECLARE_ANON_CLASS: + case ZEND_DECLARE_ANON_INHERITED_CLASS: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: /* relative extended_value don't have to be changed */ @@ -617,8 +506,8 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc op_array->arg_info = arg_info; } - if (op_array->brk_cont_array) { - zend_accel_store(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont); + if (op_array->live_range) { + zend_accel_store(op_array->live_range, sizeof(zend_live_range) * op_array->last_live_range); } if (op_array->scope) { @@ -716,6 +605,39 @@ static void zend_persist_property_info(zval *zv) } } +static void zend_persist_class_constant(zval *zv) +{ + zend_class_constant *c = zend_shared_alloc_get_xlat_entry(Z_PTR_P(zv)); + + if (c) { + Z_PTR_P(zv) = c; + return; + } + memcpy(ZCG(arena_mem), Z_PTR_P(zv), sizeof(zend_class_constant)); + zend_shared_alloc_register_xlat_entry(Z_PTR_P(zv), ZCG(arena_mem)); + c = Z_PTR_P(zv) = ZCG(arena_mem); + ZCG(arena_mem) = (void*)((char*)ZCG(arena_mem) + ZEND_ALIGNED_SIZE(sizeof(zend_class_constant))); + zend_persist_zval(&c->value); + c->ce = zend_shared_alloc_get_xlat_entry(c->ce); + if (c->doc_comment) { + if (ZCG(accel_directives).save_comments) { + zend_string *doc_comment = zend_shared_alloc_get_xlat_entry(c->doc_comment); + if (doc_comment) { + c->doc_comment = doc_comment; + } else { + zend_accel_store_string(c->doc_comment); + } + } else { + zend_string *doc_comment = zend_shared_alloc_get_xlat_entry(c->doc_comment); + if (!doc_comment) { + zend_shared_alloc_register_xlat_entry(c->doc_comment, c->doc_comment); + zend_string_release(c->doc_comment); + } + c->doc_comment = NULL; + } + } +} + static void zend_persist_class_entry(zval *zv) { zend_class_entry *ce = Z_PTR_P(zv); @@ -745,21 +667,21 @@ static void zend_persist_class_entry(zval *zv) } ce->static_members_table = NULL; - zend_hash_persist(&ce->constants_table, zend_persist_zval); + zend_hash_persist(&ce->constants_table, zend_persist_class_constant); - if (ZEND_CE_FILENAME(ce)) { + if (ce->info.user.filename) { /* do not free! PHP has centralized filename storage, compiler will free it */ - zend_accel_memdup_string(ZEND_CE_FILENAME(ce)); + zend_accel_memdup_string(ce->info.user.filename); } - if (ZEND_CE_DOC_COMMENT(ce)) { + if (ce->info.user.doc_comment) { if (ZCG(accel_directives).save_comments) { - zend_accel_store_string(ZEND_CE_DOC_COMMENT(ce)); + zend_accel_store_string(ce->info.user.doc_comment); } 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)); - zend_string_release(ZEND_CE_DOC_COMMENT(ce)); + if (!zend_shared_alloc_get_xlat_entry(ce->info.user.doc_comment)) { + zend_shared_alloc_register_xlat_entry(ce->info.user.doc_comment, ce->info.user.doc_comment); + zend_string_release(ce->info.user.doc_comment); } - ZEND_CE_DOC_COMMENT(ce) = NULL; + ce->info.user.doc_comment = NULL; } } zend_hash_persist(&ce->properties_info, zend_persist_property_info); @@ -906,7 +828,7 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script if (key && *key) { *key = zend_accel_memdup(*key, key_length + 1); } - zend_accel_store_string(script->full_path); + zend_accel_store_string(script->script.filename); #ifdef __SSE2__ /* Align to 64-byte boundary */ @@ -918,9 +840,9 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script script->arena_mem = ZCG(arena_mem) = ZCG(mem); ZCG(mem) = (void*)((char*)ZCG(mem) + script->arena_size); - zend_accel_persist_class_table(&script->class_table); - zend_hash_persist(&script->function_table, zend_persist_op_array); - zend_persist_op_array_ex(&script->main_op_array, script); + zend_accel_persist_class_table(&script->script.class_table); + zend_hash_persist(&script->script.function_table, zend_persist_op_array); + zend_persist_op_array_ex(&script->script.main_op_array, script); return script; } |