From 187f42149d8c06d191a64e789bf4162a9c76e34c Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 18 Apr 2017 12:47:53 +0800 Subject: [PATCH] Improve fix for #74456 --- ext/opcache/Optimizer/block_pass.c | 2 +- ext/opcache/Optimizer/zend_optimizer.c | 32 +++++++++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 7f249130d8..03e157e9c8 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -186,7 +186,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array COPY_NODE(opline->op1, src->op1); VAR_SOURCE(op1) = NULL; MAKE_NOP(src); - } else if (opline->opcode != ZEND_FETCH_LIST && opline->opcode != ZEND_CASE) { + } else { zval c = ZEND_OP1_LITERAL(src); zval_copy_ctor(&c); if (zend_optimizer_update_op1_const(op_array, opline, &c)) { diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 241f594728..c8524f6995 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -165,6 +165,10 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, * zend_optimizer_replace_by_const() supports this. */ zval_ptr_dtor(val); return 0; + case ZEND_CASE: + case ZEND_FETCH_LIST: + zval_ptr_dtor(val); + return 0; case ZEND_CONCAT: case ZEND_FAST_CONCAT: case ZEND_FETCH_R: @@ -417,16 +421,27 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array, */ case ZEND_FETCH_LIST: { zend_op *m = opline; + + if (Z_TYPE_P(val) == IS_STRING) { + zend_string_hash_val(Z_STR_P(val)); + } + do { if (m->opcode == ZEND_FETCH_LIST && ZEND_OP1_TYPE(m) == type && ZEND_OP1(m).var == var) { - zend_optimizer_update_op1_const(op_array, m, val); + zval v; + ZVAL_COPY_VALUE(&v, val); + zval_copy_ctor(&v); + ZEND_OP1(m).constant = zend_optimizer_add_literal(op_array, &v); + ZEND_OP1_TYPE(m) = IS_CONST; } m++; } while (m->opcode != ZEND_FREE || ZEND_OP1_TYPE(m) != type || ZEND_OP1(m).var != var); + ZEND_ASSERT(m->opcode == ZEND_FREE && ZEND_OP1_TYPE(m) == type && ZEND_OP1(m).var == var); MAKE_NOP(m); + zval_dtor(val); zend_optimizer_remove_live_range(op_array, var); return 1; } @@ -460,17 +475,22 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array, } else { n = op_array->opcodes + op_array->last; } + + if (Z_TYPE_P(val) == IS_STRING) { + zend_string_hash_val(Z_STR_P(val)); + } + while (m < n) { if (ZEND_OP1_TYPE(m) == type && ZEND_OP1(m).var == var) { if (m->opcode == ZEND_CASE || m->opcode == ZEND_SWITCH_LONG || m->opcode == ZEND_SWITCH_STRING) { - zval old_val; - ZVAL_COPY_VALUE(&old_val, val); - zval_copy_ctor(val); - zend_optimizer_update_op1_const(op_array, m, val); - ZVAL_COPY_VALUE(val, &old_val); + zval v; + ZVAL_COPY_VALUE(&v, val); + zval_copy_ctor(&v); + ZEND_OP1(m).constant = zend_optimizer_add_literal(op_array, &v); + ZEND_OP1_TYPE(m) = IS_CONST; } else if (m->opcode == ZEND_FREE) { MAKE_NOP(m); } else { -- 2.50.1