From: Dmitry Stogov Date: Fri, 28 Mar 2014 19:34:49 +0000 (+0400) Subject: ext/opcache refactoring (incomplete) X-Git-Tag: POST_PHPNG_MERGE~412^2~206^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5324f22f598c88041866b60235193e73bcaac171;p=php ext/opcache refactoring (incomplete) --- diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 6d8a10b57a..fb299d31ec 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -459,7 +459,7 @@ struct _zend_ast_ref { _ref->gc.refcount = 1; \ _ref->gc.u.v.type = IS_REFERENCE; \ _ref->gc.u.v.gc_info = 0; \ - _ref->val = *(r); \ + ZVAL_COPY_VALUE(&_ref->val, r); \ Z_REF_P(z) = _ref; \ Z_TYPE_P(z) = IS_REFERENCE; \ } while (0) diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index a6114733e3..26d4f99d23 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -1,19 +1,19 @@ #define DEBUG_BLOCKPASS 0 /* Checks if a constant (like "true") may be replaced by its value */ -static int zend_get_persistent_constant(char *name, uint name_len, zval *result, int copy TSRMLS_DC ELS_DC) +static int zend_get_persistent_constant(zend_string *name, zval *result, int copy TSRMLS_DC ELS_DC) { zend_constant *c; char *lookup_name; int retval = 1; ALLOCA_FLAG(use_heap); - if (zend_hash_find(EG(zend_constants), name, name_len + 1, (void **) &c) == FAILURE) { - lookup_name = DO_ALLOCA(name_len + 1); - memcpy(lookup_name, name, name_len + 1); - zend_str_tolower(lookup_name, name_len); + if ((c = zend_hash_find_ptr(EG(zend_constants), name)) == NULL) { + lookup_name = DO_ALLOCA(name->len + 1); + memcpy(lookup_name, name->val, name->len + 1); + zend_str_tolower(lookup_name, name->len); - if (zend_hash_find(EG(zend_constants), lookup_name, name_len + 1, (void **) &c) == SUCCESS) { + if ((c = zend_hash_str_find_ptr(EG(zend_constants), lookup_name, name->len)) != NULL) { if (!(c->flags & CONST_CT_SUBST) || (c->flags & CONST_CS)) { retval = 0; } @@ -553,7 +553,7 @@ static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int #define convert_to_string_safe(v) \ if (Z_TYPE_P((v)) == IS_NULL) { \ - ZVAL_STRINGL((v), "", 0, 1); \ + ZVAL_STRINGL((v), "", 0); \ } else { \ convert_to_string((v)); \ } @@ -740,7 +740,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, int flen = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].name_len; if(flen == sizeof("defined")-1 && zend_binary_strcasecmp(fname, flen, "defined", sizeof("defined")-1) == 0) { zval c; - if(zend_get_persistent_constant(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &c, 0 TSRMLS_CC ELS_CC) != 0) { + if(zend_get_persistent_constant(Z_STR_P(arg), &c, 0 TSRMLS_CC ELS_CC) != 0) { literal_dtor(arg); MAKE_NOP(sv); MAKE_NOP(fcall); @@ -760,7 +760,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, } } else if(flen == sizeof("constant")-1 && zend_binary_strcasecmp(fname, flen, "constant", sizeof("constant")-1) == 0) { zval c; - if(zend_get_persistent_constant(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &c, 1 TSRMLS_CC ELS_CC) != 0) { + if(zend_get_persistent_constant(Z_STR_P(arg), &c, 1 TSRMLS_CC ELS_CC) != 0) { literal_dtor(arg); MAKE_NOP(sv); MAKE_NOP(fcall); @@ -916,18 +916,18 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, convert_to_string_safe(&ZEND_OP1_LITERAL(last_op)); } l = Z_STRLEN(ZEND_OP1_LITERAL(opline)) + Z_STRLEN(ZEND_OP1_LITERAL(last_op)); - if (IS_INTERNED(Z_STRVAL(ZEND_OP1_LITERAL(last_op)))) { - char *tmp = emalloc(l + 1); - memcpy(tmp, Z_STRVAL(ZEND_OP1_LITERAL(last_op)), l + 1); - Z_STRVAL(ZEND_OP1_LITERAL(last_op)) = tmp; + if (IS_INTERNED(Z_STR(ZEND_OP1_LITERAL(last_op)))) { + zend_string *tmp = STR_ALLOC(l, 0); + memcpy(tmp->val, Z_STRVAL(ZEND_OP1_LITERAL(last_op)), l); + Z_STR(ZEND_OP1_LITERAL(last_op)) = tmp; } else { - Z_STRVAL(ZEND_OP1_LITERAL(last_op)) = erealloc(Z_STRVAL(ZEND_OP1_LITERAL(last_op)), l + 1); + Z_STR(ZEND_OP1_LITERAL(last_op)) = STR_REALLOC(Z_STR(ZEND_OP1_LITERAL(last_op)), l, 0); } memcpy(Z_STRVAL(ZEND_OP1_LITERAL(last_op))+Z_STRLEN(ZEND_OP1_LITERAL(last_op)), Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline))); Z_STRVAL(ZEND_OP1_LITERAL(last_op))[l] = '\0'; zval_dtor(&ZEND_OP1_LITERAL(opline)); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - Z_STRVAL(ZEND_OP1_LITERAL(opline)) = (char*)zend_new_interned_string(Z_STRVAL(ZEND_OP1_LITERAL(last_op)), l + 1, 1 TSRMLS_CC); + Z_STR(ZEND_OP1_LITERAL(opline)) = zend_new_interned_string(Z_STR(ZEND_OP1_LITERAL(last_op))TSRMLS_CC); Z_TYPE(ZEND_OP1_LITERAL(last_op)) = IS_NULL; #else Z_STRVAL(ZEND_OP1_LITERAL(opline)) = Z_STRVAL(ZEND_OP1_LITERAL(last_op)); @@ -960,20 +960,18 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, } COPY_NODE(opline->op1, src->op1); l = Z_STRLEN(ZEND_OP2_LITERAL(opline)) + Z_STRLEN(ZEND_OP2_LITERAL(src)); - if (IS_INTERNED(Z_STRVAL(ZEND_OP2_LITERAL(src)))) { - char *tmp = emalloc(l + 1); - memcpy(tmp, Z_STRVAL(ZEND_OP2_LITERAL(src)), l + 1); - Z_STRVAL(ZEND_OP2_LITERAL(src)) = tmp; + if (IS_INTERNED(Z_STR(ZEND_OP2_LITERAL(src)))) { + zend_string *tmp = STR_ALLOC(l, 0); + memcpy(tmp->val, Z_STRVAL(ZEND_OP2_LITERAL(last_op)), l); + Z_STR(ZEND_OP2_LITERAL(last_op)) = tmp; } else { - Z_STRVAL(ZEND_OP2_LITERAL(src)) = erealloc(Z_STRVAL(ZEND_OP2_LITERAL(src)), l + 1); + Z_STR(ZEND_OP2_LITERAL(src)) = STR_REALLOC(Z_STR(ZEND_OP2_LITERAL(src)), l, 0); } memcpy(Z_STRVAL(ZEND_OP2_LITERAL(src))+Z_STRLEN(ZEND_OP2_LITERAL(src)), Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline))); Z_STRVAL(ZEND_OP2_LITERAL(src))[l] = '\0'; - if (!IS_INTERNED(Z_STRVAL(ZEND_OP2_LITERAL(opline)))) { - efree(Z_STRVAL(ZEND_OP2_LITERAL(opline))); - } + STR_RELEASE(Z_STR(ZEND_OP2_LITERAL(opline))); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - Z_STRVAL(ZEND_OP2_LITERAL(opline)) = (char*)zend_new_interned_string(Z_STRVAL(ZEND_OP2_LITERAL(src)), l + 1, 1 TSRMLS_CC); + Z_STR(ZEND_OP2_LITERAL(opline)) = zend_new_interned_string(Z_STR(ZEND_OP2_LITERAL(src)) TSRMLS_CC); Z_TYPE(ZEND_OP2_LITERAL(src)) = IS_NULL; #else Z_STRVAL(ZEND_OP2_LITERAL(opline)) = Z_STRVAL(ZEND_OP2_LITERAL(src)); @@ -987,7 +985,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, } else if (opline->opcode == ZEND_ADD_CHAR && ZEND_OP1_TYPE(opline) == IS_CONST && ZEND_OP2_TYPE(opline) == IS_CONST) { /* convert ADD_CHAR(C1, C2) to CONCAT(C1, C2) */ char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline)); - ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1, 1); + ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1); opline->opcode = ZEND_CONCAT; continue; } else if ((opline->opcode == ZEND_ADD || @@ -1029,8 +1027,8 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, er = EG(error_reporting); EG(error_reporting) = 0; if (binary_op(&result, &ZEND_OP1_LITERAL(opline), &ZEND_OP2_LITERAL(opline) TSRMLS_CC) == SUCCESS) { - PZ_SET_REFCOUNT_P(&result, 1); - PZ_UNSET_ISREF_P(&result); +//??? PZ_SET_REFCOUNT_P(&result, 1); +//??? PZ_UNSET_ISREF_P(&result); literal_dtor(&ZEND_OP1_LITERAL(opline)); literal_dtor(&ZEND_OP2_LITERAL(opline)); @@ -1059,8 +1057,8 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, convert_to_boolean(&result); Z_TYPE(ZEND_OP1_LITERAL(opline)) = IS_NULL; } - PZ_SET_REFCOUNT_P(&result, 1); - PZ_UNSET_ISREF_P(&result); +//??? PZ_SET_REFCOUNT_P(&result, 1); +//??? PZ_UNSET_ISREF_P(&result); opline->opcode = ZEND_QM_ASSIGN; update_op1_const(op_array, opline, &result TSRMLS_CC); } else if ((opline->opcode == ZEND_RETURN || opline->opcode == ZEND_EXIT) && @@ -1086,7 +1084,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, COPY_NODE(opline->op1, opline->op2); if (opline->opcode == ZEND_ADD_CHAR) { char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline)); - ZVAL_STRINGL(&ZEND_OP1_LITERAL(opline), &c, 1, 1); + ZVAL_STRINGL(&ZEND_OP1_LITERAL(opline), &c, 1); } SET_UNUSED(opline->op2); MAKE_NOP(src); @@ -1107,7 +1105,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, COPY_NODE(opline->op1, src->op1); if (opline->opcode == ZEND_ADD_CHAR) { char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline)); - ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1, 1); + ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1); } opline->opcode = ZEND_CONCAT; literal_dtor(&ZEND_OP2_LITERAL(src)); /* will take care of empty_string too */ @@ -1138,7 +1136,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, COPY_NODE(opline->op1, src->op1); if (opline->opcode == ZEND_ADD_CHAR) { char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline)); - ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1, 1); + ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1); } opline->opcode = ZEND_CONCAT; MAKE_NOP(src); @@ -1889,8 +1887,8 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * return; } - usage = ecalloc(op_array->T, 1); - defined_here = emalloc(op_array->T); + usage = ecalloc(op_array->last_var + op_array->T, 1); + defined_here = emalloc(op_array->last_var + op_array->T); while (next_block) { zend_op *opline = next_block->start_opline; @@ -1900,7 +1898,7 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * next_block = next_block->next; continue; } - memset(defined_here, 0, op_array->T); + memset(defined_here, 0, op_array->last_var + op_array->T); while (oplineop1); @@ -1927,7 +1925,7 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * #if DEBUG_BLOCKPASS { int i; - for (i = 0; i< op_array->T; i++) { + for (i = op_array->last_var; i< op_array->T; i++) { fprintf(stderr, "T%d: %c\n", i, used_ext[i] + '0'); } } @@ -1941,7 +1939,7 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * continue; } - memcpy(usage, used_ext, op_array->T); + memcpy(usage, used_ext, op_array->last_var + op_array->T); while (opline >= block->start_opline) { /* usage checks */ @@ -2067,10 +2065,10 @@ static void zend_block_optimization(zend_op_array *op_array TSRMLS_DC) zend_rebuild_access_path(&cfg, op_array, 0); /* full rebuild here to produce correct sources! */ - usage = emalloc(op_array->T); + usage = emalloc(op_array->last_var + op_array->T); for (pass = 0; pass < PASSES; pass++) { /* Compute data dependencies */ - memset(usage, 0, op_array->T); + memset(usage, 0, op_array->last_var + op_array->T); zend_t_usage(cfg.blocks, op_array, usage); /* optimize each basic block separately */ @@ -2093,7 +2091,7 @@ static void zend_block_optimization(zend_op_array *op_array TSRMLS_DC) zend_rebuild_access_path(&cfg, op_array, 1); } - memset(usage, 0, op_array->T); + memset(usage, 0, op_array->last_var + op_array->T); zend_t_usage(cfg.blocks, op_array, usage); assemble_code_blocks(&cfg, op_array); efree(usage); diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 1604107f2c..4fa3c7d33d 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -91,14 +91,12 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) { zend_op *opline, *end; int i, j, n, *pos, *map, cache_slots; - ulong h; literal_info *info; int l_null = -1; int l_false = -1; int l_true = -1; HashTable hash; - char *key; - int key_len; + zend_string *key; if (op_array->last_literal) { info = (literal_info*)ecalloc(op_array->last_literal, sizeof(literal_info)); @@ -283,7 +281,7 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) /* Merge equal constants */ j = 0; cache_slots = 0; zend_hash_init(&hash, 16, NULL, NULL, 0); - hash.flags |= HASH_FLAG_BIG_DATA; +//??? hash.flags |= HASH_FLAG_BIG_DATA; map = (int*)ecalloc(op_array->last_literal, sizeof(int)); for (i = 0; i < op_array->last_literal; i++) { if (!info[i].flags) { @@ -327,11 +325,11 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) } break; case IS_LONG: - if (zend_hash_index_find(&hash, Z_LVAL(op_array->literals[i].constant), (void**)&pos) == SUCCESS) { + if ((pos = zend_hash_index_find_ptr(&hash, Z_LVAL(op_array->literals[i].constant))) != NULL) { map[i] = *pos; } else { map[i] = j; - zend_hash_index_update(&hash, Z_LVAL(op_array->literals[i].constant), (void**)&j, sizeof(int), NULL); + zend_hash_index_update_ptr(&hash, Z_LVAL(op_array->literals[i].constant), (void**)&j); if (i != j) { op_array->literals[j] = op_array->literals[i]; info[j] = info[i]; @@ -340,11 +338,11 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) } break; case IS_DOUBLE: - if (zend_hash_find(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double), (void**)&pos) == SUCCESS) { + if ((pos = zend_hash_str_find_ptr(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double))) != NULL) { map[i] = *pos; } else { map[i] = j; - zend_hash_add(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double), (void**)&j, sizeof(int), NULL); + zend_hash_str_add_ptr(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double), (void**)&j); if (i != j) { op_array->literals[j] = op_array->literals[i]; info[j] = info[i]; @@ -356,27 +354,27 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) case IS_CONSTANT: if (info[i].flags & LITERAL_MAY_MERGE) { if (info[i].flags & LITERAL_EX_OBJ) { - key_len = MAX_LENGTH_OF_LONG + sizeof("->") + Z_STRLEN(op_array->literals[i].constant); - key = emalloc(key_len); - key_len = snprintf(key, key_len-1, "%d->%s", info[i].u.num, Z_STRVAL(op_array->literals[i].constant)); + int key_len = MAX_LENGTH_OF_LONG + sizeof("->") + Z_STRLEN(op_array->literals[i].constant); + key = STR_ALLOC(key_len, 0); + key->len = snprintf(key->val, key->len-1, "%d->%s", info[i].u.num, Z_STRVAL(op_array->literals[i].constant)); } else if (info[i].flags & LITERAL_EX_CLASS) { + int key_len; zval *class_name = &op_array->literals[(info[i].u.num < i) ? map[info[i].u.num] : info[i].u.num].constant; key_len = Z_STRLEN_P(class_name) + sizeof("::") + Z_STRLEN(op_array->literals[i].constant); - key = emalloc(key_len); + key = STR_ALLOC(key_len, 0); memcpy(key, Z_STRVAL_P(class_name), Z_STRLEN_P(class_name)); memcpy(key + Z_STRLEN_P(class_name), "::", sizeof("::") - 1); memcpy(key + Z_STRLEN_P(class_name) + sizeof("::") - 1, Z_STRVAL(op_array->literals[i].constant), Z_STRLEN(op_array->literals[i].constant) + 1); } else { - key = Z_STRVAL(op_array->literals[i].constant); - key_len = Z_STRLEN(op_array->literals[i].constant)+1; + key = STR_INIT(Z_STRVAL(op_array->literals[i].constant), Z_STRLEN(op_array->literals[i].constant), 0); } - h = zend_hash_func(key, key_len); - h += info[i].flags; + key->h = zend_hash_func(key->val, key->len); + key->h += info[i].flags; } if ((info[i].flags & LITERAL_MAY_MERGE) && - zend_hash_quick_find(&hash, key, key_len, h, (void**)&pos) == SUCCESS && + (pos = zend_hash_find_ptr(&hash, key)) != NULL && Z_TYPE(op_array->literals[i].constant) == Z_TYPE(op_array->literals[*pos].constant) && info[i].flags == info[*pos].flags) { @@ -394,22 +392,22 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) } else { map[i] = j; if (info[i].flags & LITERAL_MAY_MERGE) { - zend_hash_quick_add(&hash, key, key_len, h, (void**)&j, sizeof(int), NULL); + zend_hash_add_ptr(&hash, key, (void**)&j); if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) { - efree(key); + STR_RELEASE(key); } } if (i != j) { op_array->literals[j] = op_array->literals[i]; info[j] = info[i]; } - if (!op_array->literals[j].hash_value) { - if (IS_INTERNED(Z_STRVAL(op_array->literals[j].constant))) { - op_array->literals[j].hash_value = INTERNED_HASH(Z_STRVAL(op_array->literals[j].constant)); - } else { - op_array->literals[j].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[j].constant), Z_STRLEN(op_array->literals[j].constant)+1); - } - } +//??? if (!Z_STR(op_array->literals[j].hash_value) { +//??? if (IS_INTERNED(Z_STRVAL(op_array->literals[j].constant))) { +//??? op_array->literals[j].hash_value = INTERNED_HASH(Z_STRVAL(op_array->literals[j].constant)); +//??? } else { +//??? op_array->literals[j].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[j].constant), Z_STRLEN(op_array->literals[j].constant)+1); +//??? } +//??? } if (LITERAL_NUM_SLOTS(info[i].flags)) { op_array->literals[j].cache_slot = cache_slots; cache_slots += LITERAL_NUM_SLOTS(info[i].flags); @@ -419,13 +417,13 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) while (n > 1) { i++; if (i != j) op_array->literals[j] = op_array->literals[i]; - if (!op_array->literals[j].hash_value) { - if (IS_INTERNED(Z_STRVAL(op_array->literals[j].constant))) { - op_array->literals[j].hash_value = INTERNED_HASH(Z_STRVAL(op_array->literals[j].constant)); - } else { - op_array->literals[j].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[j].constant), Z_STRLEN(op_array->literals[j].constant)+1); - } - } +//??? if (!op_array->literals[j].hash_value) { +//??? if (IS_INTERNED(Z_STRVAL(op_array->literals[j].constant))) { +//??? op_array->literals[j].hash_value = INTERNED_HASH(Z_STRVAL(op_array->literals[j].constant)); +//??? } else { +//??? op_array->literals[j].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[j].constant), Z_STRLEN(op_array->literals[j].constant)+1); +//??? } +//??? } j++; n--; } diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index 14f8255653..d7461b5908 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -26,9 +26,8 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script if (ZEND_OP2_TYPE(opline) == IS_CONST) { zend_function *func; zval *function_name = &op_array->literals[opline->op2.constant + 1].constant; - if ((zend_hash_quick_find(&script->function_table, - Z_STRVAL_P(function_name), Z_STRLEN_P(function_name) + 1, - Z_HASH_P(function_name), (void **)&func) == SUCCESS)) { + if ((func = zend_hash_find_ptr(&script->function_table, + Z_STR_P(function_name))) != NULL) { call_stack[call].func = func; } } diff --git a/ext/opcache/Optimizer/optimize_temp_vars_5.c b/ext/opcache/Optimizer/optimize_temp_vars_5.c index dc630733fa..7c94379416 100644 --- a/ext/opcache/Optimizer/optimize_temp_vars_5.c +++ b/ext/opcache/Optimizer/optimize_temp_vars_5.c @@ -73,6 +73,7 @@ static const char op_const_means_class[256] = { static void optimize_temporary_variables(zend_op_array *op_array) { int T = op_array->T; + int offset = op_array->last_var; char *taken_T; /* T index in use */ zend_op **start_of_T; /* opline where T is first used */ char *valid_T; /* Is the map_T valid */ @@ -96,12 +97,12 @@ static void optimize_temporary_variables(zend_op_array *op_array) #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR | IS_CONST)) { if (!(op_const_means_class[opline->opcode] & RESULT_IS_UNUSED)) { - start_of_T[VAR_NUM(ZEND_RESULT(opline).var)] = opline; + start_of_T[VAR_NUM(ZEND_RESULT(opline).var) - offset] = opline; } } #else if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR)) { - start_of_T[VAR_NUM(ZEND_RESULT(opline).var)] = opline; + start_of_T[VAR_NUM(ZEND_RESULT(opline).var) - offset] = opline; } #endif opline--; @@ -119,13 +120,13 @@ static void optimize_temporary_variables(zend_op_array *op_array) || ((op_const_means_class[opline->opcode] & OP1_CONST_IS_CLASS) && ZEND_OP1_TYPE(opline) == IS_CONST) #endif ) { - currT = VAR_NUM(ZEND_OP1(opline).var); + currT = VAR_NUM(ZEND_OP1(opline).var) - offset; if (!valid_T[currT]) { GET_AVAILABLE_T(); map_T[currT] = i; valid_T[currT] = 1; } - ZEND_OP1(opline).var = NUM_VAR(map_T[currT]); + ZEND_OP1(opline).var = NUM_VAR(map_T[currT] + offset); } /* Skip OP_DATA */ @@ -140,13 +141,13 @@ static void optimize_temporary_variables(zend_op_array *op_array) || ((op_const_means_class[opline->opcode] & OP2_CONST_IS_CLASS) && ZEND_OP2_TYPE(opline) == IS_CONST) #endif ) { - currT = VAR_NUM(ZEND_OP2(opline).var); + currT = VAR_NUM(ZEND_OP2(opline).var) - offset; if (!valid_T[currT]) { GET_AVAILABLE_T(); map_T[currT] = i; valid_T[currT] = 1; } - ZEND_OP2(opline).var = NUM_VAR(map_T[currT]); + ZEND_OP2(opline).var = NUM_VAR(map_T[currT] + offset); } #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO @@ -155,25 +156,25 @@ static void optimize_temporary_variables(zend_op_array *op_array) if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS || opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) { #endif - currT = VAR_NUM(opline->extended_value); + currT = VAR_NUM(opline->extended_value) - offset; if (!valid_T[currT]) { GET_AVAILABLE_T(); map_T[currT] = i; valid_T[currT] = 1; } - opline->extended_value = NUM_VAR(map_T[currT]); + opline->extended_value = NUM_VAR(map_T[currT] + offset); } /* Allocate OP_DATA->op2 after "operands", but before "result" */ if (opline->opcode == ZEND_ASSIGN_DIM && (opline + 1)->opcode == ZEND_OP_DATA && ZEND_OP2_TYPE(opline + 1) & (IS_VAR | IS_TMP_VAR)) { - currT = VAR_NUM(ZEND_OP2(opline + 1).var); + currT = VAR_NUM(ZEND_OP2(opline + 1).var) - offset; GET_AVAILABLE_T(); map_T[currT] = i; valid_T[currT] = 1; taken_T[i] = 0; - ZEND_OP2(opline + 1).var = NUM_VAR(i); + ZEND_OP2(opline + 1).var = NUM_VAR(i + offset); var_to_free = i; } @@ -183,12 +184,12 @@ static void optimize_temporary_variables(zend_op_array *op_array) #else if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR)) { #endif - currT = VAR_NUM(ZEND_RESULT(opline).var); + currT = VAR_NUM(ZEND_RESULT(opline).var) - offset; if (valid_T[currT]) { if (start_of_T[currT] == opline) { taken_T[map_T[currT]] = 0; } - ZEND_RESULT(opline).var = NUM_VAR(map_T[currT]); + ZEND_RESULT(opline).var = NUM_VAR(map_T[currT] + offset); } else { /* Au still needs to be assigned a T which is a bit dumb. Should consider changing Zend */ GET_AVAILABLE_T(); @@ -199,7 +200,7 @@ static void optimize_temporary_variables(zend_op_array *op_array) map_T[currT] = i; valid_T[currT] = 1; } - ZEND_RESULT(opline).var = NUM_VAR(i); + ZEND_RESULT(opline).var = NUM_VAR(i + offset); } #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO } diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 577d1b6609..e828ae2357 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -60,8 +60,8 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { break; } EG(error_reporting) = er; - PZ_SET_REFCOUNT_P(&result, 1); - PZ_UNSET_ISREF_P(&result); +//??? PZ_SET_REFCOUNT_P(&result, 1); +//??? PZ_UNSET_ISREF_P(&result); literal_dtor(&ZEND_OP1_LITERAL(opline)); literal_dtor(&ZEND_OP2_LITERAL(opline)); @@ -130,8 +130,8 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { break; } EG(error_reporting) = er; - PZ_SET_REFCOUNT_P(&result, 1); - PZ_UNSET_ISREF_P(&result); +//??? PZ_SET_REFCOUNT_P(&result, 1); +//??? PZ_UNSET_ISREF_P(&result); literal_dtor(&ZEND_OP1_LITERAL(opline)); MAKE_NOP(opline); @@ -146,6 +146,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { zend_op *next_op = opline + 1; int requires_conversion = (opline->opcode == ZEND_ADD_CHAR? 1 : 0); size_t final_length = 0; + zend_string *str; char *ptr; zend_op *last_op; @@ -161,7 +162,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { if (next_op->opcode == ZEND_ADD_CHAR) { final_length += 1; } else { /* ZEND_ADD_STRING */ - final_length += ZEND_OP2_LITERAL(next_op).value.str.len; + final_length += Z_STRLEN(ZEND_OP2_LITERAL(next_op)); } next_op++; } @@ -169,34 +170,32 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { break; } last_op = next_op; - final_length += (requires_conversion? 1 : ZEND_OP2_LITERAL(opline).value.str.len); - ptr = (char *)emalloc(final_length + 1); + final_length += (requires_conversion? 1 : Z_STRLEN(ZEND_OP2_LITERAL(opline))); + str = STR_ALLOC(final_length, 0); + ptr = str->val; ptr[final_length] = '\0'; if (requires_conversion) { /* ZEND_ADD_CHAR */ - char chval = (char)ZEND_OP2_LITERAL(opline).value.lval; + char chval = (char)Z_LVAL(ZEND_OP2_LITERAL(opline)); - ZEND_OP2_LITERAL(opline).value.str.val = ptr; + ZVAL_STR(&ZEND_OP2_LITERAL(opline), str); ptr[0] = chval; - ZEND_OP2_LITERAL(opline).type = IS_STRING; opline->opcode = ZEND_ADD_STRING; ptr++; } else { /* ZEND_ADD_STRING */ memcpy(ptr, Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline))); - if (!IS_INTERNED(Z_STRVAL(ZEND_OP2_LITERAL(opline)))) { - efree(Z_STRVAL(ZEND_OP2_LITERAL(opline))); - } - Z_STRVAL(ZEND_OP2_LITERAL(opline)) = ptr; + STR_RELEASE(Z_STR(ZEND_OP2_LITERAL(opline))); + Z_STR(ZEND_OP2_LITERAL(opline)) = str; ptr += Z_STRLEN(ZEND_OP2_LITERAL(opline)); } - ZEND_OP2_LITERAL(opline).value.str.len = final_length; + Z_STRLEN(ZEND_OP2_LITERAL(opline)) = final_length; next_op = opline + 1; while (next_op < last_op) { if (next_op->opcode == ZEND_ADD_STRING) { - memcpy(ptr, ZEND_OP2_LITERAL(next_op).value.str.val, ZEND_OP2_LITERAL(next_op).value.str.len); - ptr += ZEND_OP2_LITERAL(next_op).value.str.len; + memcpy(ptr, Z_STRVAL(ZEND_OP2_LITERAL(next_op)), Z_STRLEN(ZEND_OP2_LITERAL(next_op))); + ptr += Z_STRLEN(ZEND_OP2_LITERAL(next_op)); literal_dtor(&ZEND_OP2_LITERAL(next_op)); } else { /* ZEND_ADD_CHAR */ - *ptr = (char)ZEND_OP2_LITERAL(next_op).value.lval; + *ptr = (char)Z_LVAL(ZEND_OP2_LITERAL(next_op)); ptr++; } MAKE_NOP(next_op); @@ -244,7 +243,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { zend_uint tv = ZEND_RESULT(opline).var; zval c; - if (!zend_get_persistent_constant(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), &c, 1 TSRMLS_CC)) { + if (!zend_get_persistent_constant(Z_STR(ZEND_OP2_LITERAL(opline)), &c, 1 TSRMLS_CC)) { if (!*constants || !zend_optimizer_get_collected_constant(*constants, &ZEND_OP2_LITERAL(opline), &c)) { break; } @@ -260,25 +259,22 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { ZEND_OP2_TYPE(opline) == IS_CONST && ZEND_OP2_LITERAL(opline).type == IS_STRING) { - zend_class_entry **pce = NULL; + zend_class_entry *ce = NULL; if (ZEND_OP1_TYPE(opline) == IS_CONST && ZEND_OP1_LITERAL(opline).type == IS_STRING) { /* for A::B */ if (op_array->scope && !strncasecmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), - op_array->scope->name, Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1)) { - pce = &op_array->scope; + op_array->scope->name->val, Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1)) { + ce = op_array->scope; } else { - if (zend_hash_quick_find(EG(class_table), - Z_STRVAL(op_array->literals[opline->op1.constant + 1].constant), - Z_STRLEN(op_array->literals[opline->op1.constant].constant) + 1, - Z_HASH_P(&op_array->literals[opline->op1.constant + 1].constant), - (void **)&pce) == FAILURE || - ((*pce)->type == ZEND_INTERNAL_CLASS && - (*pce)->info.internal.module->type != MODULE_PERSISTENT) || - ((*pce)->type == ZEND_USER_CLASS && - ZEND_CE_FILENAME(*pce) != op_array->filename)) { + if ((ce = zend_hash_find_ptr(EG(class_table), + Z_STR(op_array->literals[opline->op1.constant + 1].constant))) == NULL || + (ce->type == ZEND_INTERNAL_CLASS && + ce->info.internal.module->type != MODULE_PERSISTENT) || + (ce->type == ZEND_USER_CLASS && + ZEND_CE_FILENAME(ce) != op_array->filename)) { break; } } @@ -289,24 +285,22 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { ((opline - 1)->extended_value & ~ZEND_FETCH_CLASS_NO_AUTOLOAD) == ZEND_FETCH_CLASS_SELF) && ZEND_RESULT((opline - 1)).var == ZEND_OP1(opline).var) { /* for self::B */ - pce = &op_array->scope; + ce = op_array->scope; } - if (pce) { + if (ce) { zend_uint tv = ZEND_RESULT(opline).var; - zval **c, t; - - if (zend_hash_find(&(*pce)->constants_table, - Z_STRVAL(ZEND_OP2_LITERAL(opline)), - Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1, - (void **) &c) == SUCCESS) { - if (ZEND_IS_CONSTANT_TYPE(Z_TYPE_PP(c))) { - if (!zend_get_persistent_constant(Z_STRVAL_PP(c), Z_STRLEN_PP(c), &t, 1 TSRMLS_CC) || + zval *c, t; + + if ((c = zend_hash_find(&ce->constants_table, + Z_STR(ZEND_OP2_LITERAL(opline)))) != NULL) { + if (ZEND_IS_CONSTANT_TYPE(Z_TYPE_P(c))) { + if (!zend_get_persistent_constant(Z_STR_P(c), &t, 1 TSRMLS_CC) || ZEND_IS_CONSTANT_TYPE(Z_TYPE(t))) { break; } } else { - t = **c; + ZVAL_COPY_VALUE(&t, c); zval_copy_ctor(&t); } @@ -366,8 +360,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { char *lc_name = zend_str_tolower_dup( Z_STRVAL(ZEND_OP1_LITERAL(opline - 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline - 1))); - if (zend_hash_find(EG(function_table), lc_name, Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)) + 1, - (void *)&func) == SUCCESS && + if ((func = zend_hash_str_find_ptr(EG(function_table), lc_name, Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)))) != NULL && func->type == ZEND_INTERNAL_FUNCTION && func->module->type == MODULE_PERSISTENT) { zval t; @@ -384,14 +377,13 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { !memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), "extension_loaded", sizeof("extension_loaded")-1)) { zval t; - zend_module_entry *m; char *lc_name = zend_str_tolower_dup( Z_STRVAL(ZEND_OP1_LITERAL(opline - 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline - 1))); - int found = zend_hash_find(&module_registry, - lc_name, Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)) + 1, (void *)&m) == SUCCESS; + zend_module_entry *m = zend_hash_str_find_ptr(&module_registry, + lc_name, Z_STRLEN(ZEND_OP1_LITERAL(opline - 1))); efree(lc_name); - if (!found) { + if (!m) { if (!PG(enable_dl)) { break; } else { @@ -416,8 +408,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { "defined", sizeof("defined")-1)) { zval t; - if (zend_get_persistent_constant(Z_STRVAL(ZEND_OP1_LITERAL(opline - 1)), - Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)), &t, 0 TSRMLS_CC)) { + if (zend_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline - 1)), &t, 0 TSRMLS_CC)) { ZVAL_BOOL(&t, 1); if (replace_var_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { @@ -432,8 +423,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { "constant", sizeof("constant")-1)) { zval t; - if (zend_get_persistent_constant(Z_STRVAL(ZEND_OP1_LITERAL(opline - 1)), - Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)), &t, 1 TSRMLS_CC)) { + if (zend_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline - 1)), &t, 1 TSRMLS_CC)) { if (replace_var_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { literal_dtor(&ZEND_OP1_LITERAL(opline - 1)); MAKE_NOP((opline - 1)); @@ -557,14 +547,12 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { if (use->op1_type == IS_VAR && use->op1.var == var) { use->op1_type = IS_CV; use->op1.var = zend_optimizer_lookup_cv(op_array, - Z_STRVAL(ZEND_OP1_LITERAL(opline)), - Z_STRLEN(ZEND_OP1_LITERAL(opline))); + Z_STR(ZEND_OP1_LITERAL(opline))); MAKE_NOP(opline); } else if (use->op2_type == IS_VAR && use->op2.var == var) { use->op2_type = IS_CV; use->op2.var = zend_optimizer_lookup_cv(op_array, - Z_STRVAL(ZEND_OP1_LITERAL(opline)), - Z_STRLEN(ZEND_OP1_LITERAL(opline))); + Z_STR(ZEND_OP1_LITERAL(opline))); MAKE_NOP(opline); } } diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index ce928f8db1..16a1a09c1f 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -41,65 +41,56 @@ static void zend_optimizer_collect_constant(HashTable **constants, zval *name, z if (!*constants) { *constants = emalloc(sizeof(HashTable)); - zend_hash_init(*constants, 16, NULL, (void (*)(void *))zend_optimizer_zval_dtor_wrapper, 0); + zend_hash_init(*constants, 16, NULL, zend_optimizer_zval_dtor_wrapper, 0); } - val = *value; - zval_copy_ctor(&val); - zend_hash_add(*constants, Z_STRVAL_P(name), Z_STRLEN_P(name)+1, (void**)&val, sizeof(zval), NULL); + ZVAL_DUP(&val, value); + zend_hash_add(*constants, Z_STR_P(name), &val); } static int zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value) { zval *val; - if (zend_hash_find(constants, Z_STRVAL_P(name), Z_STRLEN_P(name)+1, (void**)&val) == SUCCESS) { - *value = *val; - zval_copy_ctor(value); + if ((val = zend_hash_find(constants, Z_STR_P(name))) != NULL) { + ZVAL_DUP(value, val); return 1; } return 0; } #if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO -static int zend_optimizer_lookup_cv(zend_op_array *op_array, char* name, int name_len) +static int zend_optimizer_lookup_cv(zend_op_array *op_array, zend_string* name) { int i = 0; - ulong hash_value = zend_inline_hash_func(name, name_len+1); + ulong hash_value = STR_HASH_VAL(name); while (i < op_array->last_var) { - if (op_array->vars[i].name == name || - (op_array->vars[i].hash_value == hash_value && - op_array->vars[i].name_len == name_len && - memcmp(op_array->vars[i].name, name, name_len) == 0)) { + if (op_array->vars[i] == name || + (op_array->vars[i]->h == hash_value && + op_array->vars[i]->len == name->len && + memcmp(op_array->vars[i], name->val, name->len) == 0)) { return i; } i++; } i = op_array->last_var; op_array->last_var++; - op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_compiled_variable)); - if (IS_INTERNED(name)) { - op_array->vars[i].name = name; - } else { - op_array->vars[i].name = estrndup(name, name_len); - } - op_array->vars[i].name_len = name_len; - op_array->vars[i].hash_value = hash_value; + op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_string*)); + op_array->vars[i] = STR_DUP(name, 0); return i; } #endif #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO -int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) +int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC) { int i = op_array->last_literal; op_array->last_literal++; op_array->literals = (zend_literal*)erealloc(op_array->literals, op_array->last_literal * sizeof(zend_literal)); - op_array->literals[i].constant = *zv; - op_array->literals[i].hash_value = 0; + ZVAL_COPY_VALUE(&op_array->literals[i].constant, zv); op_array->literals[i].cache_slot = -1; - Z_SET_REFCOUNT(op_array->literals[i].constant, 2); - Z_SET_ISREF(op_array->literals[i].constant); +//??? Z_SET_REFCOUNT(op_array->literals[i].constant, 2); +//??? Z_SET_ISREF(op_array->literals[i].constant); return i; } @@ -155,21 +146,25 @@ static void update_op1_const(zend_op_array *op_array, case ZEND_CATCH: case ZEND_FETCH_CONSTANT: opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); - Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); + STR_HASH_VAL(Z_STR(ZEND_OP1_LITERAL(opline))); +//??? Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++; zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val TSRMLS_CC); - op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1); + STR_HASH_VAL(Z_STR(op_array->literals[opline->op1.constant+1].constant)); +//??? op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1); break; case ZEND_DO_FCALL: zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); - Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); + STR_HASH_VAL(Z_STR(ZEND_OP1_LITERAL(opline))); +//??? Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++; break; default: opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); - Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); + STR_HASH_VAL(Z_STR(ZEND_OP1_LITERAL(opline))); +//??? Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); break; } } else { @@ -189,7 +184,8 @@ static void update_op2_const(zend_op_array *op_array, #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO opline->op2.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); if (Z_TYPE_P(val) == IS_STRING) { - Z_HASH_P(&ZEND_OP2_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1); + STR_HASH_VAL(Z_STR(ZEND_OP2_LITERAL(opline))); +//??? Z_HASH_P(&ZEND_OP2_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1); switch (opline->opcode) { case ZEND_FETCH_R: case ZEND_FETCH_W: @@ -207,13 +203,15 @@ static void update_op2_const(zend_op_array *op_array, op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot++; zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val TSRMLS_CC); - op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1); + STR_HASH_VAL(Z_STR(op_array->literals[opline->op2.constant+1].constant)); +//??? op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1); break; case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val TSRMLS_CC); - op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1); + STR_HASH_VAL(Z_STR(op_array->literals[opline->op2.constant+1].constant)); +//??? op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1); /* break missing intentionally */ /*case ZEND_FETCH_CONSTANT:*/ case ZEND_ASSIGN_OBJ: @@ -554,24 +552,24 @@ int zend_accel_script_optimize(zend_persistent_script *script TSRMLS_DC) for (idx = 0; idx < script->function_table.nNumUsed; idx++) { p = script->function_table.arData + idx; - if (!p->xData) continue; - op_array = (zend_op_array*)p->xData; + if (Z_TYPE(p->val) == IS_UNDEF) continue; + op_array = (zend_op_array*)Z_PTR(p->val); zend_accel_optimize(op_array, script, &constants TSRMLS_CC); } for (idx = 0; idx < script->class_table.nNumUsed; idx++) { p = script->class_table.arData + idx; - if (!p->xData) continue; - ce = (zend_class_entry*)p->xData; + if (Z_TYPE(p->val) == IS_UNDEF) continue; + ce = (zend_class_entry*)Z_PTR(p->val); for (j = 0; j < ce->function_table.nNumUsed; j++) { q = ce->function_table.arData + j; - if (!q->xData) continue; - op_array = (zend_op_array*)q->xData; + if (Z_TYPE(q->val) == IS_UNDEF) continue; + op_array = (zend_op_array*)Z_PTR(q->val); if (op_array->scope == ce) { zend_accel_optimize(op_array, script, &constants TSRMLS_CC); } else if (op_array->type == ZEND_USER_FUNCTION) { zend_op_array *orig_op_array; - if (zend_hash_find(&op_array->scope->function_table, q->arKey, q->nKeyLength, (void**)&orig_op_array) == SUCCESS) { + if ((orig_op_array = zend_hash_find_ptr(&op_array->scope->function_table, q->key)) != NULL) { HashTable *ht = op_array->static_variables; *op_array = *orig_op_array; op_array->static_variables = ht; diff --git a/ext/opcache/Optimizer/zend_optimizer_internal.h b/ext/opcache/Optimizer/zend_optimizer_internal.h index d4baf531e1..c0e298b94f 100644 --- a/ext/opcache/Optimizer/zend_optimizer_internal.h +++ b/ext/opcache/Optimizer/zend_optimizer_internal.h @@ -24,7 +24,10 @@ #include "ZendAccelerator.h" -#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO +#if 1 //???ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO +# define VAR_NUM(v) EX_VAR_TO_NUM(v) +# define NUM_VAR(v) ((zend_uint)(zend_uintptr_t)EX_VAR_NUM_2(0, v)) +#elif ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO # define VAR_NUM(v) ((zend_uint)(EX_TMP_VAR_NUM(0, 0) - EX_TMP_VAR(0, v))) # define NUM_VAR(v) ((zend_uint)(zend_uintptr_t)EX_TMP_VAR_NUM(0, v)) #elif ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index f28972461f..8853cc6879 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -251,9 +251,7 @@ static ZEND_INI_MH(accel_include_path_on_modify) #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO /* Interned strings support */ -static char *orig_interned_strings_start; -static char *orig_interned_strings_end; -static const char *(*orig_new_interned_string)(const char *str, int len, int free_src TSRMLS_DC); +static zend_string *(*orig_new_interned_string)(zend_string *str TSRMLS_DC); static void (*orig_interned_strings_snapshot)(TSRMLS_D); static void (*orig_interned_strings_restore)(TSRMLS_D); @@ -261,7 +259,7 @@ static void (*orig_interned_strings_restore)(TSRMLS_D); * it creates interned strings in shared memory when saves a script. * Such interned strings are shared across all PHP processes */ -static const char *accel_new_interned_string_for_php(const char *str, int len, int free_src TSRMLS_DC) +static zend_string *accel_new_interned_string_for_php(zend_string *str TSRMLS_DC) { return str; } @@ -285,19 +283,19 @@ static void accel_interned_strings_restore_state(TSRMLS_D) while (idx > 0) { idx--; p = ZCSG(interned_strings).arData + idx; - if ((char*)p->xData < ZCSG(interned_strings_top)) break; + if ((char*)p->key < ZCSG(interned_strings_top)) break; ZCSG(interned_strings).nNumUsed--; ZCSG(interned_strings).nNumOfElements--; nIndex = p->h & ZCSG(interned_strings).nTableMask; - if (ZCSG(interned_strings).arHash[nIndex].idx == idx) { - ZCSG(interned_strings).arHash[nIndex].idx = p->next; + if (ZCSG(interned_strings).arHash[nIndex] == idx) { + ZCSG(interned_strings).arHash[nIndex] = p->val.u.next; } else { - uint prev = ZCSG(interned_strings).arHash[nIndex].idx; - while (ZCSG(interned_strings).arData[prev].next != idx) { - prev = ZCSG(interned_strings).arData[prev].next; + uint prev = ZCSG(interned_strings).arHash[nIndex]; + while (ZCSG(interned_strings).arData[prev].val.u.next != idx) { + prev = ZCSG(interned_strings).arData[prev].val.u.next; } - ZCSG(interned_strings).arData[prev].next = p->next; + ZCSG(interned_strings).arData[prev].val.u.next = p->val.u.next; } } } @@ -308,7 +306,7 @@ static void accel_interned_strings_save_state(TSRMLS_D) } #endif -const char *accel_new_interned_string(const char *arKey, int nKeyLength, int free_src TSRMLS_DC) +zend_string *accel_new_interned_string(zend_string *str TSRMLS_DC) { /* for now interned strings are supported only for non-ZTS build */ #ifndef ZTS @@ -316,59 +314,60 @@ const char *accel_new_interned_string(const char *arKey, int nKeyLength, int fre uint nIndex; uint idx; Bucket *p; - zend_string_info *info; - if (arKey >= ZCSG(interned_strings_start) && arKey < ZCSG(interned_strings_end)) { + if (IS_ACCEL_INTERNED(str)) { /* this is already an interned string */ - return arKey; + return str; } - h = zend_inline_hash_func(arKey, nKeyLength); + h = STR_HASH_VAL(str); nIndex = h & ZCSG(interned_strings).nTableMask; /* check for existing interned string */ - idx = ZCSG(interned_strings).arHash[nIndex].idx; + idx = ZCSG(interned_strings).arHash[nIndex]; while (idx != INVALID_IDX) { p = ZCSG(interned_strings).arData + idx; - if ((p->h == h) && (p->nKeyLength == (uint)nKeyLength)) { - if (!memcmp(p->arKey, arKey, nKeyLength)) { - if (free_src) { - efree((char*)arKey); - } - return p->arKey; + if ((p->h == h) && (p->key->len == str->len)) { + if (!memcmp(p->key->val, str->val, str->len)) { +//??? if (free_src) { + STR_RELEASE(str); +//??? } + return p->key; } } - idx = p->next; + idx = p->val.u.next; } - if (ZCSG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >= + if (ZCSG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_string) + str->len) >= ZCSG(interned_strings_end)) { /* no memory, return the same non-interned string */ - return arKey; + return str; } /* create new interning string in shared interned strings buffer */ - info = (zend_string_info *) ZCSG(interned_strings_top); - ZCSG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(zend_string_info) + nKeyLength); - memcpy((char*)(info + 1), arKey, nKeyLength); idx = ZCSG(interned_strings).nNumUsed++; ZCSG(interned_strings).nNumOfElements++; p = ZCSG(interned_strings).arData + idx; - p->xData = info + 1; - p->h = h; - p->nKeyLength = nKeyLength; - p->next = ZCSG(interned_strings).arHash[nIndex].idx; - ZCSG(interned_strings).arHash[nIndex].idx = idx; - p->arKey = (const char*)(info + 1); - - if (free_src) { - efree((char*)arKey); - } - - return p->arKey; + p->key = (zend_string*) ZCSG(interned_strings_top); + ZCSG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(zend_string) + str->len); + p->key->gc.refcount = 1; + p->key->gc.u.v.type = IS_STRING; + p->key->gc.u.v.flags |= IS_STR_INTERNED; + p->key->h = str->h; + p->key->len = str->len; + memcpy(p->key->val, str->val, str->len); + ZVAL_STR(&p->val, p->key); + p->val.u.next = ZCSG(interned_strings).arHash[nIndex]; + ZCSG(interned_strings).arHash[nIndex] = idx; + +//??? if (free_src) { + STR_RELEASE(str); +//??? } + + return p->key; #else - return arKey; + return str; #endif } @@ -381,62 +380,62 @@ static void accel_use_shm_interned_strings(TSRMLS_D) #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO /* empty string */ - CG(interned_empty_string) = accel_new_interned_string("", sizeof(""), 0 TSRMLS_CC); + CG(empty_string) = accel_new_interned_string(CG(empty_string) TSRMLS_CC); #endif /* function table hash keys */ for (idx = 0; idx < CG(function_table)->nNumUsed; idx++) { p = CG(function_table)->arData + idx; - if (!p->xData) continue; - if (p->nKeyLength) { - p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC); + if (Z_TYPE(p->val) == IS_UNDEF) continue; + if (p->key) { + p->key = accel_new_interned_string(p->key TSRMLS_CC); } } /* class table hash keys, class names, properties, methods, constants, etc */ for (idx = 0; idx < CG(class_table)->nNumUsed; idx++) { p = CG(class_table)->arData + idx; - if (!p->xData) continue; - zend_class_entry *ce = (zend_class_entry*)(p->xData); + if (Z_TYPE(p->val) == IS_UNDEF) continue; + zend_class_entry *ce = (zend_class_entry*)Z_PTR(p->val); - if (p->nKeyLength) { - p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC); + if (p->key) { + p->key = accel_new_interned_string(p->key TSRMLS_CC); } if (ce->name) { - ce->name = accel_new_interned_string(ce->name, ce->name_length + 1, 0 TSRMLS_CC); + ce->name = accel_new_interned_string(ce->name TSRMLS_CC); } for (j = 0; j < ce->properties_info.nNumUsed; j++) { zend_property_info *info; q = ce->properties_info.arData + j; - if (!q->xData) continue; + if (Z_TYPE(q->val) == IS_UNDEF) continue; - info = (zend_property_info*)(q->xData); + info = (zend_property_info*)Z_PTR(q->val); - if (q->nKeyLength) { - q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC); + if (q->key) { + q->key = accel_new_interned_string(q->key TSRMLS_CC); } if (info->name) { - info->name = accel_new_interned_string(info->name, info->name_length + 1, 0 TSRMLS_CC); + info->name = accel_new_interned_string(info->name TSRMLS_CC); } } for (j = 0; j < ce->function_table.nNumUsed; j++) { q = ce->function_table.arData + j; - if (!q->xData) continue; - if (q->nKeyLength) { - q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC); + if (Z_TYPE(q->val) == IS_UNDEF) continue; + if (q->key) { + q->key = accel_new_interned_string(q->key TSRMLS_CC); } } for (j = 0; j < ce->constants_table.nNumUsed; j++) { q = ce->constants_table.arData + j; - if (!q->xData) continue; - if (q->nKeyLength) { - q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC); + if (!Z_TYPE(q->val) == IS_UNDEF) continue; + if (q->key) { + q->key = accel_new_interned_string(q->key TSRMLS_CC); } } } @@ -444,9 +443,9 @@ static void accel_use_shm_interned_strings(TSRMLS_D) /* constant hash keys */ for (idx = 0; idx < EG(zend_constants)->nNumUsed; idx++) { p = EG(zend_constants)->arData + idx; - if (!p->xData) continue; - if (p->nKeyLength) { - p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC); + if (!Z_TYPE(p->val) == IS_UNDEF) continue; + if (p->key) { + p->key = accel_new_interned_string(p->key TSRMLS_CC); } } @@ -455,13 +454,13 @@ static void accel_use_shm_interned_strings(TSRMLS_D) zend_auto_global *auto_global; p = CG(auto_globals)->arData + idx; - if (!p->xData) continue; + if (Z_TYPE(p->val) == IS_UNDEF) continue; - auto_global = (zend_auto_global*)p->xData; + auto_global = (zend_auto_global*)Z_PTR(p->val);; - auto_global->name = accel_new_interned_string(auto_global->name, auto_global->name_len + 1, 0 TSRMLS_CC); - if (p->nKeyLength) { - p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC); + auto_global->name = accel_new_interned_string(auto_global->name TSRMLS_CC); + if (p->key) { + p->key = accel_new_interned_string(p->key TSRMLS_CC); } } } @@ -831,7 +830,7 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri * See bug #15140 */ if (file_handle->opened_path) { - if (strcmp(persistent_script->full_path, file_handle->opened_path) != 0) { + if (strcmp(persistent_script->full_path->val, file_handle->opened_path) != 0) { return FAILURE; } } else { @@ -840,7 +839,7 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri #else full_path_ptr = accelerator_orig_zend_resolve_path(file_handle->filename, strlen(file_handle->filename) TSRMLS_CC); #endif - if (full_path_ptr && strcmp(persistent_script->full_path, full_path_ptr) != 0) { + if (full_path_ptr && strcmp(persistent_script->full_path->val, full_path_ptr) != 0) { efree(full_path_ptr); return FAILURE; } @@ -868,8 +867,8 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri } ps_handle.type = ZEND_HANDLE_FILENAME; - ps_handle.filename = persistent_script->full_path; - ps_handle.opened_path = persistent_script->full_path; + ps_handle.filename = persistent_script->full_path->val; + ps_handle.opened_path = persistent_script->full_path->val; if (zend_get_file_handle_timestamp(&ps_handle, NULL TSRMLS_CC) == persistent_script->timestamp) { return SUCCESS; @@ -1155,7 +1154,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr /* Check if we still need to put the file into the cache (may be it was * already stored by another process. This final check is done under * exclusive lock) */ - bucket = zend_accel_hash_find_entry(&ZCSG(hash), new_persistent_script->full_path, new_persistent_script->full_path_len + 1); + bucket = zend_accel_hash_find_entry(&ZCSG(hash), new_persistent_script->full_path->val, new_persistent_script->full_path->len + 1); if (bucket) { zend_persistent_script *existing_persistent_script = (zend_persistent_script *)bucket->data; @@ -1193,7 +1192,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr zend_accel_error( ((char*)new_persistent_script->mem + new_persistent_script->size < (char*)ZCG(mem)) ? ACCEL_LOG_ERROR : ACCEL_LOG_WARNING, "Internal error: wrong size calculation: %s start=0x%08x, end=0x%08x, real=0x%08x\n", - new_persistent_script->full_path, + new_persistent_script->full_path->val, new_persistent_script->mem, (char *)new_persistent_script->mem + new_persistent_script->size, ZCG(mem)); @@ -1202,14 +1201,14 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr new_persistent_script->dynamic_members.checksum = zend_accel_script_checksum(new_persistent_script); /* store script structure in the hash table */ - bucket = zend_accel_hash_update(&ZCSG(hash), new_persistent_script->full_path, new_persistent_script->full_path_len + 1, 0, new_persistent_script); + bucket = zend_accel_hash_update(&ZCSG(hash), new_persistent_script->full_path->val, new_persistent_script->full_path->len + 1, 0, new_persistent_script); if (bucket) { zend_accel_error(ACCEL_LOG_INFO, "Cached script '%s'", new_persistent_script->full_path); if (!ZCG(accel_directives).revalidate_path && /* key may contain non-persistent PHAR aliases (see issues #115 and #149) */ memcmp(key, "phar://", sizeof("phar://") - 1) != 0 && - (new_persistent_script->full_path_len != key_length || - memcmp(new_persistent_script->full_path, key, key_length) != 0)) { + (new_persistent_script->full_path->len != key_length || + memcmp(new_persistent_script->full_path->val, key, key_length) != 0)) { /* link key to the same persistent script in hash table */ if (zend_accel_hash_update(&ZCSG(hash), key, key_length + 1, 1, bucket)) { zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", key); @@ -1234,11 +1233,11 @@ static const struct jit_auto_global_info const char *name; size_t len; } jit_auto_globals_info[] = { - { "_SERVER", sizeof("_SERVER")}, - { "_ENV", sizeof("_ENV")}, - { "_REQUEST", sizeof("_REQUEST")}, + { "_SERVER", sizeof("_SERVER")-1}, + { "_ENV", sizeof("_ENV")-1}, + { "_REQUEST", sizeof("_REQUEST")-1}, #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - { "GLOBALS", sizeof("GLOBALS")}, + { "GLOBALS", sizeof("GLOBALS")-1}, #endif }; @@ -1249,7 +1248,7 @@ static int zend_accel_get_auto_globals(TSRMLS_D) int mask = 0; for (i = 0; i < ag_size ; i++) { - if (zend_hash_exists(&EG(symbol_table), jit_auto_globals_info[i].name, jit_auto_globals_info[i].len)) { + if (zend_hash_str_exists(&EG(symbol_table).ht, jit_auto_globals_info[i].name, jit_auto_globals_info[i].len)) { mask |= n; } n += n; @@ -1260,7 +1259,7 @@ static int zend_accel_get_auto_globals(TSRMLS_D) #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO static int zend_accel_get_auto_globals_no_jit(TSRMLS_D) { - if (zend_hash_exists(&EG(symbol_table), jit_auto_globals_info[3].name, jit_auto_globals_info[3].len)) { + if (zend_hash_str_exists(&EG(symbol_table).ht, jit_auto_globals_info[3].name, jit_auto_globals_info[3].len)) { return 8; } return 0; @@ -1271,10 +1270,14 @@ static void zend_accel_set_auto_globals(int mask TSRMLS_DC) { int i, ag_size = (sizeof(jit_auto_globals_info) / sizeof(jit_auto_globals_info[0])); int n = 1; + zend_string *str; for (i = 0; i < ag_size ; i++) { if (mask & n) { - zend_is_auto_global(jit_auto_globals_info[i].name, jit_auto_globals_info[i].len - 1 TSRMLS_CC); +//??? + str = STR_INIT(jit_auto_globals_info[i].name, jit_auto_globals_info[i].len, 0); + zend_is_auto_global(str TSRMLS_CC); + STR_RELEASE(str); } n += n; } @@ -1285,7 +1288,7 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han zend_persistent_script *new_persistent_script; zend_op_array *orig_active_op_array; HashTable *orig_function_table, *orig_class_table; - zval *orig_user_error_handler; + zval orig_user_error_handler; zend_op_array *op_array; int do_bailout = 0; accel_time_t timestamp = 0; @@ -1382,12 +1385,12 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han orig_active_op_array = CG(active_op_array); orig_function_table = CG(function_table); orig_class_table = CG(class_table); - orig_user_error_handler = EG(user_error_handler); + ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler)); /* Override them with ours */ CG(function_table) = &ZCG(function_table); EG(class_table) = CG(class_table) = &new_persistent_script->class_table; - EG(user_error_handler) = NULL; + ZVAL_UNDEF(&EG(user_error_handler)); zend_try { #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO @@ -1457,13 +1460,11 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han } if (file_handle->opened_path) { - new_persistent_script->full_path_len = strlen(file_handle->opened_path); - new_persistent_script->full_path = estrndup(file_handle->opened_path, new_persistent_script->full_path_len); + new_persistent_script->full_path = STR_INIT(file_handle->opened_path, strlen(file_handle->opened_path), 0); } else { - new_persistent_script->full_path_len = strlen(file_handle->filename); - new_persistent_script->full_path = estrndup(file_handle->filename, new_persistent_script->full_path_len); + new_persistent_script->full_path = STR_INIT(file_handle->filename, strlen(file_handle->filename), 0); } - new_persistent_script->hash_value = zend_hash_func(new_persistent_script->full_path, new_persistent_script->full_path_len + 1); + STR_HASH_VAL(new_persistent_script->full_path); /* Now persistent_script structure is ready in process memory */ return cache_script_in_shared_memory(new_persistent_script, key, key_length, from_shared_memory TSRMLS_CC); @@ -1673,16 +1674,15 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type T ((*EG(opline_ptr))->op2.u.constant.value.lval != ZEND_INCLUDE_ONCE && (*EG(opline_ptr))->op2.u.constant.value.lval != ZEND_REQUIRE_ONCE)) { #endif - void *dummy = (void *) 1; - if (zend_hash_quick_add(&EG(included_files), persistent_script->full_path, persistent_script->full_path_len + 1, persistent_script->hash_value, &dummy, sizeof(void *), NULL) == SUCCESS) { + if (zend_hash_add_empty_element(&EG(included_files), persistent_script->full_path) == SUCCESS) { /* ext/phar has to load phar's metadata into memory */ - if (strstr(persistent_script->full_path, ".phar") && !strstr(persistent_script->full_path, "://")) { + if (strstr(persistent_script->full_path->val, ".phar") && !strstr(persistent_script->full_path->val, "://")) { php_stream_statbuf ssb; - char *fname = emalloc(sizeof("phar://") + persistent_script->full_path_len); + char *fname = emalloc(sizeof("phar://") + persistent_script->full_path->len); memcpy(fname, "phar://", sizeof("phar://") - 1); - memcpy(fname + sizeof("phar://") - 1, persistent_script->full_path, persistent_script->full_path_len + 1); + memcpy(fname + sizeof("phar://") - 1, persistent_script->full_path->val, persistent_script->full_path->len + 1); php_stream_stat_path(fname, &ssb); efree(fname); } @@ -1949,7 +1949,7 @@ static int persistent_stream_open_function(const char *filename, zend_file_handl (EG(opline_ptr) && (ZCG(cache_opline) == *EG(opline_ptr)))) { persistent_script = ZCG(cache_persistent_script); - handle->opened_path = estrndup(persistent_script->full_path, persistent_script->full_path_len); + handle->opened_path = estrndup(persistent_script->full_path->val, persistent_script->full_path->len); handle->type = ZEND_HANDLE_FILENAME; return SUCCESS; #if 0 @@ -2015,11 +2015,11 @@ static char* persistent_zend_resolve_path(const char *filename, int filename_len (bucket = zend_accel_hash_find_entry(&ZCSG(hash), (char*)filename, filename_len + 1)) != NULL) { persistent_script = (zend_persistent_script *)bucket->data; if (persistent_script && !persistent_script->corrupted) { - memcpy(ZCG(key), persistent_script->full_path, persistent_script->full_path_len + 1); - ZCG(key_len) = persistent_script->full_path_len; + memcpy(ZCG(key), persistent_script->full_path->val, persistent_script->full_path->len + 1); + ZCG(key_len) = persistent_script->full_path->len; ZCG(cache_opline) = EG(opline_ptr) ? *EG(opline_ptr) : NULL; ZCG(cache_persistent_script) = persistent_script; - return estrndup(persistent_script->full_path, persistent_script->full_path_len); + return estrndup(persistent_script->full_path->val, persistent_script->full_path->len); } } @@ -2036,7 +2036,7 @@ static char* persistent_zend_resolve_path(const char *filename, int filename_len /* we have persistent script */ ZCG(cache_opline) = EG(opline_ptr) ? *EG(opline_ptr) : NULL; ZCG(cache_persistent_script) = persistent_script; - return estrndup(persistent_script->full_path, persistent_script->full_path_len); + return estrndup(persistent_script->full_path->val, persistent_script->full_path->len); } /* find the full real path */ @@ -2468,20 +2468,20 @@ static int zend_accel_init_shm(TSRMLS_D) if (ZCG(accel_directives).interned_strings_buffer) { ZCSG(interned_strings).nTableMask = ZCSG(interned_strings).nTableSize - 1; ZCSG(interned_strings).arData = zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket)); - ZCSG(interned_strings).arHash = (HashBucket*)zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(HashBucket)); + ZCSG(interned_strings).arHash = (zend_uint*)zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(zend_uint)); ZCSG(interned_strings_start) = zend_shared_alloc((ZCG(accel_directives).interned_strings_buffer * 1024 * 1024)); if (!ZCSG(interned_strings).arData || !ZCSG(interned_strings_start)) { zend_accel_error(ACCEL_LOG_FATAL, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings"); return FAILURE; } - memset(ZCSG(interned_strings).arHash, INVALID_IDX, ZCSG(interned_strings).nTableSize * sizeof(HashBucket)); + memset(ZCSG(interned_strings).arHash, INVALID_IDX, ZCSG(interned_strings).nTableSize * sizeof(zend_uint)); ZCSG(interned_strings_end) = ZCSG(interned_strings_start) + (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024); ZCSG(interned_strings_top) = ZCSG(interned_strings_start); - orig_interned_strings_start = CG(interned_strings_start); - orig_interned_strings_end = CG(interned_strings_end); - CG(interned_strings_start) = ZCSG(interned_strings_start); - CG(interned_strings_end) = ZCSG(interned_strings_end); +// orig_interned_strings_start = CG(interned_strings_start); +// orig_interned_strings_end = CG(interned_strings_end); +// CG(interned_strings_start) = ZCSG(interned_strings_start); +// CG(interned_strings_end) = ZCSG(interned_strings_end); } # endif @@ -2589,14 +2589,10 @@ static int accel_startup(zend_extension *extension) accel_shared_globals = (zend_accel_shared_globals *) ZSMMG(app_shared_globals); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO zend_shared_alloc_lock(TSRMLS_C); - orig_interned_strings_start = CG(interned_strings_start); - orig_interned_strings_end = CG(interned_strings_end); orig_new_interned_string = zend_new_interned_string; orig_interned_strings_snapshot = zend_interned_strings_snapshot; orig_interned_strings_restore = zend_interned_strings_restore; - CG(interned_strings_start) = ZCSG(interned_strings_start); - CG(interned_strings_end) = ZCSG(interned_strings_end); zend_new_interned_string = accel_new_interned_string_for_php; zend_interned_strings_snapshot = accel_interned_strings_snapshot_for_php; zend_interned_strings_restore = accel_interned_strings_restore_for_php; @@ -2639,7 +2635,7 @@ static int accel_startup(zend_extension *extension) } /* Override chdir() function */ - if (zend_hash_find(CG(function_table), "chdir", sizeof("chdir"), (void**)&func) == SUCCESS && + if ((func = zend_hash_str_find_ptr(CG(function_table), "chdir", sizeof("chdir")-1)) != NULL && func->type == ZEND_INTERNAL_FUNCTION) { orig_chdir = func->internal_function.handler; func->internal_function.handler = ZEND_FN(accel_chdir); @@ -2647,7 +2643,7 @@ static int accel_startup(zend_extension *extension) ZCG(cwd) = NULL; /* Override "include_path" modifier callback */ - if (zend_hash_find(EG(ini_directives), "include_path", sizeof("include_path"), (void **) &ini_entry) == SUCCESS) { + if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), "include_path", sizeof("include_path")-1)) != NULL) { ZCG(include_path) = INI_STR("include_path"); ZCG(include_path_key) = NULL; if (ZCG(include_path) && *ZCG(include_path)) { @@ -2732,8 +2728,6 @@ void accel_shutdown(TSRMLS_D) zend_hash_clean(CG(class_table)); zend_hash_clean(EG(zend_constants)); # endif - CG(interned_strings_start) = orig_interned_strings_start; - CG(interned_strings_end) = orig_interned_strings_end; } zend_new_interned_string = orig_new_interned_string; zend_interned_strings_snapshot = orig_interned_strings_snapshot; @@ -2744,7 +2738,7 @@ void accel_shutdown(TSRMLS_D) zend_shared_alloc_shutdown(); zend_compile_file = accelerator_orig_compile_file; - if (zend_hash_find(EG(ini_directives), "include_path", sizeof("include_path"), (void **) &ini_entry) == SUCCESS) { + if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), "include_path", sizeof("include_path")-1)) != NULL) { ini_entry->on_modify = orig_include_path_on_modify; } } diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 3b7c4a9cda..192b2ec6d0 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -182,9 +182,7 @@ typedef enum _zend_accel_restart_reason { } zend_accel_restart_reason; typedef struct _zend_persistent_script { - ulong hash_value; - char *full_path; /* full real path with resolved symlinks */ - unsigned int full_path_len; + zend_string *full_path; /* full real path with resolved symlinks */ zend_op_array main_op_array; HashTable function_table; HashTable class_table; @@ -341,22 +339,13 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type T #define ZEND_DECLARE_INHERITED_CLASS_DELAYED_FLAG 0x80 +#define IS_ACCEL_INTERNED(str) \ + ((char*)(str) >= ZCSG(interned_strings_start) && (char*)(str) < ZCSG(interned_strings_end)) + #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO -const char *accel_new_interned_string(const char *arKey, int nKeyLength, int free_src TSRMLS_DC); - -# define interned_free(s) do { \ - if (!IS_INTERNED(s)) { \ - free(s); \ - } \ - } while (0) -# define interned_efree(s) do { \ - if (!IS_INTERNED(s)) { \ - efree(s); \ - } \ - } while (0) -# define interned_estrndup(s, n) \ - (IS_INTERNED(s) ? (s) : estrndup(s, n)) +zend_string *accel_new_interned_string(zend_string *str TSRMLS_DC); + # define ZEND_RESULT_TYPE(opline) (opline)->result_type # define ZEND_RESULT(opline) (opline)->result # define ZEND_OP1_TYPE(opline) (opline)->op1_type diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c index 0ca37dfa42..af56fbf9e9 100644 --- a/ext/opcache/zend_accelerator_blacklist.c +++ b/ext/opcache/zend_accelerator_blacklist.c @@ -371,7 +371,7 @@ zend_bool zend_accel_blacklist_is_blacklisted(zend_blacklist *blacklist, char *v return ret; } -void zend_accel_blacklist_apply(zend_blacklist *blacklist, apply_func_arg_t func, void *argument TSRMLS_DC) +void zend_accel_blacklist_apply(zend_blacklist *blacklist, blacklist_apply_func_arg_t func, void *argument TSRMLS_DC) { int i; diff --git a/ext/opcache/zend_accelerator_blacklist.h b/ext/opcache/zend_accelerator_blacklist.h index 869068410f..1990e414b9 100644 --- a/ext/opcache/zend_accelerator_blacklist.h +++ b/ext/opcache/zend_accelerator_blacklist.h @@ -37,6 +37,8 @@ typedef struct _zend_blacklist { zend_regexp_list *regexp_list; } zend_blacklist; +typedef int (*blacklist_apply_func_arg_t)(zend_blacklist_entry *, zval * TSRMLS_DC); + extern zend_blacklist accel_blacklist; void zend_accel_blacklist_init(zend_blacklist *blacklist); @@ -44,6 +46,6 @@ void zend_accel_blacklist_shutdown(zend_blacklist *blacklist); void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename); zend_bool zend_accel_blacklist_is_blacklisted(zend_blacklist *blacklist, char *verify_path); -void zend_accel_blacklist_apply(zend_blacklist *blacklist, apply_func_arg_t func, void *argument TSRMLS_DC); +void zend_accel_blacklist_apply(zend_blacklist *blacklist, blacklist_apply_func_arg_t func, void *argument TSRMLS_DC); #endif /* ZEND_ACCELERATOR_BLACKLIST_H */ diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index b98623e1f2..a0ccfb3a3a 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -120,10 +120,9 @@ static ZEND_INI_MH(OnUpdateMemoryConsumption) zend_accel_error(ACCEL_LOG_WARNING, "opcache.memory_consumption is set below the required 8MB.\n"); zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use the minimal 8MB configuration.\n"); - if (zend_hash_find(EG(ini_directives), + if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), "opcache.memory_consumption", - sizeof("opcache.memory_consumption"), - (void *) &ini_entry) == FAILURE) { + sizeof("opcache.memory_consumption")-1)) == NULL) { return FAILURE; } @@ -167,10 +166,9 @@ static ZEND_INI_MH(OnUpdateMaxAcceleratedFiles) zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_accelerated_files is set above the limit (%d).\n", MAX_ACCEL_FILES); zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use the maximal configuration.\n"); } - if (zend_hash_find(EG(ini_directives), + if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), "opcache.max_accelerated_files", - sizeof("opcache.max_accelerated_files"), - (void *) &ini_entry) == FAILURE) { + sizeof("opcache.max_accelerated_files")-1)) == NULL) { return FAILURE; } ini_entry->value = strdup(new_new_value); @@ -203,10 +201,9 @@ static ZEND_INI_MH(OnUpdateMaxWastedPercentage) percentage = 5; zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_wasted_percentage must be set between 1 and 50.\n"); zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use 5%.\n"); - if (zend_hash_find(EG(ini_directives), + if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), "opcache.max_wasted_percentage", - sizeof("opcache.max_wasted_percentage"), - (void *) &ini_entry) == FAILURE) { + sizeof("opcache.max_wasted_percentage")-1)) == NULL) { return FAILURE; } ini_entry->value = strdup(new_new_value); @@ -333,15 +330,15 @@ static int filename_is_in_cache(char *filename, int filename_len TSRMLS_DC) static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS) { - zval **zfilename; + zval zfilename; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, &zfilename) == FAILURE || - Z_TYPE_PP(zfilename) != IS_STRING || - Z_STRLEN_PP(zfilename) == 0) { + Z_TYPE(zfilename) != IS_STRING || + Z_STRLEN(zfilename) == 0) { return 0; } - return filename_is_in_cache(Z_STRVAL_PP(zfilename), Z_STRLEN_PP(zfilename) TSRMLS_CC); + return filename_is_in_cache(Z_STRVAL(zfilename), Z_STRLEN(zfilename) TSRMLS_CC); } static void accel_file_exists(INTERNAL_FUNCTION_PARAMETERS) @@ -387,15 +384,15 @@ void zend_accel_override_file_functions(TSRMLS_D) zend_function *old_function; if (ZCG(enabled) && accel_startup_ok && ZCG(accel_directives).file_override_enabled) { /* override file_exists */ - if (zend_hash_find(CG(function_table), "file_exists", sizeof("file_exists"), (void **)&old_function) == SUCCESS) { + if ((old_function = zend_hash_str_find_ptr(CG(function_table), "file_exists", sizeof("file_exists")-1)) != NULL) { orig_file_exists = old_function->internal_function.handler; old_function->internal_function.handler = accel_file_exists; } - if (zend_hash_find(CG(function_table), "is_file", sizeof("is_file"), (void **)&old_function) == SUCCESS) { + if ((old_function = zend_hash_str_find_ptr(CG(function_table), "is_file", sizeof("is_file")-1)) != NULL) { orig_is_file = old_function->internal_function.handler; old_function->internal_function.handler = accel_is_file; } - if (zend_hash_find(CG(function_table), "is_readable", sizeof("is_readable"), (void **)&old_function) == SUCCESS) { + if ((old_function = zend_hash_str_find_ptr(CG(function_table), "is_readable", sizeof("is_readable")-1)) != NULL) { orig_is_readable = old_function->internal_function.handler; old_function->internal_function.handler = accel_is_readable; } @@ -488,10 +485,10 @@ int start_accel_module(void) /* {{{ proto array accelerator_get_scripts() Get the scripts which are accelerated by ZendAccelerator */ -static zval* accelerator_get_scripts(TSRMLS_D) +static int accelerator_get_scripts(zval *return_value TSRMLS_DC) { uint i; - zval *return_value,*persistent_script_report; + zval persistent_script_report; zend_accel_hash_entry *cache_entry; struct tm *ta; struct timeval exec_time; @@ -501,7 +498,6 @@ static zval* accelerator_get_scripts(TSRMLS_D) return 0; } - MAKE_STD_ZVAL(return_value); array_init(return_value); for (i = 0; inext) { @@ -513,29 +509,28 @@ static zval* accelerator_get_scripts(TSRMLS_D) script = (zend_persistent_script *)cache_entry->data; - MAKE_STD_ZVAL(persistent_script_report); - array_init(persistent_script_report); - add_assoc_stringl(persistent_script_report, "full_path", script->full_path, script->full_path_len, 1); - add_assoc_long(persistent_script_report, "hits", script->dynamic_members.hits); - add_assoc_long(persistent_script_report, "memory_consumption", script->dynamic_members.memory_consumption); + array_init(&persistent_script_report); + add_assoc_str(&persistent_script_report, "full_path", STR_DUP(script->full_path, 0)); + add_assoc_long(&persistent_script_report, "hits", script->dynamic_members.hits); + add_assoc_long(&persistent_script_report, "memory_consumption", script->dynamic_members.memory_consumption); ta = localtime(&script->dynamic_members.last_used); str = asctime(ta); len = strlen(str); if (len > 0 && str[len - 1] == '\n') len--; - add_assoc_stringl(persistent_script_report, "last_used", str, len, 1); - add_assoc_long(persistent_script_report, "last_used_timestamp", script->dynamic_members.last_used); + add_assoc_stringl(&persistent_script_report, "last_used", str, len, 1); + add_assoc_long(&persistent_script_report, "last_used_timestamp", script->dynamic_members.last_used); if (ZCG(accel_directives).validate_timestamps) { - add_assoc_long(persistent_script_report, "timestamp", (long)script->timestamp); + add_assoc_long(&persistent_script_report, "timestamp", (long)script->timestamp); } timerclear(&exec_time); timerclear(&fetch_time); - zend_hash_update(return_value->value.ht, cache_entry->key, cache_entry->key_length, &persistent_script_report, sizeof(zval *), NULL); + zend_hash_str_update(Z_ARRVAL_P(return_value), cache_entry->key, cache_entry->key_length-1, &persistent_script_report); } } accelerator_shm_read_unlock(TSRMLS_C); - return return_value; + return 1; } /* {{{ proto array accelerator_get_status([bool fetch_scripts]) @@ -543,12 +538,9 @@ static zval* accelerator_get_scripts(TSRMLS_D) static ZEND_FUNCTION(opcache_get_status) { long reqs; - zval *memory_usage,*statistics,*scripts; + zval memory_usage, statistics, scripts; zend_bool fetch_scripts = 1; - /* keep the compiler happy */ - (void)ht; (void)return_value_ptr; (void)this_ptr; (void)return_value_used; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &fetch_scripts) == FAILURE) { return; } @@ -570,38 +562,35 @@ static ZEND_FUNCTION(opcache_get_status) add_assoc_bool(return_value, "restart_in_progress", ZCSG(restart_in_progress)); /* Memory usage statistics */ - MAKE_STD_ZVAL(memory_usage); - array_init(memory_usage); - add_assoc_long(memory_usage, "used_memory", ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory)); - add_assoc_long(memory_usage, "free_memory", zend_shared_alloc_get_free_memory()); - add_assoc_long(memory_usage, "wasted_memory", ZSMMG(wasted_shared_memory)); - add_assoc_double(memory_usage, "current_wasted_percentage", (((double) ZSMMG(wasted_shared_memory))/ZCG(accel_directives).memory_consumption)*100.0); - add_assoc_zval(return_value, "memory_usage", memory_usage); + array_init(&memory_usage); + add_assoc_long(&memory_usage, "used_memory", ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory)); + add_assoc_long(&memory_usage, "free_memory", zend_shared_alloc_get_free_memory()); + add_assoc_long(&memory_usage, "wasted_memory", ZSMMG(wasted_shared_memory)); + add_assoc_double(&memory_usage, "current_wasted_percentage", (((double) ZSMMG(wasted_shared_memory))/ZCG(accel_directives).memory_consumption)*100.0); + add_assoc_zval(return_value, "memory_usage", &memory_usage); /* Accelerator statistics */ - MAKE_STD_ZVAL(statistics); - array_init(statistics); - add_assoc_long(statistics, "num_cached_scripts", ZCSG(hash).num_direct_entries); - add_assoc_long(statistics, "num_cached_keys", ZCSG(hash).num_entries); - add_assoc_long(statistics, "max_cached_keys", ZCSG(hash).max_num_entries); - add_assoc_long(statistics, "hits", ZCSG(hits)); - add_assoc_long(statistics, "start_time", ZCSG(start_time)); - add_assoc_long(statistics, "last_restart_time", ZCSG(last_restart_time)); - add_assoc_long(statistics, "oom_restarts", ZCSG(oom_restarts)); - add_assoc_long(statistics, "hash_restarts", ZCSG(hash_restarts)); - add_assoc_long(statistics, "manual_restarts", ZCSG(manual_restarts)); - add_assoc_long(statistics, "misses", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses)); - add_assoc_long(statistics, "blacklist_misses", ZCSG(blacklist_misses)); + array_init(&statistics); + add_assoc_long(&statistics, "num_cached_scripts", ZCSG(hash).num_direct_entries); + add_assoc_long(&statistics, "num_cached_keys", ZCSG(hash).num_entries); + add_assoc_long(&statistics, "max_cached_keys", ZCSG(hash).max_num_entries); + add_assoc_long(&statistics, "hits", ZCSG(hits)); + add_assoc_long(&statistics, "start_time", ZCSG(start_time)); + add_assoc_long(&statistics, "last_restart_time", ZCSG(last_restart_time)); + add_assoc_long(&statistics, "oom_restarts", ZCSG(oom_restarts)); + add_assoc_long(&statistics, "hash_restarts", ZCSG(hash_restarts)); + add_assoc_long(&statistics, "manual_restarts", ZCSG(manual_restarts)); + add_assoc_long(&statistics, "misses", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses)); + add_assoc_long(&statistics, "blacklist_misses", ZCSG(blacklist_misses)); reqs = ZCSG(hits)+ZCSG(misses); - add_assoc_double(statistics, "blacklist_miss_ratio", reqs?(((double) ZCSG(blacklist_misses))/reqs)*100.0:0); - add_assoc_double(statistics, "opcache_hit_rate", reqs?(((double) ZCSG(hits))/reqs)*100.0:0); - add_assoc_zval(return_value, "opcache_statistics", statistics); + add_assoc_double(&statistics, "blacklist_miss_ratio", reqs?(((double) ZCSG(blacklist_misses))/reqs)*100.0:0); + add_assoc_double(&statistics, "opcache_hit_rate", reqs?(((double) ZCSG(hits))/reqs)*100.0:0); + add_assoc_zval(return_value, "opcache_statistics", &statistics); if (fetch_scripts) { /* accelerated scripts */ - scripts = accelerator_get_scripts(TSRMLS_C); - if (scripts) { - add_assoc_zval(return_value, "scripts", scripts); + if (accelerator_get_scripts(&scripts TSRMLS_CC)) { + add_assoc_zval(return_value, "scripts", &scripts); } } } @@ -616,10 +605,7 @@ static int add_blacklist_path(zend_blacklist_entry *p, zval *return_value TSRMLS Obtain configuration information */ static ZEND_FUNCTION(opcache_get_configuration) { - zval *directives,*version,*blacklist; - - /* keep the compiler happy */ - (void)ht; (void)return_value_ptr; (void)this_ptr; (void)return_value_used; + zval directives, version, blacklist; #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO if (zend_parse_parameters_none() == FAILURE) { @@ -634,61 +620,55 @@ static ZEND_FUNCTION(opcache_get_configuration) array_init(return_value); /* directives */ - MAKE_STD_ZVAL(directives); - array_init(directives); - add_assoc_bool(directives, "opcache.enable", ZCG(enabled)); - add_assoc_bool(directives, "opcache.enable_cli", ZCG(accel_directives).enable_cli); - add_assoc_bool(directives, "opcache.use_cwd", ZCG(accel_directives).use_cwd); - add_assoc_bool(directives, "opcache.validate_timestamps", ZCG(accel_directives).validate_timestamps); - add_assoc_bool(directives, "opcache.inherited_hack", ZCG(accel_directives).inherited_hack); - add_assoc_bool(directives, "opcache.dups_fix", ZCG(accel_directives).ignore_dups); - add_assoc_bool(directives, "opcache.revalidate_path", ZCG(accel_directives).revalidate_path); - - add_assoc_long(directives, "opcache.log_verbosity_level", ZCG(accel_directives).log_verbosity_level); - add_assoc_long(directives, "opcache.memory_consumption", ZCG(accel_directives).memory_consumption); + array_init(&directives); + add_assoc_bool(&directives, "opcache.enable", ZCG(enabled)); + add_assoc_bool(&directives, "opcache.enable_cli", ZCG(accel_directives).enable_cli); + add_assoc_bool(&directives, "opcache.use_cwd", ZCG(accel_directives).use_cwd); + add_assoc_bool(&directives, "opcache.validate_timestamps", ZCG(accel_directives).validate_timestamps); + add_assoc_bool(&directives, "opcache.inherited_hack", ZCG(accel_directives).inherited_hack); + add_assoc_bool(&directives, "opcache.dups_fix", ZCG(accel_directives).ignore_dups); + add_assoc_bool(&directives, "opcache.revalidate_path", ZCG(accel_directives).revalidate_path); + + add_assoc_long(&directives, "opcache.log_verbosity_level", ZCG(accel_directives).log_verbosity_level); + add_assoc_long(&directives, "opcache.memory_consumption", ZCG(accel_directives).memory_consumption); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - add_assoc_long(directives, "opcache.interned_strings_buffer",ZCG(accel_directives).interned_strings_buffer); + add_assoc_long(&directives, "opcache.interned_strings_buffer",ZCG(accel_directives).interned_strings_buffer); #endif - add_assoc_long(directives, "opcache.max_accelerated_files", ZCG(accel_directives).max_accelerated_files); - add_assoc_double(directives, "opcache.max_wasted_percentage", ZCG(accel_directives).max_wasted_percentage); - add_assoc_long(directives, "opcache.consistency_checks", ZCG(accel_directives).consistency_checks); - add_assoc_long(directives, "opcache.force_restart_timeout", ZCG(accel_directives).force_restart_timeout); - add_assoc_long(directives, "opcache.revalidate_freq", ZCG(accel_directives).revalidate_freq); - add_assoc_string(directives, "opcache.preferred_memory_model", STRING_NOT_NULL(ZCG(accel_directives).memory_model), 1); - add_assoc_string(directives, "opcache.blacklist_filename", STRING_NOT_NULL(ZCG(accel_directives).user_blacklist_filename), 1); - add_assoc_long(directives, "opcache.max_file_size", ZCG(accel_directives).max_file_size); - add_assoc_string(directives, "opcache.error_log", STRING_NOT_NULL(ZCG(accel_directives).error_log), 1); - - add_assoc_bool(directives, "opcache.protect_memory", ZCG(accel_directives).protect_memory); - add_assoc_bool(directives, "opcache.save_comments", ZCG(accel_directives).save_comments); - add_assoc_bool(directives, "opcache.load_comments", ZCG(accel_directives).load_comments); - add_assoc_bool(directives, "opcache.fast_shutdown", ZCG(accel_directives).fast_shutdown); - add_assoc_bool(directives, "opcache.enable_file_override", ZCG(accel_directives).file_override_enabled); - add_assoc_long(directives, "opcache.optimization_level", ZCG(accel_directives).optimization_level); - - add_assoc_zval(return_value, "directives", directives); + add_assoc_long(&directives, "opcache.max_accelerated_files", ZCG(accel_directives).max_accelerated_files); + add_assoc_double(&directives, "opcache.max_wasted_percentage", ZCG(accel_directives).max_wasted_percentage); + add_assoc_long(&directives, "opcache.consistency_checks", ZCG(accel_directives).consistency_checks); + add_assoc_long(&directives, "opcache.force_restart_timeout", ZCG(accel_directives).force_restart_timeout); + add_assoc_long(&directives, "opcache.revalidate_freq", ZCG(accel_directives).revalidate_freq); + add_assoc_string(&directives, "opcache.preferred_memory_model", STRING_NOT_NULL(ZCG(accel_directives).memory_model), 1); + add_assoc_string(&directives, "opcache.blacklist_filename", STRING_NOT_NULL(ZCG(accel_directives).user_blacklist_filename), 1); + add_assoc_long(&directives, "opcache.max_file_size", ZCG(accel_directives).max_file_size); + add_assoc_string(&directives, "opcache.error_log", STRING_NOT_NULL(ZCG(accel_directives).error_log), 1); + + add_assoc_bool(&directives, "opcache.protect_memory", ZCG(accel_directives).protect_memory); + add_assoc_bool(&directives, "opcache.save_comments", ZCG(accel_directives).save_comments); + add_assoc_bool(&directives, "opcache.load_comments", ZCG(accel_directives).load_comments); + add_assoc_bool(&directives, "opcache.fast_shutdown", ZCG(accel_directives).fast_shutdown); + add_assoc_bool(&directives, "opcache.enable_file_override", ZCG(accel_directives).file_override_enabled); + add_assoc_long(&directives, "opcache.optimization_level", ZCG(accel_directives).optimization_level); + + add_assoc_zval(return_value, "directives", &directives); /*version */ - MAKE_STD_ZVAL(version); - array_init(version); - add_assoc_string(version, "version", ACCELERATOR_VERSION, 1); - add_assoc_string(version, "opcache_product_name", ACCELERATOR_PRODUCT_NAME, 1); - add_assoc_zval(return_value, "version", version); + array_init(&version); + add_assoc_string(&version, "version", ACCELERATOR_VERSION, 1); + add_assoc_string(&version, "opcache_product_name", ACCELERATOR_PRODUCT_NAME, 1); + add_assoc_zval(return_value, "version", &version); /* blacklist */ - MAKE_STD_ZVAL(blacklist); - array_init(blacklist); - zend_accel_blacklist_apply(&accel_blacklist, (apply_func_arg_t) add_blacklist_path, blacklist TSRMLS_CC); - add_assoc_zval(return_value, "blacklist", blacklist); + array_init(&blacklist); + zend_accel_blacklist_apply(&accel_blacklist, add_blacklist_path, &blacklist TSRMLS_CC); + add_assoc_zval(return_value, "blacklist", &blacklist); } /* {{{ proto void accelerator_reset() Request that the contents of the opcode cache to be reset */ static ZEND_FUNCTION(opcache_reset) { - /* keep the compiler happy */ - (void)ht; (void)return_value_ptr; (void)this_ptr; (void)return_value_used; - #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO if (zend_parse_parameters_none() == FAILURE) { RETURN_FALSE; diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index d3ab3d44f1..efda22fb29 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -31,22 +31,23 @@ static zend_uint zend_accel_refcount = ZEND_PROTECTED_REFCOUNT; #if SIZEOF_SIZE_T <= SIZEOF_LONG /* If sizeof(void*) == sizeof(ulong) we can use zend_hash index functions */ -# define accel_xlat_set(old, new) zend_hash_index_update(&ZCG(bind_hash), (ulong)(zend_uintptr_t)(old), &(new), sizeof(void*), NULL) -# define accel_xlat_get(old, new) zend_hash_index_find(&ZCG(bind_hash), (ulong)(zend_uintptr_t)(old), (void**)&(new)) +# define accel_xlat_set(old, new) zend_hash_index_update_ptr(&ZCG(bind_hash), (ulong)(zend_uintptr_t)(old), (new)) +# define accel_xlat_get(old) zend_hash_index_find_ptr(&ZCG(bind_hash), (ulong)(zend_uintptr_t)(old)) #else -# define accel_xlat_set(old, new) zend_hash_quick_add(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (ulong)(zend_uintptr_t)(old), (void**)&(new), sizeof(void*), NULL) -# define accel_xlat_get(old, new) zend_hash_quick_find(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (ulong)(zend_uintptr_t)(old), (void**)&(new)) +# define accel_xlat_set(old, new) (zend_hash_str_add_ptr(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (ulong)(zend_uintptr_t)(old), (void**)&(new)) +# define accel_xlat_get(old, new) ((new) = zend_hash_str_find_ptr(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (ulong)(zend_uintptr_t)(old), (void**)&(new))) #endif typedef int (*id_function_t)(void *, void *); typedef void (*unique_copy_ctor_func_t)(void *pElement); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO -static const HashBucket uninitialized_bucket = {INVALID_IDX}; +static const zend_uint uninitialized_bucket = {INVALID_IDX}; #endif static int zend_prepare_function_for_execution(zend_op_array *op_array); static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind); +static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC); static void zend_accel_destroy_zend_function(zend_function *function) { @@ -63,12 +64,11 @@ static void zend_accel_destroy_zend_function(zend_function *function) destroy_zend_function(function TSRMLS_CC); } -static void zend_accel_destroy_zend_class(zend_class_entry **pce) +static void zend_accel_destroy_zend_class(zval *zv) { - zend_class_entry *ce = *pce; - + zend_class_entry *ce = Z_PTR_P(zv); ce->function_table.pDestructor = (dtor_func_t) zend_accel_destroy_zend_function; - destroy_zend_class(pce); + destroy_zend_class(zv); } zend_persistent_script* create_persistent_script(void) @@ -92,7 +92,7 @@ static int compact_hash_table(HashTable *ht) uint j; uint nSize; Bucket *d; - HashBucket *h; + zend_uint *h; Bucket *p; if (!ht->nNumOfElements || (ht->flags & HASH_FLAG_PACKED)) { @@ -116,14 +116,14 @@ static int compact_hash_table(HashTable *ht) } d = (Bucket *)pemalloc(nSize * sizeof(Bucket), ht->flags & HASH_FLAG_PERSISTENT); - h = (HashBucket *)pemalloc(nSize * sizeof(HashBucket), ht->flags & HASH_FLAG_PERSISTENT); + h = (zend_uint *)pemalloc(nSize * sizeof(zend_uint), ht->flags & HASH_FLAG_PERSISTENT); if (!d || !h) { return 0; } for (i = 0, j = 0; i < ht->nNumUsed; i++) { p = ht->arData + i; - if (p->xData) { + if (Z_TYPE(p->val) != IS_UNDEF) { d[j++] = *p; } } @@ -167,8 +167,9 @@ void free_persistent_script(zend_persistent_script *persistent_script, int destr efree(persistent_script); } -static int is_not_internal_function(zend_function *function) +static int is_not_internal_function(zval *zv) { + zend_function *function = Z_PTR_P(zv); return(function->type != ZEND_INTERNAL_FUNCTION); } @@ -181,12 +182,13 @@ void zend_accel_free_user_functions(HashTable *ht TSRMLS_DC) ht->pDestructor = orig_dtor; } -static int move_user_function(zend_function *function +static int move_user_function(zval *zv #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO TSRMLS_DC #endif , int num_args, va_list args, zend_hash_key *hash_key) { + zend_function *function = Z_PTR_P(zv); HashTable *function_table = va_arg(args, HashTable *); (void)num_args; /* keep the compiler happy */ #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO @@ -194,7 +196,7 @@ static int move_user_function(zend_function *function #endif if (function->type == ZEND_USER_FUNCTION) { - zend_hash_quick_update(function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, function, sizeof(zend_function), NULL); + zend_hash_update_mem(function_table, hash_key->key, function, sizeof(zend_function)); return 1; } else { return 0; @@ -214,10 +216,11 @@ void zend_accel_move_user_functions(HashTable *src, HashTable *dst TSRMLS_DC) src->pDestructor = orig_dtor; } -static int copy_internal_function(zend_function *function, HashTable *function_table TSRMLS_DC) +static int copy_internal_function(zval *zv, HashTable *function_table TSRMLS_DC) { + zend_internal_function *function = Z_PTR_P(zv); if (function->type == ZEND_INTERNAL_FUNCTION) { - zend_hash_update(function_table, function->common.function_name, strlen(function->common.function_name) + 1, function, sizeof(zend_function), NULL); + zend_hash_update_mem(function_table, function->function_name, function, sizeof(zend_internal_function)); } return 0; } @@ -230,9 +233,79 @@ void zend_accel_copy_internal_functions(TSRMLS_D) static void zend_destroy_property_info(zend_property_info *property_info) { - interned_efree((char*)property_info->name); + STR_RELEASE(property_info->name); if (property_info->doc_comment) { - efree((char*)property_info->doc_comment); + STR_RELEASE(property_info->doc_comment); + } +} + +static inline void zend_clone_zval(zval *src, int bind TSRMLS_DC) +{ + void *ptr; + +#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO + switch ((Z_TYPE_P(src) & IS_CONSTANT_TYPE_MASK)) { +#else + switch ((Z_TYPE_P(src) & ~IS_CONSTANT_INDEX)) { +#endif + case IS_STRING: + case IS_CONSTANT: + if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_STR_P(src))) != NULL) { + Z_STR_P(src) = ptr; + } else { + zend_string *old = Z_STR_P(src); + + Z_STR_P(src) = STR_DUP(old, 0); + Z_STR_P(src)->gc = old->gc; + if (bind && Z_REFCOUNT_P(src) > 1) { + accel_xlat_set(old, Z_STR_P(src)); + } + } + break; + case IS_ARRAY: + case IS_CONSTANT_ARRAY: + if (Z_ARR_P(src) != &EG(symbol_table)) { + if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_ARR_P(src))) != NULL) { + Z_ARR_P(src) = ptr; + } else { + zend_array *old = Z_ARR_P(src); + + Z_ARR_P(src) = emalloc(sizeof(zend_array)); + Z_ARR_P(src)->gc = old->gc; + if (bind && Z_REFCOUNT_P(src) > 1) { + accel_xlat_set(old, Z_ARR_P(src)); + } + zend_hash_clone_zval(Z_ARRVAL_P(src), &old->ht, 0); + } + } + break; + case IS_REFERENCE: + if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_REF_P(src))) != NULL) { + Z_REF_P(src) = ptr; + } else { + zend_reference *old = Z_REF_P(src); + ZVAL_NEW_REF(src, &old->val); + Z_REF_P(src)->gc = old->gc; + if (bind && Z_REFCOUNT_P(src) > 1) { + accel_xlat_set(old, Z_REF_P(src)); + } + zend_clone_zval(Z_REFVAL_P(src), bind TSRMLS_C); + } + break; + case IS_CONSTANT_AST: + if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_AST_P(src))) != NULL) { + Z_AST_P(src) = ptr; + } else { + zend_ast_ref *old = Z_AST_P(src); + + ZVAL_NEW_AST(src, old->ast); + Z_AST_P(src)->gc = old->gc; + if (bind && Z_REFCOUNT_P(src) > 1) { + accel_xlat_set(old, Z_AST_P(src)); + } + Z_ASTVAL_P(src) = zend_ast_clone(Z_ASTVAL_P(src) TSRMLS_CC); + } + break; } } @@ -246,26 +319,8 @@ static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC) node = emalloc(sizeof(zend_ast) + sizeof(zval)); node->kind = ZEND_CONST; node->children = 0; - node->u.val = (zval*)(node + 1); - *node->u.val = *ast->u.val; - if ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) { - switch ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK)) { - case IS_STRING: - case IS_CONSTANT: - Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRLEN_P(ast->u.val)); - break; - case IS_ARRAY: - case IS_CONSTANT_ARRAY: - if (ast->u.val->value.ht && ast->u.val->value.ht != &EG(symbol_table)) { - ALLOC_HASHTABLE(node->u.val->value.ht); - zend_hash_clone_zval(node->u.val->value.ht, ast->u.val->value.ht, 0); - } - break; - case IS_CONSTANT_AST: - Z_AST_P(node->u.val) = zend_ast_clone(Z_AST_P(ast->u.val) TSRMLS_CC); - break; - } - } + ZVAL_COPY_VALUE(&node->u.val, &ast->u.val); + zend_clone_zval(&node->u.val, 0); } else { node = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); node->kind = ast->kind; @@ -282,59 +337,11 @@ static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC) } #endif -static inline zval* zend_clone_zval(zval *src, int bind TSRMLS_DC) -{ - zval *ret, **ret_ptr = NULL; - - if (!bind) { - ALLOC_ZVAL(ret); - *ret = *src; - INIT_PZVAL(ret); - } else if (Z_REFCOUNT_P(src) == 1) { - ALLOC_ZVAL(ret); - *ret = *src; - } else if (accel_xlat_get(src, ret_ptr) != SUCCESS) { - ALLOC_ZVAL(ret); - *ret = *src; - accel_xlat_set(src, ret); - } else { - return *ret_ptr; - } - -#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO - if ((Z_TYPE_P(ret) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) { - switch ((Z_TYPE_P(ret) & IS_CONSTANT_TYPE_MASK)) { -#else - if ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX) >= IS_ARRAY) { - switch ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX)) { -#endif - case IS_STRING: - case IS_CONSTANT: - Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRLEN_P(ret)); - break; - case IS_ARRAY: - case IS_CONSTANT_ARRAY: - if (ret->value.ht && ret->value.ht != &EG(symbol_table)) { - ALLOC_HASHTABLE(ret->value.ht); - zend_hash_clone_zval(ret->value.ht, src->value.ht, 0); - } - break; -#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO - case IS_CONSTANT_AST: - Z_AST_P(ret) = zend_ast_clone(Z_AST_P(ret) TSRMLS_CC); - break; -#endif - } - } - return ret; -} - static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) { uint idx; Bucket *p, *q; ulong nIndex; - zval *ppz; TSRMLS_FETCH(); ht->nTableSize = source->nTableSize; @@ -344,9 +351,9 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) ht->nNextFreeElement = source->nNextFreeElement; ht->pDestructor = ZVAL_PTR_DTOR; #if ZEND_DEBUG - ht->inconsistent = 0; +//??? ht->inconsistent = 0; #endif - ht->flags = HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_PTR_DATA; + ht->flags = HASH_FLAG_APPLY_PROTECTION; ht->arData = NULL; ht->arHash = NULL; ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX; @@ -354,7 +361,7 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (!ht->nTableMask) { - ht->arHash = (HashBucket*)&uninitialized_bucket; + ht->arHash = (zend_uint*)&uninitialized_bucket; return; } #endif @@ -362,15 +369,15 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket)); if (source->flags & HASH_FLAG_PACKED) { ht->flags |= HASH_FLAG_PACKED; - ht->arHash = (HashBucket*)&uninitialized_bucket; + ht->arHash = (zend_uint*)&uninitialized_bucket; } else { - ht->arHash = (HashBucket *) ecalloc(ht->nTableSize, sizeof(HashBucket)); - memset(ht->arHash, INVALID_IDX, sizeof(HashBucket) * ht->nTableSize); + ht->arHash = (zend_uint *) ecalloc(ht->nTableSize, sizeof(zend_uint)); + memset(ht->arHash, INVALID_IDX, sizeof(zend_uint) * ht->nTableSize); } for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; - if (!p->xData) continue; + if (Z_TYPE(p->val) == IS_UNDEF) continue; nIndex = p->h & ht->nTableMask; /* Insert into hash collision list */ @@ -379,65 +386,21 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) ht->nNumUsed = p->h + 1; } else { q = ht->arData + ht->nNumUsed; - q->next = ht->arHash[nIndex].idx; - ht->arHash[nIndex].idx = ht->nNumUsed++; + q->val.u.next = ht->arHash[nIndex]; + ht->arHash[nIndex] = ht->nNumUsed++; } /* Initialize key */ q->h = p->h; - q->nKeyLength = p->nKeyLength; - if (!p->nKeyLength) { - q->arKey = NULL; - } else if (IS_INTERNED(p->arKey)) { - q->arKey = p->arKey; + if (!p->key) { + q->key = NULL; } else { - q->arKey = (const char *) emalloc(p->nKeyLength); - memcpy((char*)q->arKey, p->arKey, p->nKeyLength); + q->key = STR_DUP(q->key, 0); } /* Copy data */ - if (!bind) { - ALLOC_ZVAL(ppz); - *ppz = *((zval*)p->xData); - INIT_PZVAL(ppz); - } else if (Z_REFCOUNT_P((zval*)p->xData) == 1) { - ALLOC_ZVAL(ppz); - *ppz = *((zval*)p->xData); - } else if (accel_xlat_get(p->xData, ppz) != SUCCESS) { - ALLOC_ZVAL(ppz); - *ppz = *((zval*)p->xData); - accel_xlat_set(p->xData, ppz); - } else { - q->xData = *(void**)ppz; - continue; - } - q->xData = (void*)ppz; - -#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO - if ((Z_TYPE_P((zval*)p->xData) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) { - switch ((Z_TYPE_P((zval*)p->xData) & IS_CONSTANT_TYPE_MASK)) { -#else - if ((Z_TYPE_P((zval*)p->xData) & ~IS_CONSTANT_INDEX) >= IS_ARRAY) { - switch ((Z_TYPE_P((zval*)p->xData) & ~IS_CONSTANT_INDEX)) { -#endif - case IS_STRING: - case IS_CONSTANT: - Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->xData), Z_STRLEN_P((zval*)p->xData)); - break; - case IS_ARRAY: - case IS_CONSTANT_ARRAY: - if (((zval*)p->xData)->value.ht && ((zval*)p->xData)->value.ht != &EG(symbol_table)) { - ALLOC_HASHTABLE(ppz->value.ht); - zend_hash_clone_zval(ppz->value.ht, ((zval*)p->xData)->value.ht, 0); - } - break; -#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO - case IS_CONSTANT_AST: - Z_AST_P(ppz) = zend_ast_clone(Z_AST_P(ppz) TSRMLS_CC); - break; -#endif - } - } + ZVAL_COPY_VALUE(&q->val, &p->val); + zend_clone_zval(&q->val, bind TSRMLS_C); } } @@ -446,8 +409,8 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class uint idx; Bucket *p, *q; ulong nIndex; - zend_class_entry **new_ce; - zend_function** new_prototype; + zend_class_entry *new_ce; + zend_function *new_prototype; zend_op_array *new_entry; ht->nTableSize = source->nTableSize; @@ -457,15 +420,15 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class ht->nNextFreeElement = source->nNextFreeElement; ht->pDestructor = ZEND_FUNCTION_DTOR; #if ZEND_DEBUG - ht->inconsistent = 0; +//??? ht->inconsistent = 0; #endif - ht->flags = HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_BIG_DATA; + ht->flags = HASH_FLAG_APPLY_PROTECTION; ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX; ht->nApplyCount = 0; #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (!ht->nTableMask) { - ht->arHash = (HashBucket*)&uninitialized_bucket; + ht->arHash = (zend_uint*)&uninitialized_bucket; return; } #endif @@ -473,15 +436,15 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket)); if (source->flags & HASH_FLAG_PACKED) { ht->flags |= HASH_FLAG_PACKED; - ht->arHash = (HashBucket*)&uninitialized_bucket; + ht->arHash = (zend_uint*)&uninitialized_bucket; } else { - ht->arHash = (HashBucket *) ecalloc(ht->nTableSize, sizeof(HashBucket)); - memset(ht->arHash, INVALID_IDX, sizeof(HashBucket) * ht->nTableSize); + ht->arHash = (zend_uint *) ecalloc(ht->nTableSize, sizeof(zend_uint)); + memset(ht->arHash, INVALID_IDX, sizeof(zend_uint) * ht->nTableSize); } for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; - if (!p->xData) continue; + if (Z_TYPE(p->val) == IS_UNDEF) continue; nIndex = p->h & ht->nTableMask; @@ -491,31 +454,27 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class ht->nNumUsed = p->h + 1; } else { q = ht->arData + ht->nNumUsed; - q->next = ht->arHash[nIndex].idx; - ht->arHash[nIndex].idx = ht->nNumUsed++; + q->val.u.next = ht->arHash[nIndex]; + ht->arHash[nIndex] = ht->nNumUsed++; } /* Initialize key */ q->h = p->h; - q->nKeyLength = p->nKeyLength; - if (!p->nKeyLength) { - q->arKey = NULL; - } else if (IS_INTERNED(p->arKey)) { - q->arKey = p->arKey; + if (!p->key) { + q->key = NULL; } else { - q->arKey = (const char *) emalloc(p->nKeyLength); - memcpy((char*)q->arKey, p->arKey, p->nKeyLength); + q->key = STR_DUP(p->key, 0); } /* Copy data */ - q->xData = (void *) emalloc(sizeof(zend_function)); - new_entry = (zend_op_array*)q->xData; - *new_entry = *(zend_op_array*)p->xData; + Z_PTR(q->val) = (void *) emalloc(sizeof(zend_function)); + new_entry = (zend_op_array*)Z_PTR(q->val); + *new_entry = *(zend_op_array*)Z_PTR(p->val); /* Copy constructor */ /* we use refcount to show that op_array is referenced from several places */ if (new_entry->refcount != NULL) { - accel_xlat_set(p->xData, new_entry); + accel_xlat_set(Z_PTR(p->val), new_entry); } zend_prepare_function_for_execution(new_entry); @@ -523,19 +482,19 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class if (old_ce == new_entry->scope) { new_entry->scope = ce; } else { - if (accel_xlat_get(new_entry->scope, new_ce) == SUCCESS) { - new_entry->scope = *new_ce; + if ((new_ce = accel_xlat_get(new_entry->scope)) != NULL) { + new_entry->scope = new_ce; } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name); + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name->val, new_entry->function_name->val); } } /* update prototype */ if (new_entry->prototype) { - if (accel_xlat_get(new_entry->prototype, new_prototype) == SUCCESS) { - new_entry->prototype = *new_prototype; + if ((new_prototype = accel_xlat_get(new_entry->prototype)) != NULL) { + new_entry->prototype = new_prototype; } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name); + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name->val, new_entry->function_name->val); } } } @@ -546,7 +505,7 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla uint idx; Bucket *p, *q; ulong nIndex; - zend_class_entry **new_ce; + zend_class_entry *new_ce; zend_property_info *prop_info; ht->nTableSize = source->nTableSize; @@ -556,15 +515,15 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla ht->nNextFreeElement = source->nNextFreeElement; ht->pDestructor = (dtor_func_t) zend_destroy_property_info; #if ZEND_DEBUG - ht->inconsistent = 0; +//??? ht->inconsistent = 0; #endif - ht->flags = HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_BIG_DATA; + ht->flags = HASH_FLAG_APPLY_PROTECTION; ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX; ht->nApplyCount = 0; #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (!ht->nTableMask) { - ht->arHash = (HashBucket*)&uninitialized_bucket; + ht->arHash = (zend_uint*)&uninitialized_bucket; return; } #endif @@ -572,15 +531,15 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket)); if (source->flags & HASH_FLAG_PACKED) { ht->flags |= HASH_FLAG_PACKED; - ht->arHash = (HashBucket*)&uninitialized_bucket; + ht->arHash = (zend_uint*)&uninitialized_bucket; } else { - ht->arHash = (HashBucket *) ecalloc(ht->nTableSize, sizeof(HashBucket)); - memset(ht->arHash, INVALID_IDX, sizeof(HashBucket) * ht->nTableSize); + ht->arHash = (zend_uint *) ecalloc(ht->nTableSize, sizeof(zend_uint)); + memset(ht->arHash, INVALID_IDX, sizeof(zend_uint) * ht->nTableSize); } for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; - if (!p->xData) continue; + if (Z_TYPE(p->val) == IS_UNDEF) continue; nIndex = p->h & ht->nTableMask; @@ -590,42 +549,38 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla ht->nNumUsed = p->h + 1; } else { q = ht->arData + ht->nNumUsed; - q->next = ht->arHash[nIndex].idx; - ht->arHash[nIndex].idx = ht->nNumUsed++; + q->val.u.next = ht->arHash[nIndex]; + ht->arHash[nIndex] = ht->nNumUsed++; } /* Initialize key */ q->h = p->h; - q->nKeyLength = p->nKeyLength; - if (!p->nKeyLength) { - q->arKey = NULL; - } else if (IS_INTERNED(p->arKey)) { - q->arKey = p->arKey; + if (!p->key) { + q->key = NULL; } else { - q->arKey = (const char *) emalloc(p->nKeyLength); - memcpy((char*)q->arKey, p->arKey, p->nKeyLength); + q->key = STR_DUP(p->key, 0); } /* Copy data */ - q->xData = (void *) emalloc(sizeof(zend_property_info)); - prop_info = q->xData; - *prop_info = *(zend_property_info*)p->xData; + Z_PTR(q->val) = (void *) emalloc(sizeof(zend_property_info)); + prop_info = Z_PTR(q->val); + *prop_info = *(zend_property_info*)Z_PTR(p->val); /* Copy constructor */ - prop_info->name = interned_estrndup(prop_info->name, prop_info->name_length); + prop_info->name = STR_DUP(prop_info->name, 0); if (prop_info->doc_comment) { if (ZCG(accel_directives).load_comments) { - prop_info->doc_comment = estrndup(prop_info->doc_comment, prop_info->doc_comment_len); + prop_info->doc_comment = STR_DUP(prop_info->doc_comment, 0); } else { prop_info->doc_comment = NULL; } } if (prop_info->ce == old_ce) { prop_info->ce = ce; - } else if (accel_xlat_get(prop_info->ce, new_ce) == SUCCESS) { - prop_info->ce = *new_ce; + } else if ((new_ce = accel_xlat_get(prop_info->ce)) != NULL) { + prop_info->ce = new_ce; } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name, prop_info->name); + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name->val, prop_info->name->val); } } } @@ -651,10 +606,10 @@ static int zend_prepare_function_for_execution(zend_op_array *op_array) #define zend_update_inherited_handler(handler) \ { \ if (ce->handler != NULL) { \ - if (accel_xlat_get(ce->handler, new_func) == SUCCESS) { \ - ce->handler = *new_func; \ + if ((new_func = accel_xlat_get(ce->handler)) != NULL) { \ + ce->handler = new_func; \ } else { \ - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name); \ + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name->val); \ } \ } \ } @@ -664,8 +619,8 @@ static void zend_class_copy_ctor(zend_class_entry **pce) { zend_class_entry *ce = *pce; zend_class_entry *old_ce = ce; - zend_class_entry **new_ce; - zend_function **new_func; + zend_class_entry *new_ce; + zend_function *new_func; TSRMLS_FETCH(); *pce = ce = emalloc(sizeof(zend_class_entry)); @@ -683,11 +638,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce) ce->default_properties_table = emalloc(sizeof(zval*) * old_ce->default_properties_count); for (i = 0; i < old_ce->default_properties_count; i++) { - if (old_ce->default_properties_table[i]) { - ce->default_properties_table[i] = zend_clone_zval(old_ce->default_properties_table[i], 0 TSRMLS_CC); - } else { - ce->default_properties_table[i] = NULL; - } + zend_clone_zval(&old_ce->default_properties_table[i], 0 TSRMLS_CC); } } #else @@ -703,11 +654,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce) ce->default_static_members_table = emalloc(sizeof(zval*) * old_ce->default_static_members_count); for (i = 0; i < old_ce->default_static_members_count; i++) { - if (old_ce->default_static_members_table[i]) { - ce->default_static_members_table[i] = zend_clone_zval(old_ce->default_static_members_table[i], 1 TSRMLS_CC); - } else { - ce->default_static_members_table[i] = NULL; - } + zend_clone_zval(&old_ce->default_static_members_table[i], 1 TSRMLS_CC); } } ce->static_members_table = ce->default_static_members_table; @@ -722,7 +669,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce) /* constants table */ zend_hash_clone_zval(&ce->constants_table, &old_ce->constants_table, 0); - ce->name = interned_estrndup(ce->name, ce->name_length); + ce->name = STR_DUP(ce->name, 0); /* interfaces aren't really implemented, so we create a new table */ if (ce->num_interfaces) { @@ -733,17 +680,17 @@ static void zend_class_copy_ctor(zend_class_entry **pce) } if (ZEND_CE_DOC_COMMENT(ce)) { if (ZCG(accel_directives).load_comments) { - ZEND_CE_DOC_COMMENT(ce) = estrndup(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce)); + ZEND_CE_DOC_COMMENT(ce) = STR_DUP(ZEND_CE_DOC_COMMENT(ce), 0); } else { ZEND_CE_DOC_COMMENT(ce) = NULL; } } if (ce->parent) { - if (accel_xlat_get(ce->parent, new_ce) == SUCCESS) { - ce->parent = *new_ce; + if ((new_ce = accel_xlat_get(ce->parent)) != NULL) { + ce->parent = new_ce; } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name); + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name->val); } } @@ -785,20 +732,17 @@ static void zend_class_copy_ctor(zend_class_entry **pce) if (trait_aliases[i]->trait_method) { if (trait_aliases[i]->trait_method->method_name) { trait_aliases[i]->trait_method->method_name = - estrndup(trait_aliases[i]->trait_method->method_name, - trait_aliases[i]->trait_method->mname_len); + STR_DUP(trait_aliases[i]->trait_method->method_name, 0); } if (trait_aliases[i]->trait_method->class_name) { trait_aliases[i]->trait_method->class_name = - estrndup(trait_aliases[i]->trait_method->class_name, - trait_aliases[i]->trait_method->cname_len); + STR_DUP(trait_aliases[i]->trait_method->class_name, 0); } } if (trait_aliases[i]->alias) { trait_aliases[i]->alias = - estrndup(trait_aliases[i]->alias, - trait_aliases[i]->alias_len); + STR_DUP(trait_aliases[i]->alias, 0); } i++; } @@ -822,29 +766,26 @@ static void zend_class_copy_ctor(zend_class_entry **pce) memcpy(trait_precedences[i]->trait_method, ce->trait_precedences[i]->trait_method, sizeof(zend_trait_method_reference)); trait_precedences[i]->trait_method->method_name = - estrndup(trait_precedences[i]->trait_method->method_name, - trait_precedences[i]->trait_method->mname_len); + STR_DUP(trait_precedences[i]->trait_method->method_name, 0); trait_precedences[i]->trait_method->class_name = - estrndup(trait_precedences[i]->trait_method->class_name, - trait_precedences[i]->trait_method->cname_len); + STR_DUP(trait_precedences[i]->trait_method->class_name, 0); if (trait_precedences[i]->exclude_from_classes) { - zend_class_entry **exclude_from_classes; + zend_string **exclude_from_classes; int j = 0; - while (trait_precedences[i]->exclude_from_classes[j]) { + while (trait_precedences[i]->exclude_from_classes[j].class_name) { j++; } - exclude_from_classes = emalloc(sizeof(zend_class_entry*) * (j + 1)); + exclude_from_classes = emalloc(sizeof(zend_string*) * (j + 1)); j = 0; - while (trait_precedences[i]->exclude_from_classes[j]) { - exclude_from_classes[j] = (zend_class_entry*)estrndup( - (char*)trait_precedences[i]->exclude_from_classes[j], - strlen((char*)trait_precedences[i]->exclude_from_classes[j])); + while (trait_precedences[i]->exclude_from_classes[j].class_name) { + exclude_from_classes[j] = + STR_DUP(trait_precedences[i]->exclude_from_classes[j].class_name, 0); j++; } exclude_from_classes[j] = NULL; - trait_precedences[i]->exclude_from_classes = exclude_from_classes; + trait_precedences[i]->exclude_from_classes = (void*)exclude_from_classes; } i++; } @@ -854,7 +795,59 @@ static void zend_class_copy_ctor(zend_class_entry **pce) #endif } -static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor, uint size, int ignore_dups, void **fail_data, void **conflict_data) +static int zend_hash_unique_copy_mem(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor, uint size, int ignore_dups, void **fail_data, void **conflict_data) +{ + uint idx; + Bucket *p; + void *t; + + for (idx = 0; idx < source->nNumUsed; idx++) { + p = source->arData + idx; + if (Z_TYPE(p->val) == IS_UNDEF) continue; + if (p->key) { + if ((t = zend_hash_add_mem(target, p->key, Z_PTR(p->val), size)) != NULL) { + if (pCopyConstructor) { + pCopyConstructor(t); + } + } else { + if (p->key->len > 0 && p->key->val[0] == 0) { + /* Mangled key */ +#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO + if (((zend_function*)Z_PTR(p->val))->common.fn_flags & ZEND_ACC_CLOSURE) { + /* update closure */ + if ((t = zend_hash_update_mem(target, p->key, Z_PTR(p->val), size)) != NULL) { + if (pCopyConstructor) { + pCopyConstructor(t); + } + } + } else { + /* ignore and wait for runtime */ + } +#endif + } else if (!ignore_dups && (t = zend_hash_find_ptr(target, p->key)) != NULL) { + *fail_data = Z_PTR(p->val); + *conflict_data = t; + return FAILURE; + } + } + } else { + if (!zend_hash_index_exists(target, p->h) && (t = zend_hash_index_update_mem(target, p->h, Z_PTR(p->val), size)) != NULL) { + if (pCopyConstructor) { + pCopyConstructor(t); + } + } else if (!ignore_dups && (t = zend_hash_index_find_ptr(target,p->h)) != NULL) { + *fail_data = Z_PTR(p->val); + *conflict_data = t; + return FAILURE; + } + } + } + target->nInternalPointer = target->nNumOfElements ? 0 : INVALID_IDX; + + return SUCCESS; +} + +static int zend_hash_unique_copy_ptr(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor, int ignore_dups, void **fail_data, void **conflict_data) { uint idx; Bucket *p; @@ -862,19 +855,19 @@ static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_co for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; - if (!p->xData) continue; - if (p->nKeyLength > 0) { - if (zend_hash_quick_add(target, p->arKey, p->nKeyLength, p->h, HASH_DATA(source, p), size, &t) == SUCCESS) { + if (Z_TYPE(p->val) == IS_UNDEF) continue; + if (p->key) { + if ((t = zend_hash_add_ptr(target, p->key, Z_PTR(p->val))) != NULL) { if (pCopyConstructor) { pCopyConstructor(t); } } else { - if (p->nKeyLength > 0 && p->arKey[0] == 0) { + if (p->key->len > 0 && p->key->val[0] == 0) { /* Mangled key */ #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO - if (((zend_function*)p->xData)->common.fn_flags & ZEND_ACC_CLOSURE) { + if (((zend_function*)Z_PTR(p->val))->common.fn_flags & ZEND_ACC_CLOSURE) { /* update closure */ - if (zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, HASH_DATA(source, p), size, &t) == SUCCESS) { + if ((t = zend_hash_update_ptr(target, p->key, Z_PTR(p->val))) != NULL) { if (pCopyConstructor) { pCopyConstructor(t); } @@ -883,19 +876,19 @@ static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_co /* ignore and wait for runtime */ } #endif - } else if (!ignore_dups && zend_hash_quick_find(target, p->arKey, p->nKeyLength, p->h, &t) == SUCCESS) { - *fail_data = HASH_DATA(source, p); + } else if (!ignore_dups && (t = zend_hash_find_ptr(target, p->key)) != NULL) { + *fail_data = Z_PTR(p->val); *conflict_data = t; return FAILURE; } } } else { - if (!zend_hash_index_exists(target, p->h) && zend_hash_index_update(target, p->h, HASH_DATA(source, p), size, &t) == SUCCESS) { + if (!zend_hash_index_exists(target, p->h) && (t = zend_hash_index_update_ptr(target, p->h, Z_PTR(p->val))) != NULL) { if (pCopyConstructor) { pCopyConstructor(t); } - } else if (!ignore_dups && zend_hash_index_find(target,p->h, &t) == SUCCESS) { - *fail_data = HASH_DATA(source, p); + } else if (!ignore_dups && (t = zend_hash_index_find_ptr(target,p->h)) != NULL) { + *fail_data = Z_PTR(p->val); *conflict_data = t; return FAILURE; } @@ -911,36 +904,36 @@ static void zend_accel_function_hash_copy(HashTable *target, HashTable *source, zend_function *function1, *function2; TSRMLS_FETCH(); - if (zend_hash_unique_copy(target, source, pCopyConstructor, sizeof(zend_function), 0, (void**)&function1, (void**)&function2) != SUCCESS) { + if (zend_hash_unique_copy_mem(target, source, pCopyConstructor, sizeof(zend_function), 0, (void**)&function1, (void**)&function2) != SUCCESS) { CG(in_compilation) = 1; zend_set_compiled_filename(function1->op_array.filename TSRMLS_CC); CG(zend_lineno) = function1->op_array.opcodes[0].lineno; if (function2->type == ZEND_USER_FUNCTION && function2->op_array.last > 0) { zend_error(E_ERROR, "Cannot redeclare %s() (previously declared in %s:%d)", - function1->common.function_name, - function2->op_array.filename, + function1->common.function_name->val, + function2->op_array.filename->val, (int)function2->op_array.opcodes[0].lineno); } else { - zend_error(E_ERROR, "Cannot redeclare %s()", function1->common.function_name); + zend_error(E_ERROR, "Cannot redeclare %s()", function1->common.function_name->val); } } } static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor TSRMLS_DC) { - zend_class_entry **pce1, **pce2; + zend_class_entry *ce1, *ce2; - if (zend_hash_unique_copy(target, source, pCopyConstructor, sizeof(zend_class_entry*), ZCG(accel_directives).ignore_dups, (void**)&pce1, (void**)&pce2) != SUCCESS) { + if (zend_hash_unique_copy_ptr(target, source, pCopyConstructor, ZCG(accel_directives).ignore_dups, (void**)&ce1, (void**)&ce2) != SUCCESS) { CG(in_compilation) = 1; #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - zend_set_compiled_filename((*pce1)->info.user.filename TSRMLS_CC); - CG(zend_lineno) = (*pce1)->info.user.line_start; + zend_set_compiled_filename(ce1->info.user.filename TSRMLS_CC); + CG(zend_lineno) = ce1->info.user.line_start; #else - zend_set_compiled_filename((*pce1)->filename TSRMLS_CC); - CG(zend_lineno) = (*pce1)->line_start; + zend_set_compiled_filename(ce1->filename TSRMLS_CC); + CG(zend_lineno) = ce1->line_start; #endif - zend_error(E_ERROR, "Cannot redeclare class %s", (*pce1)->name); + zend_error(E_ERROR, "Cannot redeclare class %s", ce1->name->val); } } @@ -992,17 +985,14 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, /* Register __COMPILER_HALT_OFFSET__ constant */ if (persistent_script->compiler_halt_offset != 0 && persistent_script->full_path) { - char *name, *cfilename; + zend_string *name; char haltoff[] = "__COMPILER_HALT_OFFSET__"; - int len, clen; - cfilename = persistent_script->full_path; - clen = strlen(cfilename); - zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, cfilename, clen, 0); - if (!zend_hash_exists(EG(zend_constants), name, len + 1)) { - zend_register_long_constant(name, len + 1, persistent_script->compiler_halt_offset, CONST_CS, 0 TSRMLS_CC); + name = zend_mangle_property_name(haltoff, sizeof(haltoff) - 1, persistent_script->full_path->val, persistent_script->full_path->len, 0); + if (!zend_hash_exists(EG(zend_constants), name)) { + zend_register_long_constant(name->val, name->len, persistent_script->compiler_halt_offset, CONST_CS, 0 TSRMLS_CC); } - efree(name); + STR_RELEASE(name); } #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO @@ -1023,7 +1013,7 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO if (op_array->early_binding != (zend_uint)-1) { - char *orig_compiled_filename = CG(compiled_filename); + zend_string *orig_compiled_filename = CG(compiled_filename); CG(compiled_filename) = persistent_script->full_path; zend_do_delayed_early_binding(op_array TSRMLS_CC); CG(compiled_filename) = orig_compiled_filename; diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 01d4ce69ab..bcec15c03b 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -34,12 +34,14 @@ _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); } \ - } while (0) +# define zend_accel_store_string(str) \ + zend_accel_store(str, sizeof(zend_string) + (str)->len) +# define zend_accel_memdup_string(str) \ + zend_accel_memdup(str, sizeof(zend_string) + (str)->len) +# define zend_accel_store_interned_string(str) \ + (IS_ACCEL_INTERNED(str) ? str : zend_accel_store_string(str)) +# define zend_accel_memdup_interned_string(str) \ + (IS_ACCEL_INTERNED(str) ? str : zend_accel_memdup_string(str)) #else # define zend_accel_memdup_interned_string(str, len) \ zend_accel_memdup(str, len) @@ -48,48 +50,40 @@ 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); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO -static const HashBucket uninitialized_bucket = {INVALID_IDX}; +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) { uint idx; Bucket *p; if (!ht->nTableMask) { - ht->arHash = (HashBucket*)&uninitialized_bucket; + ht->arHash = (zend_uint*)&uninitialized_bucket; return; } zend_accel_store(ht->arData, sizeof(Bucket) * ht->nTableSize); if (!(ht->flags & HASH_FLAG_PACKED)) { - zend_accel_store(ht->arHash, sizeof(HashBucket) * ht->nTableSize); + zend_accel_store(ht->arHash, sizeof(zend_uint) * ht->nTableSize); } else { - ht->arHash = (HashBucket*)&uninitialized_bucket; + ht->arHash = (zend_uint*)&uninitialized_bucket; } for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; - if (!p->xData) continue; + if (Z_TYPE(p->val) == IS_UNDEF) continue; /* persist bucket and key */ - if (p->nKeyLength) { - zend_accel_store_interned_string(p->arKey, p->nKeyLength); - } - - /* persist data pointer in bucket */ - if (ht->flags & HASH_FLAG_BIG_DATA) { - zend_accel_store(p->xData, el_size); + if (p->key) { + zend_accel_store_interned_string(p->key); } /* persist the data itself */ - if (pPersistElement) { - pPersistElement(HASH_DATA(ht, p) TSRMLS_CC); - } + pPersistElement(&p->val TSRMLS_CC); } } @@ -100,9 +94,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++) { @@ -118,6 +111,8 @@ static zend_ast *zend_persist_ast(zend_ast *ast TSRMLS_DC) static void zend_persist_zval(zval *z TSRMLS_DC) { + void *new_ptr; + #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO switch (z->type & IS_CONSTANT_TYPE_MASK) { #else @@ -125,38 +120,45 @@ static void zend_persist_zval(zval *z TSRMLS_DC) #endif case IS_STRING: case IS_CONSTANT: - zend_accel_store_interned_string(z->value.str.val, z->value.str.len + 1); + zend_accel_store_interned_string(Z_STR_P(z)); break; case IS_ARRAY: case IS_CONSTANT_ARRAY: - 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; + } else { + zend_accel_store(Z_ARR_P(z), sizeof(zend_array)); + zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval TSRMLS_CC); + } 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) -{ - zval *new_ptr = zend_shared_alloc_get_xlat_entry(*zp); - - 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); - } -} - static void zend_protect_zval(zval *z TSRMLS_DC) { - PZ_SET_ISREF_P(z); - PZ_SET_REFCOUNT_P(z, 2); +//??? 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) @@ -168,7 +170,7 @@ 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 zend_literal *orig_literals = NULL; #endif - + if (op_array->type != ZEND_USER_FUNCTION) { return; } @@ -184,7 +186,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc 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); + zend_accel_memdup_string(op_array->filename); } if (main_persistent_script) { @@ -333,11 +335,11 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } if (op_array->function_name) { - char *new_name; + zend_string *new_name; if ((new_name = zend_shared_alloc_get_xlat_entry(op_array->function_name))) { 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); } } @@ -351,10 +353,10 @@ 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); } 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); } } } @@ -365,7 +367,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } 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_hash_persist(op_array->static_variables, zend_persist_zval TSRMLS_CC); zend_accel_store(op_array->static_variables, sizeof(HashTable)); } @@ -375,14 +377,13 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc if (op_array->doc_comment) { if (ZCG(accel_directives).save_comments) { - zend_accel_store(op_array->doc_comment, op_array->doc_comment_len + 1); + 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); + STR_RELEASE(op_array->doc_comment); } op_array->doc_comment = NULL; - op_array->doc_comment_len = 0; } } @@ -392,12 +393,12 @@ 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; + 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]); } } } @@ -414,45 +415,47 @@ 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); + zend_accel_store(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; + + zend_accel_store(Z_PTR_P(zv), sizeof(zend_property_info)); + prop = Z_PTR_P(zv); + 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); + Z_PTR_P(zv) = zend_accel_store(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); 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) { @@ -460,36 +463,33 @@ static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC) 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); } @@ -506,12 +506,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, @@ -519,8 +517,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 @@ -537,10 +534,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)); @@ -548,9 +543,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, @@ -644,18 +638,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; diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index 47abb908bc..f5aa322b2c 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -32,13 +32,18 @@ #define RETURN_SIZE() return memory_used #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO -# define ADD_INTERNED_STRING(str, len) do { \ - if (!IS_INTERNED(str)) { \ - const char *tmp = accel_new_interned_string((str), (len), 1 TSRMLS_CC); \ +# define ADD_STRING(str) \ + ADD_DUP_SIZE((str), sizeof(zend_string) + (str)->len) +# define ADD_INTERNED_STRING(str, do_free) do { \ + if (!IS_ACCEL_INTERNED(str)) { \ + zend_string *tmp = accel_new_interned_string(str TSRMLS_CC); \ if (tmp != (str)) { \ - (str) = (char*)tmp; \ + if (do_free) { \ + /*STR_RELEASE(str);*/ \ + } \ + (str) = tmp; \ } else { \ - ADD_DUP_SIZE((str), (len)); \ + ADD_STRING(str); \ } \ } \ } while (0) @@ -46,10 +51,9 @@ # define ADD_INTERNED_STRING(str, len) ADD_DUP_SIZE((str), (len)) #endif -static uint zend_persist_zval_ptr_calc(zval **zp TSRMLS_DC); static uint zend_persist_zval_calc(zval *z TSRMLS_DC); -static uint zend_hash_persist_calc(HashTable *ht, int (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC) +static uint zend_hash_persist_calc(HashTable *ht, uint (*pPersistElement)(zval *pElement TSRMLS_DC) TSRMLS_DC) { uint idx; Bucket *p; @@ -60,33 +64,19 @@ static uint zend_hash_persist_calc(HashTable *ht, int (*pPersistElement)(void *p } ADD_DUP_SIZE(ht->arData, sizeof(Bucket) * ht->nTableSize); if (!(ht->flags & HASH_FLAG_PACKED)) { - ADD_DUP_SIZE(ht->arHash, sizeof(HashBucket) * ht->nTableSize); + ADD_DUP_SIZE(ht->arHash, sizeof(zend_uint) * ht->nTableSize); } for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; - if (!p->xData) continue; + if (Z_TYPE(p->val) == IS_UNDEF) continue; /* persist bucket and key */ - if (p->nKeyLength) { - const char *tmp = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC); - if (tmp != p->arKey) { - efree(p->arKey); - p->arKey = tmp; - } else { - ADD_DUP_SIZE(p->arKey, p->nKeyLength); - } - } - - /* persist data pointer in bucket */ - if (ht->flags & HASH_FLAG_BIG_DATA) { - ADD_DUP_SIZE(p->xData, el_size); + if (p->key) { + ADD_INTERNED_STRING(p->key, 1); } - /* persist the data itself */ - if (pPersistElement) { - ADD_SIZE(pPersistElement(HASH_DATA(ht, p) TSRMLS_CC)); - } + ADD_SIZE(pPersistElement(&p->val TSRMLS_CC)); } RETURN_SIZE(); @@ -99,8 +89,8 @@ static uint zend_persist_ast_calc(zend_ast *ast TSRMLS_DC) START_SIZE(); if (ast->kind == ZEND_CONST) { - ADD_SIZE(sizeof(zend_ast) + sizeof(zval)); - ADD_SIZE(zend_persist_zval_calc(ast->u.val TSRMLS_CC)); + ADD_SIZE(sizeof(zend_ast)); + ADD_SIZE(zend_persist_zval_calc(&ast->u.val TSRMLS_CC)); } else { ADD_SIZE(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); for (i = 0; i < ast->children; i++) { @@ -115,6 +105,7 @@ static uint zend_persist_ast_calc(zend_ast *ast TSRMLS_DC) static uint zend_persist_zval_calc(zval *z TSRMLS_DC) { + uint size; START_SIZE(); #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO @@ -124,35 +115,37 @@ static uint zend_persist_zval_calc(zval *z TSRMLS_DC) #endif case IS_STRING: case IS_CONSTANT: - ADD_INTERNED_STRING(Z_STRVAL_P(z), Z_STRLEN_P(z) + 1); + ADD_INTERNED_STRING(Z_STR_P(z), 0); break; case IS_ARRAY: case IS_CONSTANT_ARRAY: - ADD_DUP_SIZE(z->value.ht, sizeof(HashTable)); - ADD_SIZE(zend_hash_persist_calc(z->value.ht, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); + size = zend_shared_memdup_size(Z_ARR_P(z), sizeof(zend_array)); + if (size) { + ADD_SIZE(size); + ADD_SIZE(zend_hash_persist_calc(Z_ARRVAL_P(z), zend_persist_zval_calc TSRMLS_CC)); + } break; #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO + case IS_REFERENCE: + size = zend_shared_memdup_size(Z_REF_P(z), sizeof(zend_reference)); + if (size) { + ADD_SIZE(size); + zend_persist_zval_calc(Z_REFVAL_P(z) TSRMLS_CC); + } + break; case IS_CONSTANT_AST: - ADD_SIZE(zend_persist_ast_calc(Z_AST_P(z) TSRMLS_CC)); + size = zend_shared_memdup_size(Z_AST_P(z), sizeof(zend_ast_ref)); + if (size) { + ADD_SIZE(size); + ADD_SIZE(zend_persist_ast_calc(Z_ASTVAL_P(z) TSRMLS_CC)); + } break; #endif } RETURN_SIZE(); } -static uint zend_persist_zval_ptr_calc(zval **zp TSRMLS_DC) -{ - START_SIZE(); - zval *new_ptr = zend_shared_alloc_get_xlat_entry(*zp); - - if (!new_ptr) { - ADD_DUP_SIZE(*zp, sizeof(zval)); - ADD_SIZE(zend_persist_zval_calc(*zp TSRMLS_CC)); - } - RETURN_SIZE(); -} - -static uint zend_persist_op_array_calc(zend_op_array *op_array TSRMLS_DC) +static uint zend_persist_op_array_calc_ex(zend_op_array *op_array TSRMLS_DC) { START_SIZE(); @@ -161,7 +154,7 @@ static uint zend_persist_op_array_calc(zend_op_array *op_array TSRMLS_DC) } if (op_array->filename) { - ADD_DUP_SIZE(op_array->filename, strlen(op_array->filename) + 1); + ADD_STRING(op_array->filename); } #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO @@ -197,7 +190,7 @@ static uint zend_persist_op_array_calc(zend_op_array *op_array TSRMLS_DC) } if (op_array->function_name) { - ADD_DUP_SIZE(op_array->function_name, strlen(op_array->function_name) + 1); + ADD_INTERNED_STRING(op_array->function_name, 0); } if (op_array->arg_info && @@ -207,10 +200,10 @@ static uint zend_persist_op_array_calc(zend_op_array *op_array TSRMLS_DC) ADD_DUP_SIZE(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) { - ADD_INTERNED_STRING(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1); +//??? ADD_INTERNED_STRING(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1); } if (op_array->arg_info[i].class_name) { - ADD_INTERNED_STRING(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1); +//??? ADD_INTERNED_STRING(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1); } } @@ -222,11 +215,11 @@ static uint zend_persist_op_array_calc(zend_op_array *op_array TSRMLS_DC) if (op_array->static_variables) { ADD_DUP_SIZE(op_array->static_variables, sizeof(HashTable)); - ADD_SIZE(zend_hash_persist_calc(op_array->static_variables, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); + ADD_SIZE(zend_hash_persist_calc(op_array->static_variables, zend_persist_zval_calc TSRMLS_CC)); } if (ZCG(accel_directives).save_comments && op_array->doc_comment) { - ADD_DUP_SIZE(op_array->doc_comment, op_array->doc_comment_len + 1); + ADD_STRING(op_array->doc_comment); } if (op_array->try_catch_array) { @@ -236,43 +229,52 @@ static uint zend_persist_op_array_calc(zend_op_array *op_array TSRMLS_DC) if (op_array->vars && !zend_shared_alloc_get_xlat_entry(op_array->vars)) { int i; - ADD_DUP_SIZE(op_array->vars, sizeof(zend_compiled_variable) * op_array->last_var); + ADD_DUP_SIZE(op_array->vars, sizeof(zend_string*) * op_array->last_var); for (i = 0; i < op_array->last_var; i++) { - ADD_INTERNED_STRING(op_array->vars[i].name, op_array->vars[i].name_len + 1); + ADD_INTERNED_STRING(op_array->vars[i], 0); } } RETURN_SIZE(); } -static uint zend_persist_property_info_calc(zend_property_info *prop TSRMLS_DC) +static uint zend_persist_op_array_calc(zval *zv TSRMLS_DC) { START_SIZE(); - ADD_INTERNED_STRING(prop->name, prop->name_length + 1); + ADD_SIZE(sizeof(zend_op_array)); + ADD_SIZE(zend_persist_op_array_calc_ex(Z_PTR_P(zv) TSRMLS_CC)); + RETURN_SIZE(); +} + +static uint zend_persist_property_info_calc(zval *zv TSRMLS_DC) +{ + zend_property_info *prop = Z_PTR_P(zv); + START_SIZE(); + + ADD_SIZE(sizeof(zend_property_info)); + ADD_INTERNED_STRING(prop->name, 0); if (ZCG(accel_directives).save_comments && prop->doc_comment) { - ADD_DUP_SIZE(prop->doc_comment, prop->doc_comment_len + 1); + ADD_STRING(prop->doc_comment); } RETURN_SIZE(); } -static uint zend_persist_class_entry_calc(zend_class_entry **pce TSRMLS_DC) +static uint zend_persist_class_entry_calc(zval *zv TSRMLS_DC) { - zend_class_entry *ce = *pce; + zend_class_entry *ce = Z_PTR_P(zv); START_SIZE(); if (ce->type == ZEND_USER_CLASS) { ADD_DUP_SIZE(ce, sizeof(zend_class_entry)); - ADD_INTERNED_STRING(ce->name, ce->name_length + 1); - ADD_SIZE(zend_hash_persist_calc(&ce->function_table, (int (*)(void* TSRMLS_DC)) zend_persist_op_array_calc, sizeof(zend_op_array) TSRMLS_CC)); + ADD_INTERNED_STRING(ce->name, 0); + ADD_SIZE(zend_hash_persist_calc(&ce->function_table, zend_persist_op_array_calc TSRMLS_CC)); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (ce->default_properties_table) { int i; ADD_SIZE(sizeof(zval*) * ce->default_properties_count); for (i = 0; i < ce->default_properties_count; i++) { - if (ce->default_properties_table[i]) { - ADD_SIZE(zend_persist_zval_ptr_calc(&ce->default_properties_table[i] TSRMLS_CC)); - } + ADD_SIZE(zend_persist_zval_calc(&ce->default_properties_table[i] TSRMLS_CC)); } } if (ce->default_static_members_table) { @@ -280,25 +282,23 @@ static uint zend_persist_class_entry_calc(zend_class_entry **pce TSRMLS_DC) ADD_SIZE(sizeof(zval*) * ce->default_static_members_count); for (i = 0; i < ce->default_static_members_count; i++) { - if (ce->default_static_members_table[i]) { - ADD_SIZE(zend_persist_zval_ptr_calc(&ce->default_static_members_table[i] TSRMLS_CC)); - } + ADD_SIZE(zend_persist_zval_calc(&ce->default_static_members_table[i] TSRMLS_CC)); } } #else ADD_SIZE(zend_hash_persist_calc(&ce->default_properties, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); ADD_SIZE(zend_hash_persist_calc(&ce->default_static_members, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); #endif - ADD_SIZE(zend_hash_persist_calc(&ce->constants_table, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); + ADD_SIZE(zend_hash_persist_calc(&ce->constants_table, zend_persist_zval_calc TSRMLS_CC)); if (ZEND_CE_FILENAME(ce)) { - ADD_DUP_SIZE(ZEND_CE_FILENAME(ce), strlen(ZEND_CE_FILENAME(ce)) + 1); + ADD_STRING(ZEND_CE_FILENAME(ce)); } if (ZCG(accel_directives).save_comments && ZEND_CE_DOC_COMMENT(ce)) { - ADD_DUP_SIZE(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce) + 1); + ADD_STRING(ZEND_CE_DOC_COMMENT(ce)); } - ADD_SIZE(zend_hash_persist_calc(&ce->properties_info, (int (*)(void* TSRMLS_DC)) zend_persist_property_info_calc, sizeof(zend_property_info) TSRMLS_CC)); + ADD_SIZE(zend_hash_persist_calc(&ce->properties_info, zend_persist_property_info_calc TSRMLS_CC)); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (ce->trait_aliases) { @@ -306,16 +306,16 @@ static uint zend_persist_class_entry_calc(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) { - ADD_SIZE(ce->trait_aliases[i]->trait_method->mname_len + 1); + ADD_INTERNED_STRING(ce->trait_aliases[i]->trait_method->method_name, 0); } if (ce->trait_aliases[i]->trait_method->class_name) { - ADD_SIZE(ce->trait_aliases[i]->trait_method->cname_len + 1); + ADD_INTERNED_STRING(ce->trait_aliases[i]->trait_method->class_name, 0); } ADD_SIZE(sizeof(zend_trait_method_reference)); } if (ce->trait_aliases[i]->alias) { - ADD_SIZE(ce->trait_aliases[i]->alias_len + 1); + ADD_INTERNED_STRING(ce->trait_aliases[i]->alias, 0); } ADD_SIZE(sizeof(zend_trait_alias)); i++; @@ -327,15 +327,15 @@ static uint zend_persist_class_entry_calc(zend_class_entry **pce TSRMLS_DC) int i = 0; while (ce->trait_precedences[i]) { - ADD_SIZE(ce->trait_precedences[i]->trait_method->mname_len + 1); - ADD_SIZE(ce->trait_precedences[i]->trait_method->cname_len + 1); + ADD_INTERNED_STRING(ce->trait_precedences[i]->trait_method->method_name, 0); + ADD_INTERNED_STRING(ce->trait_precedences[i]->trait_method->class_name, 0); ADD_SIZE(sizeof(zend_trait_method_reference)); if (ce->trait_precedences[i]->exclude_from_classes) { int j = 0; - while (ce->trait_precedences[i]->exclude_from_classes[j]) { - ADD_SIZE(strlen((char*)ce->trait_precedences[i]->exclude_from_classes[j]) + 1); + while (ce->trait_precedences[i]->exclude_from_classes[j].class_name) { + ADD_INTERNED_STRING(ce->trait_precedences[i]->exclude_from_classes[j].class_name, 0); j++; } ADD_SIZE(sizeof(zend_class_entry*) * (j + 1)); @@ -352,18 +352,18 @@ static uint zend_persist_class_entry_calc(zend_class_entry **pce TSRMLS_DC) static uint zend_accel_persist_class_table_calc(HashTable *class_table TSRMLS_DC) { - return zend_hash_persist_calc(class_table, (int (*)(void* TSRMLS_DC)) zend_persist_class_entry_calc, sizeof(zend_class_entry*) TSRMLS_CC); + return zend_hash_persist_calc(class_table, zend_persist_class_entry_calc TSRMLS_CC); } uint zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, char *key, unsigned int key_length TSRMLS_DC) { START_SIZE(); - ADD_SIZE(zend_hash_persist_calc(&new_persistent_script->function_table, (int (*)(void* TSRMLS_DC)) zend_persist_op_array_calc, sizeof(zend_op_array) TSRMLS_CC)); + ADD_SIZE(zend_hash_persist_calc(&new_persistent_script->function_table, zend_persist_op_array_calc TSRMLS_CC)); ADD_SIZE(zend_accel_persist_class_table_calc(&new_persistent_script->class_table TSRMLS_CC)); - ADD_SIZE(zend_persist_op_array_calc(&new_persistent_script->main_op_array TSRMLS_CC)); + ADD_SIZE(zend_persist_op_array_calc_ex(&new_persistent_script->main_op_array TSRMLS_CC)); ADD_DUP_SIZE(key, key_length + 1); - ADD_DUP_SIZE(new_persistent_script->full_path, new_persistent_script->full_path_len + 1); + ADD_STRING(new_persistent_script->full_path); ADD_DUP_SIZE(new_persistent_script, sizeof(zend_persistent_script)); RETURN_SIZE(); diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index e1a570a3a0..061a4e2777 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -325,9 +325,9 @@ void *zend_shared_alloc(size_t size) int zend_shared_memdup_size(void *source, size_t size) { - void **old_p; + void *old_p; - if (zend_hash_index_find(&xlat_table, (ulong)source, (void **)&old_p) == SUCCESS) { + if ((old_p = zend_hash_index_find_ptr(&xlat_table, (ulong)source)) != NULL) { /* we already duplicated this pointer */ return 0; } @@ -337,17 +337,17 @@ int zend_shared_memdup_size(void *source, size_t size) void *_zend_shared_memdup(void *source, size_t size, zend_bool free_source TSRMLS_DC) { - void **old_p, *retval; + void *old_p, *retval; - if (zend_hash_index_find(&xlat_table, (ulong)source, (void **)&old_p) == SUCCESS) { + if ((old_p = zend_hash_index_find_ptr(&xlat_table, (ulong)source)) != NULL) { /* we already duplicated this pointer */ - return *old_p; + return old_p; } retval = ZCG(mem);; ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size)); memcpy(retval, source, size); if (free_source) { - interned_efree((char*)source); +//??? interned_efree((char*)source); } zend_shared_alloc_register_xlat_entry(source, retval); return retval; @@ -431,17 +431,17 @@ void zend_shared_alloc_clear_xlat_table(void) void zend_shared_alloc_register_xlat_entry(const void *old, const void *new) { - zend_hash_index_update(&xlat_table, (ulong)old, (void*)&new, sizeof(void *), NULL); + zend_hash_index_update_ptr(&xlat_table, (ulong)old, (void*)new); } void *zend_shared_alloc_get_xlat_entry(const void *old) { - void **retval; + void *retval; - if (zend_hash_index_find(&xlat_table, (ulong)old, (void **)&retval) == FAILURE) { + if ((retval = zend_hash_index_find_ptr(&xlat_table, (ulong)old)) == NULL) { return NULL; } - return *retval; + return retval; } size_t zend_shared_alloc_get_free_memory(void)