summaryrefslogtreecommitdiff
path: root/ext/opcache
diff options
context:
space:
mode:
Diffstat (limited to 'ext/opcache')
-rw-r--r--ext/opcache/Optimizer/block_pass.c86
1 files changed, 47 insertions, 39 deletions
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index b8c381406b..7f874e7a4b 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -558,6 +558,52 @@ static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int
convert_to_string((v)); \
}
+static void strip_nop(zend_code_block *block)
+{
+ zend_op *opline = block->start_opline;
+ zend_op *end, *new_end;
+ int new_len = 0;
+
+ /* remove leading NOPs */
+ while (block->len > 0 && block->start_opline->opcode == ZEND_NOP) {
+ if (block->len == 1) {
+ /* this block is all NOPs, join with following block */
+ if (block->follow_to) {
+ delete_code_block(block);
+ }
+ return;
+ }
+ block->start_opline++;
+ block->start_opline_no++;
+ block->len--;
+ }
+
+ /* strip the inside NOPs */
+ opline = new_end = block->start_opline;
+ end = opline + block->len;
+
+ while (opline < end) {
+ zend_op *src;
+ int len = 0;
+
+ while (opline < end && opline->opcode == ZEND_NOP) {
+ opline++;
+ }
+ src = opline;
+
+ while (opline < end && opline->opcode != ZEND_NOP) {
+ opline++;
+ }
+ len = opline - src;
+
+ /* move up non-NOP opcodes */
+ memmove(new_end, src, len*sizeof(zend_op));
+
+ new_end += len;
+ }
+ block->len = new_end - block->start_opline;
+}
+
static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, char *used_ext TSRMLS_DC)
{
zend_op *opline = block->start_opline;
@@ -1168,45 +1214,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
opline++;
}
- /* remove leading NOPs */
- while (block->len > 0 && block->start_opline->opcode == ZEND_NOP) {
- if (block->len == 1) {
- /* this block is all NOPs, join with following block */
- if (block->follow_to) {
- delete_code_block(block);
- }
- if (op_array->T) {
- efree(Tsource);
- }
- return;
- }
- block->start_opline++;
- block->start_opline_no++;
- block->len--;
- }
-
- /* strip the inside NOPs */
- opline = block->start_opline;
- end = opline + block->len;
- while (opline < end) {
- if (opline->opcode == ZEND_NOP) {
- zend_op *nop = opline + 1;
- int noplen;
- while (nop < end && nop->opcode == ZEND_NOP) {
- nop++;
- }
- noplen = nop-opline;
- if (nop < end) {
- /* move up non-NOP opcodes */
- memmove(opline, nop, (end-nop)*sizeof(zend_op));
- } else {
- /* all NOPs up to the end, do nothing */
- }
- block->len -= noplen;
- end = block->start_opline + block->len;
- }
- opline++;
- }
+ strip_nop(block);
if (op_array->T) {
efree(Tsource);