]> granicus.if.org Git - php/commitdiff
Use do_alloca() instead of alloca()
authorDmitry Stogov <dmitry@zend.com>
Wed, 16 Dec 2015 01:59:05 +0000 (04:59 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 16 Dec 2015 01:59:05 +0000 (04:59 +0300)
ext/opcache/Optimizer/zend_call_graph.c
ext/opcache/Optimizer/zend_cfg.c
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_ssa.c
ext/opcache/Optimizer/zend_worklist.h

index 86db61352d0bc8b5febf7284255b07e74f01648f..2d163c5ae133a572c3a6230a116102c33b48b3e4 100644 (file)
@@ -142,8 +142,10 @@ static int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t
        zend_function *func;
        zend_call_info *call_info;
        int call = 0;
-       zend_call_info **call_stack = alloca((op_array->last / 2) * sizeof(zend_call_info*));
+       zend_call_info **call_stack;
+       ALLOCA_FLAG(use_heap);
 
+       call_stack = do_alloca((op_array->last / 2) * sizeof(zend_call_info*), use_heap);
        while (opline != end) {
                call_info = NULL;
                switch (opline->opcode) {
@@ -199,6 +201,7 @@ static int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t
                }
                opline++;
        }
+       free_alloca(call_stack, use_heap);
        return SUCCESS;
 }
 
index 7818836d44b1231ac2c3bf6d8a1ad9c934066fa3..c7399316842e6f4ed398c68fcbb05026524440ae 100644 (file)
@@ -703,9 +703,11 @@ int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg, uint32
        int *dj_spanning_tree;
        zend_worklist work;
        int flag = ZEND_FUNC_NO_LOOPS;
+       ALLOCA_FLAG(list_use_heap);
+       ALLOCA_FLAG(tree_use_heap);
 
-       ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count);
-       dj_spanning_tree = alloca(sizeof(int) * cfg->blocks_count);
+       ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count, list_use_heap);
+       dj_spanning_tree = do_alloca(sizeof(int) * cfg->blocks_count, tree_use_heap);
 
        for (i = 0; i < cfg->blocks_count; i++) {
                dj_spanning_tree[i] = -1;
@@ -794,6 +796,8 @@ int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg, uint32
                }
        }
 
+       free_alloca(dj_spanning_tree, tree_use_heap);
+       ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap);
        *flags |= flag;
 
        return SUCCESS;
index 25b7eb9275373b4c2b87218998ff0e57cf7e5e31..438757107552822888638351e875e0caa3b14857 100644 (file)
@@ -158,11 +158,14 @@ int zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa) /* {{{ */
        int index = 0, *dfs, *root;
        zend_worklist_stack stack;
        int j;
+       ALLOCA_FLAG(dfs_use_heap);
+       ALLOCA_FLAG(root_use_heap);
+       ALLOCA_FLAG(stack_use_heap);
 
-       dfs = alloca(sizeof(int) * ssa->vars_count);
+       dfs = do_alloca(sizeof(int) * ssa->vars_count, dfs_use_heap);
        memset(dfs, -1, sizeof(int) * ssa->vars_count);
-       root = alloca(sizeof(int) * ssa->vars_count);
-       ZEND_WORKLIST_STACK_ALLOCA(&stack, ssa->vars_count);
+       root = do_alloca(sizeof(int) * ssa->vars_count, root_use_heap);
+       ZEND_WORKLIST_STACK_ALLOCA(&stack, ssa->vars_count, stack_use_heap);
 
        /* Find SCCs */
        for (j = 0; j < ssa->vars_count; j++) {
@@ -188,6 +191,10 @@ int zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa) /* {{{ */
                }
        }
 
+       ZEND_WORKLIST_STACK_FREE_ALLOCA(&stack, stack_use_heap);
+       free_alloca(root, root_use_heap);
+       free_alloca(dfs, dfs_use_heap);
+
        return SUCCESS;
 }
 /* }}} */
@@ -200,11 +207,13 @@ int zend_ssa_find_false_dependencies(const zend_op_array *op_array, zend_ssa *ss
        zend_bitset worklist;
        int i, j, use;
        zend_ssa_phi *p;
+       ALLOCA_FLAG(use_heap);
 
-       if (!op_array->function_name || !ssa->vars || !ssa->ops)
+       if (!op_array->function_name || !ssa->vars || !ssa->ops) {
                return SUCCESS;
+       }
 
-       worklist = alloca(sizeof(zend_ulong) * zend_bitset_len(ssa_vars_count));
+       worklist = do_alloca(sizeof(zend_ulong) * zend_bitset_len(ssa_vars_count), use_heap);
        memset(worklist, 0, sizeof(zend_ulong) * zend_bitset_len(ssa_vars_count));
 
        for (i = 0; i < ssa_vars_count; i++) {
@@ -243,6 +252,8 @@ int zend_ssa_find_false_dependencies(const zend_op_array *op_array, zend_ssa *ss
                }
        }
 
+       free_alloca(worklist, use_heap);
+
        return SUCCESS;
 }
 /* }}} */
@@ -1757,13 +1768,16 @@ static int zend_check_inner_cycles(const zend_op_array *op_array, zend_ssa *ssa,
 static void zend_infer_ranges_warmup(const zend_op_array *op_array, zend_ssa *ssa, int *scc_var, int *next_scc_var, int scc)
 {
        int worklist_len = zend_bitset_len(ssa->vars_count);
-       zend_bitset worklist = alloca(sizeof(zend_ulong) * worklist_len);
-       zend_bitset visited = alloca(sizeof(zend_ulong) * worklist_len);
+       zend_bitset worklist;
+       zend_bitset visited;
        int j, n;
        zend_ssa_range tmp;
 #ifdef NEG_RANGE
        int has_inner_cycles = 0;
+       ALLOCA_FLAG(use_heap);
 
+       worklist = do_alloca(sizeof(zend_ulong) * worklist_len * 2, use_heap);
+       visited = worklist + worklist_len;
        memset(worklist, 0, sizeof(zend_ulong) * worklist_len);
        memset(visited, 0, sizeof(zend_ulong) * worklist_len);
        j= scc_var[scc];
@@ -1860,17 +1874,26 @@ static void zend_infer_ranges_warmup(const zend_op_array *op_array, zend_ssa *ss
                        }
                }
        }
+       free_alloca(worklist, use_heap);
 }
 
 static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{{ */
 {
        int worklist_len = zend_bitset_len(ssa->vars_count);
-       zend_bitset worklist = alloca(sizeof(zend_ulong) * worklist_len);
-       int *next_scc_var = alloca(sizeof(int) * ssa->vars_count);
-       int *scc_var = alloca(sizeof(int) * ssa->sccs);
+       zend_bitset worklist;
+       int *next_scc_var;
+       int *scc_var;
        zend_ssa_phi *p;
        zend_ssa_range tmp;
        int scc, j;
+       ALLOCA_FLAG(use_heap);
+
+       worklist = do_alloca(
+               sizeof(zend_ulong) * worklist_len +
+               sizeof(int) * ssa->vars_count +
+               sizeof(int) * ssa->sccs, use_heap);
+       next_scc_var = (int*)(worklist + worklist_len);
+       scc_var = next_scc_var + ssa->vars_count;
 
 #ifdef LOG_SSA_RANGE
        fprintf(stderr, "Range Inference\n");
@@ -1949,6 +1972,8 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
                }
        }
 
+       free_alloca(worklist, use_heap);
+
        return SUCCESS;
 }
 /* }}} */
@@ -3655,10 +3680,11 @@ static int zend_type_narrowing(const zend_op_array *op_array, const zend_script
        int ssa_vars_count = ssa->vars_count;
        int j;
        zend_bitset worklist, types;
+       ALLOCA_FLAG(use_heap);
 
-       types = alloca(sizeof(zend_ulong) * op_array->last_var);
+       types = do_alloca(sizeof(zend_ulong) * (op_array->last_var + zend_bitset_len(ssa_vars_count)), use_heap);
        memset(types, 0, sizeof(zend_ulong) * op_array->last_var);
-       worklist = alloca(sizeof(zend_ulong) * zend_bitset_len(ssa_vars_count));
+       worklist = types + op_array->last_var;
        memset(worklist, 0, sizeof(zend_ulong) * zend_bitset_len(ssa_vars_count));
 
        /* Find variables that may be only LONG or DOUBLE */
@@ -3673,6 +3699,7 @@ static int zend_type_narrowing(const zend_op_array *op_array, const zend_script
                }
        }
        if (zend_bitset_empty(worklist, zend_bitset_len(ssa_vars_count))) {
+               free_alloca(types, use_heap);
                return SUCCESS;
        }
 
@@ -3694,6 +3721,7 @@ static int zend_type_narrowing(const zend_op_array *op_array, const zend_script
                }
        }
        if (zend_bitset_empty(worklist, zend_bitset_len(ssa_vars_count))) {
+               free_alloca(types, use_heap);
                return SUCCESS;
        }
 
@@ -3708,6 +3736,7 @@ static int zend_type_narrowing(const zend_op_array *op_array, const zend_script
                }
        }
        if (zend_bitset_empty(worklist, zend_bitset_len(ssa_vars_count))) {
+               free_alloca(types, use_heap);
                return SUCCESS;
        }
 
@@ -3731,9 +3760,11 @@ static int zend_type_narrowing(const zend_op_array *op_array, const zend_script
        }
 
        if (zend_infer_types_ex(op_array, script, ssa, worklist) != SUCCESS) {
+               free_alloca(types, use_heap);
                return FAILURE;
        }
 
+       free_alloca(types, use_heap);
        return SUCCESS;
 }
 
@@ -3957,8 +3988,9 @@ static int zend_infer_types(const zend_op_array *op_array, const zend_script *sc
        int ssa_vars_count = ssa->vars_count;
        int j;
        zend_bitset worklist;
+       ALLOCA_FLAG(use_heap);
 
-       worklist = alloca(sizeof(zend_ulong) * zend_bitset_len(ssa_vars_count));
+       worklist = do_alloca(sizeof(zend_ulong) * zend_bitset_len(ssa_vars_count), use_heap);
        memset(worklist, 0, sizeof(zend_ulong) * zend_bitset_len(ssa_vars_count));
 
        /* Type Inference */
@@ -3968,6 +4000,7 @@ static int zend_infer_types(const zend_op_array *op_array, const zend_script *sc
        }
 
        if (zend_infer_types_ex(op_array, script, ssa, worklist) != SUCCESS) {
+               free_alloca(worklist,  use_heap);
                return FAILURE;
        }
 
@@ -3978,6 +4011,7 @@ static int zend_infer_types(const zend_op_array *op_array, const zend_script *sc
                zend_func_return_info(op_array, 1, 0, &ZEND_FUNC_INFO(op_array)->return_info);
        }
 
+       free_alloca(worklist,  use_heap);
        return SUCCESS;
 }
 
@@ -4026,12 +4060,13 @@ void zend_inference_check_recursive_dependencies(zend_op_array *op_array)
        zend_call_info *call_info;
        zend_bitset worklist;
        int worklist_len;
+       ALLOCA_FLAG(use_heap);
 
        if (!info->ssa.var_info || !(info->flags & ZEND_FUNC_RECURSIVE)) {
                return;
        }
        worklist_len = zend_bitset_len(info->ssa.vars_count);
-       worklist = alloca(sizeof(zend_ulong) * worklist_len);
+       worklist = do_alloca(sizeof(zend_ulong) * worklist_len, use_heap);
        memset(worklist, 0, sizeof(zend_ulong) * worklist_len);
        call_info = info->callee_info;
        while (call_info) {
@@ -4049,6 +4084,7 @@ void zend_inference_check_recursive_dependencies(zend_op_array *op_array)
                        add_usages(op_array, &info->ssa, worklist, i);
                }
        }
+       free_alloca(worklist, use_heap);
 }
 
 /*
index 5cdbd283ecd51878caa2f30b7417fd7833cbc822..24b2eb1ed52b396358824daca1ef146e48cb2667 100644 (file)
@@ -82,10 +82,11 @@ static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *va
        uint32_t k;
        zend_op *opline;
        int *tmp = NULL;
+       ALLOCA_FLAG(use_heap);
 
        // FIXME: Can we optimize this copying out in some cases?
        if (blocks[n].next_child >= 0) {
-               tmp = alloca(sizeof(int) * (op_array->last_var + op_array->T));
+               tmp = do_alloca(sizeof(int) * (op_array->last_var + op_array->T), use_heap);
                memcpy(tmp, var, sizeof(int) * (op_array->last_var + op_array->T));
                var = tmp;
        }
@@ -365,6 +366,10 @@ static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *va
                j = blocks[j].next_child;
        }
 
+       if (tmp) {
+               free_alloca(tmp, use_heap);
+       }
+
        return SUCCESS;
 }
 /* }}} */
@@ -379,6 +384,8 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        int *var = NULL;
        int i, j, k, changed;
        zend_dfg dfg;
+       ALLOCA_FLAG(dfg_use_heap);
+       ALLOCA_FLAG(var_use_heap);
 
        ssa->rt_constants = (build_flags & ZEND_RT_CONSTANTS);
        ssa_blocks = zend_arena_calloc(arena, blocks_count, sizeof(zend_ssa_block));
@@ -390,7 +397,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        /* Compute Variable Liveness */
        dfg.vars = op_array->last_var + op_array->T;
        dfg.size = set_size = zend_bitset_len(dfg.vars);
-       dfg.tmp = alloca((set_size * sizeof(zend_ulong)) * (blocks_count * 5 + 1));
+       dfg.tmp = do_alloca((set_size * sizeof(zend_ulong)) * (blocks_count * 5 + 1), dfg_use_heap);
        memset(dfg.tmp, 0, (set_size * sizeof(zend_ulong)) * (blocks_count * 5 + 1));
        dfg.gen = dfg.tmp + set_size;
        dfg.def = dfg.gen + set_size * blocks_count;
@@ -399,6 +406,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        dfg.out = dfg.in  + set_size * blocks_count;
 
        if (zend_build_dfg(op_array, &ssa->cfg, &dfg) != SUCCESS) {
+               free_alloca(dfg.tmp, dfg_use_heap);
                return FAILURE;
        }
 
@@ -435,8 +443,9 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        } while (changed);
 
        /* SSA construction, Step 2: Phi placement based on Dominance Frontiers */
-       var = alloca(sizeof(int) * (op_array->last_var + op_array->T));
+       var = do_alloca(sizeof(int) * (op_array->last_var + op_array->T), var_use_heap);
        if (!var) {
+               free_alloca(dfg.tmp, dfg_use_heap);
                return FAILURE;
        }
        zend_bitset_clear(tmp, set_size);
@@ -472,8 +481,9 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                                                        sizeof(int) * blocks[j].predecessors_count +
                                                        sizeof(void*) * blocks[j].predecessors_count);
 
-                                               if (!phi)
-                                                       return FAILURE;
+                                               if (!phi) {
+                                                       goto failure;
+                                               }
                                                phi->sources = (int*)(((char*)phi) + sizeof(zend_ssa_phi));
                                                memset(phi->sources, 0xff, sizeof(int) * blocks[j].predecessors_count);
                                                phi->use_chains = (zend_ssa_phi**)(((char*)phi->sources) + sizeof(int) * ssa->cfg.blocks[j].predecessors_count);
@@ -668,34 +678,34 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                        if (var1 >= 0) {
                                if ((opline-1)->opcode == ZEND_IS_EQUAL) {
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bt, var1, var2, var2, val2, val2, 0, 0, 0) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bf, var1, var2, var2, val2, val2, 0, 0, 1) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                } else if ((opline-1)->opcode == ZEND_IS_NOT_EQUAL) {
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bf, var1, var2, var2, val2, val2, 0, 0, 0) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bt, var1, var2, var2, val2, val2, 0, 0, 1) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                } else if ((opline-1)->opcode == ZEND_IS_SMALLER) {
                                        if (val2 > LONG_MIN) {
                                                if (add_pi(arena, op_array, &dfg, ssa, j, bt, var1, -1, var2, LONG_MIN, val2-1, 1, 0, 0) != SUCCESS) {
-                                                       return FAILURE;
+                                                       goto failure;
                                                }
                                        }
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bf, var1, var2, -1, val2, LONG_MAX, 0, 1, 0) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                } else if ((opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL) {
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bt, var1, -1, var2, LONG_MIN, val2, 1, 0, 0) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                        if (val2 < LONG_MAX) {
                                                if (add_pi(arena, op_array, &dfg, ssa, j, bf, var1, var2, -1, val2+1, LONG_MAX, 0, 1, 0) != SUCCESS) {
-                                                       return FAILURE;
+                                                       goto failure;
                                                }
                                        }
                                }
@@ -703,33 +713,34 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                        if (var2 >= 0) {
                                if((opline-1)->opcode == ZEND_IS_EQUAL) {
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bt, var2, var1, var1, val1, val1, 0, 0, 0) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, var1, var1, val1, val1, 0, 0, 1) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                } else if ((opline-1)->opcode == ZEND_IS_NOT_EQUAL) {
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, var1, var1, val1, val1, 0, 0, 0) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bt, var2, var1, var1, val1, val1, 0, 0, 1) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                } else if ((opline-1)->opcode == ZEND_IS_SMALLER) {
                                        if (val1 < LONG_MAX) {
                                                if (add_pi(arena, op_array, &dfg, ssa, j, bt, var2, var1, -1, val1+1, LONG_MAX, 0, 1, 0) != SUCCESS) {
-                                                       return FAILURE;
+                                                       goto failure;
                                                }
                                        }
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, -1, var1, LONG_MIN, val1, 1, 0, 0) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                } else if ((opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL) {
                                        if (add_pi(arena, op_array, &dfg, ssa, j, bt, var2, var1, -1, val1, LONG_MAX, 0 ,1, 0) != SUCCESS) {
-                                               return FAILURE;
+                                               goto failure;
                                        }
                                        if (val1 > LONG_MIN) {
-                                               if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, -1, var1, LONG_MIN, val1-1, 1, 0, 0) != SUCCESS) {                                          return FAILURE;
+                                               if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, -1, var1, LONG_MIN, val1-1, 1, 0, 0) != SUCCESS) {
+                                                       goto failure;
                                                }
                                        }
                                }
@@ -743,17 +754,17 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
 
                        if ((opline-1)->opcode == ZEND_POST_DEC) {
                                if (add_pi(arena, op_array, &dfg, ssa, j, bf, var, -1, -1, -1, -1, 0, 0, 0) != SUCCESS) {
-                                       return FAILURE;
+                                       goto failure;
                                }
                                if (add_pi(arena, op_array, &dfg, ssa, j, bt, var, -1, -1, -1, -1, 0, 0, 1) != SUCCESS) {
-                                       return FAILURE;
+                                       goto failure;
                                }
                        } else if ((opline-1)->opcode == ZEND_POST_INC) {
                                if (add_pi(arena, op_array, &dfg, ssa, j, bf, var, -1, -1, 1, 1, 0, 0, 0) != SUCCESS) {
-                                       return FAILURE;
+                                       goto failure;
                                }
                                if (add_pi(arena, op_array, &dfg, ssa, j, bt, var, -1, -1, 1, 1, 0, 0, 1) != SUCCESS) {
-                                       return FAILURE;
+                                       goto failure;
                                }
                        }
                } else if (opline->op1_type == IS_VAR &&
@@ -765,19 +776,19 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
 
                        if ((opline-1)->opcode == ZEND_PRE_DEC) {
                                if (add_pi(arena, op_array, &dfg, ssa, j, bf, var, -1, -1, 0, 0, 0, 0, 0) != SUCCESS) {
-                                       return FAILURE;
+                                       goto failure;
                                }
                                /* speculative */
                                if (add_pi(arena, op_array, &dfg, ssa, j, bt, var, -1, -1, 0, 0, 0, 0, 1) != SUCCESS) {
-                                       return FAILURE;
+                                       goto failure;
                                }
                        } else if ((opline-1)->opcode == ZEND_PRE_INC) {
                                if (add_pi(arena, op_array, &dfg, ssa, j, bf, var, -1, -1, 0, 0, 0, 0, 0) != SUCCESS) {
-                                       return FAILURE;
+                                       goto failure;
                                }
                                /* speculative */
                                if (add_pi(arena, op_array, &dfg, ssa, j, bt, var, -1, -1, 0, 0, 0, 0, 1) != SUCCESS) {
-                                       return FAILURE;
+                                       goto failure;
                                }
                        }
                }
@@ -836,8 +847,9 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                                                                sizeof(int) * blocks[j].predecessors_count +
                                                                sizeof(void*) * blocks[j].predecessors_count);
 
-                                                       if (!phi)
-                                                               return FAILURE;
+                                                       if (!phi) {
+                                                               goto failure;
+                                                       }
                                                        phi->sources = (int*)(((char*)phi) + sizeof(zend_ssa_phi));
                                                        memset(phi->sources, 0xff, sizeof(int) * blocks[j].predecessors_count);
                                                        phi->use_chains = (zend_ssa_phi**)(((char*)phi->sources) + sizeof(int) * ssa->cfg.blocks[j].predecessors_count);
@@ -868,9 +880,15 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        }
        ssa->vars_count = op_array->last_var;
        if (zend_ssa_rename(op_array, ssa, var, 0) != SUCCESS) {
+failure:
+               free_alloca(var, var_use_heap);
+               free_alloca(dfg.tmp, dfg_use_heap);
                return FAILURE;
        }
 
+       free_alloca(var, var_use_heap);
+       free_alloca(dfg.tmp, dfg_use_heap);
+
        return SUCCESS;
 }
 /* }}} */
index c48e03992246da4460271742e20f460c5b33dff8..2ba0e1c632f2b21c715ed6b25ef8c35f31cb11ea 100644 (file)
@@ -30,12 +30,15 @@ typedef struct _zend_worklist_stack {
        int capacity;
 } zend_worklist_stack;
 
-#define ZEND_WORKLIST_STACK_ALLOCA(s, _len) do { \
-               (s)->buf = (int*)alloca(sizeof(int) * _len); \
+#define ZEND_WORKLIST_STACK_ALLOCA(s, _len, use_heap) do { \
+               (s)->buf = (int*)do_alloca(sizeof(int) * _len, use_heap); \
                (s)->len = 0; \
                (s)->capacity = _len; \
        } while (0)
 
+#define ZEND_WORKLIST_STACK_FREE_ALLOCA(s, use_heap) \
+       free_alloca((s)->buf, use_heap)
+
 static inline int zend_worklist_stack_prepare(zend_arena **arena, zend_worklist_stack *stack, int len)
 {
        ZEND_ASSERT(len >= 0);
@@ -73,12 +76,17 @@ typedef struct _zend_worklist {
        zend_worklist_stack stack;
 } zend_worklist;
 
-#define ZEND_WORKLIST_ALLOCA(w, _len) do { \
-               (w)->visited = (zend_bitset)alloca(sizeof(zend_ulong) * zend_bitset_len(_len)); \
+#define ZEND_WORKLIST_ALLOCA(w, _len, use_heap) do { \
+               (w)->stack.buf = (int*)do_alloca(sizeof(int) * _len + sizeof(zend_ulong) * zend_bitset_len(_len), use_heap); \
+               (w)->stack.len = 0; \
+               (w)->stack.capacity = _len; \
+               (w)->visited = (zend_bitset)((w)->stack.buf + _len); \
                memset((w)->visited, 0, sizeof(zend_ulong) * zend_bitset_len(_len)); \
-               ZEND_WORKLIST_STACK_ALLOCA(&(w)->stack, _len); \
        } while (0)
 
+#define ZEND_WORKLIST_FREE_ALLOCA(w, use_heap) \
+       free_alloca((w)->stack.buf, use_heap)
+
 static inline int zend_worklist_prepare(zend_arena **arena, zend_worklist *worklist, int len)
 {
        ZEND_ASSERT(len >= 0);