diff options
Diffstat (limited to 'ext/opcache')
| -rw-r--r-- | ext/opcache/Optimizer/optimize_func_calls.c | 2 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/pass1_5.c | 209 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 8 | ||||
| -rw-r--r-- | ext/opcache/ZendAccelerator.c | 17 | ||||
| -rw-r--r-- | ext/opcache/ZendAccelerator.h | 1 | ||||
| -rw-r--r-- | ext/opcache/tests/bug68104.phpt | 19 | ||||
| -rw-r--r-- | ext/opcache/tests/bug68252.phpt | 20 | ||||
| -rw-r--r-- | ext/opcache/zend_accelerator_module.c | 2 |
8 files changed, 193 insertions, 85 deletions
diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index aa62a4542d..9031a38f56 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -143,8 +143,6 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) && call_stack[call - 1].func) { if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) { opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND | ZEND_ARG_SEND_BY_REF; - } else if (opline->extended_value) { - opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND; } else { opline->opcode = ZEND_SEND_VAR; opline->extended_value = 0; diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index b91ac5b50f..15bca2adf8 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -341,28 +341,75 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML } break; - case ZEND_INIT_FCALL: + case ZEND_DO_FCALL: { + zend_op *send1_opline = opline - 1; + zend_op *send2_opline = NULL; + zend_op *init_opline = NULL; + + while (send1_opline->opcode == ZEND_NOP) { + send1_opline--; + } + if (send1_opline->opcode != ZEND_SEND_VAL || + ZEND_OP1_TYPE(send1_opline) != IS_CONST) { + /* don't colllect constants after unknown function call */ + collect_constants = 0; + break; + } + if (send1_opline->op2.num == 2) { + send2_opline = send1_opline; + send1_opline--; + while (send1_opline->opcode == ZEND_NOP) { + send1_opline--; + } + if (send1_opline->opcode != ZEND_SEND_VAL || + ZEND_OP1_TYPE(send1_opline) != IS_CONST) { + /* don't colllect constants after unknown function call */ + collect_constants = 0; + break; + } + } + init_opline = send1_opline - 1; + while (init_opline->opcode == ZEND_NOP) { + init_opline--; + } + if (init_opline->opcode != ZEND_INIT_FCALL || + ZEND_OP2_TYPE(init_opline) != IS_CONST || + Z_TYPE(ZEND_OP2_LITERAL(init_opline)) != IS_STRING) { + /* don't colllect constants after unknown function call */ + collect_constants = 0; + break; + } + /* define("name", scalar); */ - if (collect_constants && - ZEND_OP2_TYPE(opline) == IS_CONST && - Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING && - Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("define")-1 && - zend_binary_strcasecmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), "define", sizeof("define")-1) == 0) { + if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("define")-1 && + zend_binary_strcasecmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), Z_STRLEN(ZEND_OP2_LITERAL(init_opline)), "define", sizeof("define")-1) == 0) { - if ((opline+1)->opcode == ZEND_SEND_VAL && - ZEND_OP1_TYPE(opline+1) == IS_CONST && - Z_TYPE(ZEND_OP1_LITERAL(opline+1)) == IS_STRING && - (opline+2)->opcode == ZEND_SEND_VAL && - ZEND_OP1_TYPE(opline+2) == IS_CONST && - Z_TYPE(ZEND_OP1_LITERAL(opline+2)) <= IS_STRING && - (opline+3)->opcode == ZEND_DO_FCALL) { - - zend_optimizer_collect_constant(ctx, &ZEND_OP1_LITERAL(opline+1), &ZEND_OP1_LITERAL(opline+2)); + if (Z_TYPE(ZEND_OP1_LITERAL(send1_opline)) == IS_STRING && + send2_opline && + Z_TYPE(ZEND_OP1_LITERAL(send2_opline)) <= IS_STRING) { + + if (collect_constants) { + zend_optimizer_collect_constant(ctx, &ZEND_OP1_LITERAL(send1_opline), &ZEND_OP1_LITERAL(send2_opline)); + } + + if (RESULT_UNUSED(opline) && + !zend_memnstr(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), "::", sizeof("::") - 1, Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)) + Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)))) { + + opline->opcode = ZEND_DECLARE_CONST; + opline->op1_type = IS_CONST; + opline->op2_type = IS_CONST; + opline->result_type = IS_UNUSED; + opline->op1.constant = send1_opline->op1.constant; + opline->op2.constant = send2_opline->op1.constant; + opline->result.zv = NULL; + + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + MAKE_NOP(send1_opline); + MAKE_NOP(send2_opline); + } break; } - } else { - /* don't colllect constants after any other function call */ - collect_constants = 0; } /* pre-evaluate constant functions: @@ -372,42 +419,42 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML is_callable(x) extension_loaded(x) */ - if ((opline + 1)->opcode == ZEND_SEND_VAL && - (opline + 2)->opcode == ZEND_DO_FCALL && - ZEND_OP1_TYPE(opline + 1) == IS_CONST && Z_TYPE(ZEND_OP1_LITERAL(opline + 1)) == IS_STRING && - ZEND_OP2_TYPE(opline) == IS_CONST && Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { - if ((Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("function_exists")-1 && - !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), + if (!send2_opline && + Z_TYPE(ZEND_OP1_LITERAL(send1_opline)) == IS_STRING) { + if ((Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("function_exists")-1 && + !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "function_exists", sizeof("function_exists")-1)) || - (Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("is_callable")-1 && - !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), + (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("is_callable")-1 && + !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "is_callable", sizeof("is_callable")))) { zend_internal_function *func; char *lc_name = zend_str_tolower_dup( - Z_STRVAL(ZEND_OP1_LITERAL(opline + 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline + 1))); + Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline))); - if ((func = zend_hash_str_find_ptr(EG(function_table), lc_name, Z_STRLEN(ZEND_OP1_LITERAL(opline + 1)))) != NULL && + if ((func = zend_hash_str_find_ptr(EG(function_table), lc_name, Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)))) != NULL && func->type == ZEND_INTERNAL_FUNCTION && func->module->type == MODULE_PERSISTENT) { zval t; ZVAL_BOOL(&t, 1); - if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { - literal_dtor(&ZEND_OP2_LITERAL(opline)); + if (zend_optimizer_replace_by_const(op_array, opline + 1, IS_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); + MAKE_NOP(send1_opline); MAKE_NOP(opline); - literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); - MAKE_NOP(opline + 1); - MAKE_NOP(opline + 2); + efree(lc_name); + break; } } efree(lc_name); - } else if (Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("extension_loaded")-1 && - !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), + } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("extension_loaded")-1 && + !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "extension_loaded", sizeof("extension_loaded")-1)) { zval t; char *lc_name = zend_str_tolower_dup( - Z_STRVAL(ZEND_OP1_LITERAL(opline + 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline + 1))); + Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline))); zend_module_entry *m = zend_hash_str_find_ptr(&module_registry, - lc_name, Z_STRLEN(ZEND_OP1_LITERAL(opline + 1))); + lc_name, Z_STRLEN(ZEND_OP1_LITERAL(send1_opline))); efree(lc_name); if (!m) { @@ -424,60 +471,89 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML } } - if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { - literal_dtor(&ZEND_OP2_LITERAL(opline)); + if (zend_optimizer_replace_by_const(op_array, opline + 1, IS_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); + MAKE_NOP(send1_opline); MAKE_NOP(opline); - literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); - MAKE_NOP(opline + 1); - MAKE_NOP(opline + 2); + break; } - } else if (Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("defined")-1 && - !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), + } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("defined")-1 && + !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "defined", sizeof("defined")-1)) { zval t; - if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 0 TSRMLS_CC)) { + if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(send1_opline)), &t, 0 TSRMLS_CC)) { ZVAL_BOOL(&t, 1); - if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { - literal_dtor(&ZEND_OP2_LITERAL(opline)); + if (zend_optimizer_replace_by_const(op_array, opline + 1, IS_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); + MAKE_NOP(send1_opline); MAKE_NOP(opline); - literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); - MAKE_NOP(opline + 1); - MAKE_NOP(opline + 2); + break; } } - } else if (Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("constant")-1 && - !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), + } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("constant")-1 && + !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "constant", sizeof("constant")-1)) { zval t; - if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 1 TSRMLS_CC)) { - if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { - literal_dtor(&ZEND_OP2_LITERAL(opline)); + if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(send1_opline)), &t, 1 TSRMLS_CC)) { + if (zend_optimizer_replace_by_const(op_array, opline + 1, IS_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); + MAKE_NOP(send1_opline); MAKE_NOP(opline); - literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); - MAKE_NOP(opline + 1); - MAKE_NOP(opline + 2); + break; } } } else if ((CG(compiler_options) & ZEND_COMPILE_NO_BUILTIN_STRLEN) == 0 && - Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("strlen")-1 && - !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), + Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("strlen")-1 && + !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "strlen", sizeof("strlen")-1)) { zval t; - ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline + 1))); - if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { - literal_dtor(&ZEND_OP2_LITERAL(opline)); + ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(send1_opline))); + if (zend_optimizer_replace_by_const(op_array, opline + 1, IS_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); + MAKE_NOP(send1_opline); MAKE_NOP(opline); - literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); - MAKE_NOP(opline + 1); - MAKE_NOP(opline + 2); + break; + } + /* dirname(IS_CONST/IS_STRING) -> IS_CONST/IS_STRING */ + } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("dirname")-1 && + !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), + "dirname", sizeof("dirname")-1) && + IS_ABSOLUTE_PATH(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)))) { + zend_string *dirname = zend_string_init(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)), 0); + dirname->len = zend_dirname(dirname->val, dirname->len); + if (IS_ABSOLUTE_PATH(dirname->val, dirname->len)) { + zval t; + + ZVAL_STR(&t, dirname); + if (zend_optimizer_replace_by_const(op_array, opline + 1, IS_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); + MAKE_NOP(send1_opline); + MAKE_NOP(opline); + break; + } + } else { + zend_string_release(dirname); } } } + /* don't colllect constants after any other function call */ + collect_constants = 0; break; + } case ZEND_STRLEN: if (ZEND_OP1_TYPE(opline) == IS_CONST && Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING) { @@ -530,7 +606,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML case ZEND_FE_RESET: case ZEND_FE_FETCH: case ZEND_NEW: - case ZEND_DO_FCALL: case ZEND_JMP_SET: case ZEND_COALESCE: collect_constants = 0; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 1a6d0b675a..589028368f 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -283,6 +283,14 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array, case ZEND_ASSIGN_DIM: case ZEND_SEPARATE: return 0; + case ZEND_SEND_VAR: + opline->extended_value = 0; + opline->opcode = ZEND_SEND_VAL; + break; + case ZEND_SEND_VAR_EX: + opline->extended_value = 0; + opline->opcode = ZEND_SEND_VAL_EX; + break; case ZEND_SEND_VAR_NO_REF: if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { if (opline->extended_value & ZEND_ARG_SEND_BY_REF) { diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 6f37146a91..42117ae1b7 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -878,12 +878,12 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle TSRMLS_DC) { if (ZCG(accel_directives).revalidate_freq && - (persistent_script->dynamic_members.revalidate >= ZCSG(revalidate_at))) { + persistent_script->dynamic_members.revalidate >= ZCG(request_time)) { return SUCCESS; } else if (do_validate_timestamps(persistent_script, file_handle TSRMLS_CC) == FAILURE) { return FAILURE; } else { - persistent_script->dynamic_members.revalidate = ZCSG(revalidate_at); + persistent_script->dynamic_members.revalidate = ZCG(request_time) + ZCG(accel_directives).revalidate_freq; return SUCCESS; } } @@ -1424,7 +1424,7 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han * otherwise we have a race-condition. */ new_persistent_script->timestamp = timestamp; - new_persistent_script->dynamic_members.revalidate = ZCSG(revalidate_at); + new_persistent_script->dynamic_members.revalidate = ZCG(request_time) + ZCG(accel_directives).revalidate_freq; } if (file_handle->opened_path) { @@ -1894,13 +1894,6 @@ static void accel_activate(void) zend_accel_error(ACCEL_LOG_WARNING, "Internal functions count changed - was %d, now %d", ZCG(internal_functions_count), zend_hash_num_elements(&ZCG(function_table))); } - if (ZCG(accel_directives).validate_timestamps) { - time_t now = ZCG(request_time); - if (now > ZCSG(revalidate_at) + (time_t)ZCG(accel_directives).revalidate_freq) { - ZCSG(revalidate_at) = now; - } - } - ZCG(cwd) = NULL; SHM_PROTECT(); @@ -2353,10 +2346,6 @@ static int accel_startup(zend_extension *extension) accelerator_orig_zend_resolve_path = zend_resolve_path; zend_resolve_path = persistent_zend_resolve_path; - if (ZCG(accel_directives).validate_timestamps) { - ZCSG(revalidate_at) = zend_accel_get_time() + ZCG(accel_directives).revalidate_freq; - } - /* Override chdir() function */ if ((func = zend_hash_str_find_ptr(CG(function_table), "chdir", sizeof("chdir")-1)) != NULL && func->type == ZEND_INTERNAL_FUNCTION) { diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 066c957e9f..119148aa27 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -270,7 +270,6 @@ typedef struct _zend_accel_shared_globals { LONGLONG restart_in; #endif zend_bool restart_in_progress; - time_t revalidate_at; /* Interned Strings Support */ char *interned_strings_start; char *interned_strings_top; diff --git a/ext/opcache/tests/bug68104.phpt b/ext/opcache/tests/bug68104.phpt new file mode 100644 index 0000000000..8d3bf70a4d --- /dev/null +++ b/ext/opcache/tests/bug68104.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #68104 (Segfault while pre-evaluating a disabled function) +--CREDITS-- +manuel <manuel@mausz.at> +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +disable_functions=dl +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +var_dump(is_callable("dl")); +dl("a.so"); +?> +--EXPECTF-- +bool(true) + +Warning: dl() has been disabled for security reasons in %sbug68104.php on line %d diff --git a/ext/opcache/tests/bug68252.phpt b/ext/opcache/tests/bug68252.phpt new file mode 100644 index 0000000000..e05467a244 --- /dev/null +++ b/ext/opcache/tests/bug68252.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #68252 (segfault in Zend/zend_hash.c in function _zend_hash_del_el) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.fast_shutdown=1 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +/* run this test script with valgrind */ +function a() { + echo "okey"; +} + +create_function('', 'var_dump("22");'); + +a(); +--EXPECT-- +okey diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 001c3ee9ed..fcaf96408c 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -499,7 +499,7 @@ static int accelerator_get_scripts(zval *return_value TSRMLS_DC) timerclear(&exec_time); timerclear(&fetch_time); - zend_hash_str_update(Z_ARRVAL_P(return_value), cache_entry->key, cache_entry->key_length-1, &persistent_script_report); + zend_hash_str_update(Z_ARRVAL_P(return_value), cache_entry->key, cache_entry->key_length, &persistent_script_report); } } accelerator_shm_read_unlock(TSRMLS_C); |
