From: Dmitry Stogov Date: Wed, 1 Jul 2015 23:00:34 +0000 (+0300) Subject: Fixed memory leak because of incorrect 'if ();' optimization X-Git-Tag: php-7.1.0alpha3~25^2~70 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fa1abb567798fb50a2d84e82021b79909c6aefba;p=php Fixed memory leak because of incorrect 'if ();' optimization --- diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index a810829628..ee9bda6094 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -1403,6 +1403,34 @@ static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_arra break; } + if (block->op2_to == block->follow_to) { + /* L: JMPZ(X, L+1) -> NOP or FREE(X) */ + + if (last_op->op1_type == IS_VAR) { + zend_op **Tsource = cfg->Tsource; + zend_op *src = VAR_SOURCE(last_op->op1); + + if (src && + src->opcode != ZEND_FETCH_R && + src->opcode != ZEND_FETCH_DIM_R && + src->opcode != ZEND_FETCH_OBJ_R) { + ZEND_RESULT_TYPE(src) |= EXT_TYPE_UNUSED; + MAKE_NOP(last_op); + block->op2_to = NULL; + break; + } + } + if (last_op->op1_type & (IS_VAR|IS_TMP_VAR)) { + last_op->opcode = ZEND_FREE; + last_op->op2.num = 0; + block->op2_to = NULL; + } else { + MAKE_NOP(last_op); + block->op2_to = NULL; + } + break; + } + if (block->op2_to) { zend_uchar same_type = ZEND_OP1_TYPE(last_op); uint32_t same_var = VAR_NUM_EX(last_op->op1); diff --git a/ext/opcache/Optimizer/pass3.c b/ext/opcache/Optimizer/pass3.c index cb717998d6..3e589df628 100644 --- a/ext/opcache/Optimizer/pass3.c +++ b/ext/opcache/Optimizer/pass3.c @@ -202,12 +202,6 @@ void zend_optimizer_pass3(zend_op_array *op_array) break; } - /* convert L: JMPZ L+1 to NOP */ - if (ZEND_OP2(opline).opline_num == opline_num + 1) { - MAKE_NOP(opline); - goto done_jmp_optimization; - } - while (ZEND_OP2(opline).opline_num < op_array->last) { int target = ZEND_OP2(opline).opline_num; diff --git a/ext/opcache/tests/leak_001.phpt b/ext/opcache/tests/leak_001.phpt new file mode 100644 index 0000000000..c590943fcb --- /dev/null +++ b/ext/opcache/tests/leak_001.phpt @@ -0,0 +1,34 @@ +--TEST-- +Leak 001: Incorrect 'if ();' optimization +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache_only=0 +--SKIPIF-- + +--FILE-- + +OK +--EXPECT-- +OK