summaryrefslogtreecommitdiff
path: root/ext/opcache
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-02-16 21:25:49 +0100
committerNikita Popov <nikita.ppv@gmail.com>2018-02-16 21:30:48 +0100
commitb0af9ac7331e3efa0dcee4f43b2ba8b1e4e52f2f (patch)
tree5b40edba9eee94ab22fe494ce0c919b3ffdfebe4 /ext/opcache
parent07ad75ca9603b8b0195ddcd90229ae9dbe650900 (diff)
downloadphp-git-b0af9ac7331e3efa0dcee4f43b2ba8b1e4e52f2f.tar.gz
Avoid live range references in opcodes
Don't store the live range of the freed variable for FREE_ON_RETURN frees, instead look it up at runtime. As this is an extremely unlikely codepath (in particular, it requires a loop variable with a throwing destructor), saving the runtime lookup of the live range is not worth the extra complexity this adds everywhere else.
Diffstat (limited to 'ext/opcache')
-rw-r--r--ext/opcache/Optimizer/block_pass.c24
-rw-r--r--ext/opcache/Optimizer/zend_dump.c4
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c20
3 files changed, 4 insertions, 44 deletions
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 97e44fe0b2..b402cce276 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -347,10 +347,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
src->opcode != ZEND_FETCH_DIM_R &&
src->opcode != ZEND_FETCH_OBJ_R &&
src->opcode != ZEND_NEW) {
- if (opline->extended_value & ZEND_FREE_ON_RETURN) {
- /* mark as removed (empty live range) */
- op_array->live_range[opline->op2.num].var = (uint32_t)-1;
- }
src->result_type = IS_UNUSED;
MAKE_NOP(opline);
}
@@ -1040,10 +1036,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
/* adjust loop jump targets & remove unused live range entries */
if (op_array->last_live_range) {
int i, j;
- uint32_t *map;
- ALLOCA_FLAG(use_heap);
-
- map = (uint32_t *)do_alloca(sizeof(uint32_t) * op_array->last_live_range, use_heap);
for (i = 0, j = 0; i < op_array->last_live_range; i++) {
if (op_array->live_range[i].var == (uint32_t)-1) {
@@ -1062,7 +1054,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
}
op_array->live_range[i].start = start_op;
op_array->live_range[i].end = end_op;
- map[i] = j;
if (i != j) {
op_array->live_range[j] = op_array->live_range[i];
}
@@ -1071,23 +1062,12 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
}
if (i != j) {
- if ((op_array->last_live_range = j)) {
- zend_op *opline = new_opcodes;
- zend_op *end = opline + len;
- while (opline != end) {
- if ((opline->opcode == ZEND_FREE || opline->opcode == ZEND_FE_FREE) &&
- opline->extended_value == ZEND_FREE_ON_RETURN) {
- ZEND_ASSERT(opline->op2.num < (uint32_t) i);
- opline->op2.num = map[opline->op2.num];
- }
- opline++;
- }
- } else {
+ op_array->last_live_range = j;
+ if (j == 0) {
efree(op_array->live_range);
op_array->live_range = NULL;
}
}
- free_alloca(map, use_heap);
}
/* adjust early binding list */
diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c
index 7fb55355fd..e4516b59cc 100644
--- a/ext/opcache/Optimizer/zend_dump.c
+++ b/ext/opcache/Optimizer/zend_dump.c
@@ -118,10 +118,6 @@ static void zend_dump_unused_op(const zend_op *opline, znode_op op, uint32_t fla
if (op.num != (uint32_t)-1) {
fprintf(stderr, " try-catch(%u)", op.num);
}
- } else if (ZEND_VM_OP_LIVE_RANGE == (flags & ZEND_VM_OP_MASK)) {
- if (opline->extended_value & ZEND_FREE_ON_RETURN) {
- fprintf(stderr, " live-range(%u)", op.num);
- }
} else if (ZEND_VM_OP_THIS == (flags & ZEND_VM_OP_MASK)) {
fprintf(stderr, " THIS");
} else if (ZEND_VM_OP_NEXT == (flags & ZEND_VM_OP_MASK)) {
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 07860f3998..ffc04854e2 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -566,14 +566,9 @@ void zend_optimizer_remove_live_range(zend_op_array *op_array, uint32_t var)
if (op_array->last_live_range) {
int i = 0;
int j = 0;
- uint32_t *map;
- ALLOCA_FLAG(use_heap);
-
- map = (uint32_t *)do_alloca(sizeof(uint32_t) * op_array->last_live_range, use_heap);
do {
if ((op_array->live_range[i].var & ~ZEND_LIVE_MASK) != var) {
- map[i] = j;
if (i != j) {
op_array->live_range[j] = op_array->live_range[i];
}
@@ -582,23 +577,12 @@ void zend_optimizer_remove_live_range(zend_op_array *op_array, uint32_t var)
i++;
} while (i < op_array->last_live_range);
if (i != j) {
- if ((op_array->last_live_range = j)) {
- zend_op *opline = op_array->opcodes;
- zend_op *end = opline + op_array->last;
-
- while (opline != end) {
- if ((opline->opcode == ZEND_FREE || opline->opcode == ZEND_FE_FREE) &&
- opline->extended_value == ZEND_FREE_ON_RETURN) {
- opline->op2.num = map[opline->op2.num];
- }
- opline++;
- }
- } else {
+ op_array->last_live_range = j;
+ if (j == 0) {
efree(op_array->live_range);
op_array->live_range = NULL;
}
}
- free_alloca(map, use_heap);
}
}