diff options
Diffstat (limited to 'ext/opcache/Optimizer/nop_removal.c')
-rw-r--r-- | ext/opcache/Optimizer/nop_removal.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/ext/opcache/Optimizer/nop_removal.c b/ext/opcache/Optimizer/nop_removal.c index 9983ff4f60..20510b4163 100644 --- a/ext/opcache/Optimizer/nop_removal.c +++ b/ext/opcache/Optimizer/nop_removal.c @@ -44,6 +44,14 @@ void zend_optimizer_nop_removal(zend_op_array *op_array) end = op_array->opcodes + op_array->last; for (opline = op_array->opcodes; opline < end; opline++) { + /* GOTO target is unresolved yet. We can't optimize. */ + if (opline->opcode == ZEND_GOTO && + Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) { + /* TODO: in general we can avoid this restriction */ + FREE_ALLOCA(shiftlist); + return; + } + /* Kill JMP-over-NOP-s */ if (opline->opcode == ZEND_JMP && ZEND_OP1(opline).opline_num > i) { /* check if there are only NOPs under the branch */ @@ -77,6 +85,7 @@ void zend_optimizer_nop_removal(zend_op_array *op_array) for (opline = op_array->opcodes; opline<end; opline++) { switch (opline->opcode) { case ZEND_JMP: + case ZEND_GOTO: case ZEND_FAST_CALL: case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS: @@ -108,6 +117,13 @@ void zend_optimizer_nop_removal(zend_op_array *op_array) } } + /* update brk/cont array */ + for (j = 0; j < op_array->last_brk_cont; j++) { + op_array->brk_cont_array[j].brk -= shiftlist[op_array->brk_cont_array[j].brk]; + op_array->brk_cont_array[j].cont -= shiftlist[op_array->brk_cont_array[j].cont]; + op_array->brk_cont_array[j].start -= shiftlist[op_array->brk_cont_array[j].start]; + } + /* update try/catch array */ for (j = 0; j < op_array->last_try_catch; j++) { op_array->try_catch_array[j].try_op -= shiftlist[op_array->try_catch_array[j].try_op]; |