Removed op_array->brk_cont_array

This commit is contained in:
Dmitry Stogov 2015-07-06 13:28:45 +03:00
parent ae5e58b598
commit 883b73c56e
10 changed files with 43 additions and 153 deletions

View File

@ -210,16 +210,21 @@ void zend_oparray_context_begin(zend_oparray_context *prev_context) /* {{{ */
CG(context).opcodes_size = INITIAL_OP_ARRAY_SIZE;
CG(context).vars_size = 0;
CG(context).literals_size = 0;
CG(context).current_brk_cont = -1;
CG(context).backpatch_count = 0;
CG(context).in_finally = 0;
CG(context).fast_call_var = -1;
CG(context).current_brk_cont = -1;
CG(context).last_brk_cont = 0;
CG(context).brk_cont_array = NULL;
CG(context).labels = NULL;
}
/* }}} */
void zend_oparray_context_end(zend_oparray_context *prev_context) /* {{{ */
{
if (CG(context).brk_cont_array) {
efree(CG(context).brk_cont_array);
}
if (CG(context).labels) {
zend_hash_destroy(CG(context).labels);
FREE_HASHTABLE(CG(context).labels);
@ -562,7 +567,7 @@ static inline void zend_begin_loop(const znode *loop_var) /* {{{ */
zend_brk_cont_element *brk_cont_element;
int parent = CG(context).current_brk_cont;
CG(context).current_brk_cont = CG(active_op_array)->last_brk_cont;
CG(context).current_brk_cont = CG(context).last_brk_cont;
brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
brk_cont_element->parent = parent;
@ -580,7 +585,7 @@ static inline void zend_begin_loop(const znode *loop_var) /* {{{ */
static inline void zend_end_loop(int cont_addr) /* {{{ */
{
zend_brk_cont_element *brk_cont_element
= &CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont];
= &CG(context).brk_cont_array[CG(context).current_brk_cont];
brk_cont_element->cont = cont_addr;
brk_cont_element->brk = get_next_op_number(CG(active_op_array));
CG(context).current_brk_cont = brk_cont_element->parent;
@ -914,7 +919,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2
}
zend_error_noreturn(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed");
}
current = op_array->brk_cont_array[current].parent;
current = CG(context).brk_cont_array[current].parent;
}
if (distance == 0) {
@ -3614,12 +3619,12 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
depth, depth == 1 ? "" : "s");
}
if (nest_level > 1 && CG(active_op_array)->brk_cont_array[array_offset].start >= 0) {
if (nest_level > 1 && CG(context).brk_cont_array[array_offset].start >= 0) {
generate_free_loop_var(loop_var);
loop_var--;
}
array_offset = CG(active_op_array)->brk_cont_array[array_offset].parent;
array_offset = CG(context).brk_cont_array[array_offset].parent;
} while (--nest_level > 0);
}
opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT, NULL, NULL);

View File

@ -109,15 +109,36 @@ typedef struct _zend_declarables {
zend_long ticks;
} zend_declarables;
typedef struct _zend_brk_cont_element {
int start;
int cont;
int brk;
int parent;
} zend_brk_cont_element;
typedef struct _zend_label {
int brk_cont;
uint32_t opline_num;
} zend_label;
typedef struct _zend_try_catch_element {
uint32_t try_op;
uint32_t catch_op; /* ketchup! */
uint32_t finally_op;
uint32_t finally_end;
} zend_try_catch_element;
/* Compilation context that is different for each op array. */
typedef struct _zend_oparray_context {
uint32_t opcodes_size;
int vars_size;
int literals_size;
int current_brk_cont;
int backpatch_count;
int in_finally;
uint32_t fast_call_var;
int current_brk_cont;
int last_brk_cont;
zend_brk_cont_element *brk_cont_array;
HashTable *labels;
} zend_oparray_context;
@ -163,26 +184,6 @@ struct _zend_op {
zend_uchar result_type;
};
typedef struct _zend_brk_cont_element {
int start;
int cont;
int brk;
int parent;
} zend_brk_cont_element;
typedef struct _zend_label {
int brk_cont;
uint32_t opline_num;
} zend_label;
typedef struct _zend_try_catch_element {
uint32_t try_op;
uint32_t catch_op; /* ketchup! */
uint32_t finally_op;
uint32_t finally_end;
} zend_try_catch_element;
/* method flags (types) */
#define ZEND_ACC_STATIC 0x01
#define ZEND_ACC_ABSTRACT 0x02
@ -358,9 +359,8 @@ struct _zend_op_array {
zend_string **vars;
uint32_t *T_liveliness;
int last_brk_cont;
//TODO: improve layout ???
int last_try_catch;
zend_brk_cont_element *brk_cont_array;
zend_try_catch_element *try_catch_array;
/* static variables support */

View File

@ -78,9 +78,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
op_array->scope = NULL;
op_array->prototype = NULL;
op_array->brk_cont_array = NULL;
op_array->try_catch_array = NULL;
op_array->last_brk_cont = 0;
op_array->static_variables = NULL;
op_array->last_try_catch = 0;
@ -384,9 +382,6 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
if (op_array->doc_comment) {
zend_string_release(op_array->doc_comment);
}
if (op_array->brk_cont_array) {
efree(op_array->brk_cont_array);
}
if (op_array->try_catch_array) {
efree(op_array->try_catch_array);
}
@ -451,9 +446,9 @@ int get_next_op_number(zend_op_array *op_array)
zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array)
{
op_array->last_brk_cont++;
op_array->brk_cont_array = erealloc(op_array->brk_cont_array, sizeof(zend_brk_cont_element)*op_array->last_brk_cont);
return &op_array->brk_cont_array[op_array->last_brk_cont-1];
CG(context).last_brk_cont++;
CG(context).brk_cont_array = erealloc(CG(context).brk_cont_array, sizeof(zend_brk_cont_element)*CG(context).last_brk_cont);
return &CG(context).brk_cont_array[CG(context).last_brk_cont-1];
}
static void zend_update_extended_info(zend_op_array *op_array)
@ -676,7 +671,7 @@ static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const ze
int array_offset = opline->op1.num;
zend_brk_cont_element *jmp_to;
do {
jmp_to = &op_array->brk_cont_array[array_offset];
jmp_to = &CG(context).brk_cont_array[array_offset];
if (nest_levels > 1) {
array_offset = jmp_to->parent;
}

View File

@ -197,59 +197,6 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
blocks[op_array->try_catch_array[i].try_op].protected = 1;
}
}
/* Currently, we don't optimize op_arrays with BRK/CONT/GOTO opcodes,
* but, we have to keep brk_cont_array to avoid memory leaks during
* exception handling */
if (op_array->last_brk_cont) {
int i, j;
j = 0;
for (i = 0; i< op_array->last_brk_cont; i++) {
if (op_array->brk_cont_array[i].start >= 0 &&
(op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE ||
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FE_FREE)) {
int parent = op_array->brk_cont_array[i].parent;
while (parent >= 0 &&
op_array->brk_cont_array[parent].start < 0 &&
(op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_FREE ||
op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_FE_FREE)) {
parent = op_array->brk_cont_array[parent].parent;
}
op_array->brk_cont_array[i].parent = parent;
j++;
}
}
if (j) {
cfg->loop_start = zend_arena_calloc(&ctx->arena, op_array->last_brk_cont, sizeof(zend_code_block *));
cfg->loop_cont = zend_arena_calloc(&ctx->arena, op_array->last_brk_cont, sizeof(zend_code_block *));
cfg->loop_brk = zend_arena_calloc(&ctx->arena, op_array->last_brk_cont, sizeof(zend_code_block *));
j = 0;
for (i = 0; i< op_array->last_brk_cont; i++) {
if (op_array->brk_cont_array[i].start >= 0 &&
(op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE ||
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FE_FREE)) {
if (i != j) {
op_array->brk_cont_array[j] = op_array->brk_cont_array[i];
}
cfg->loop_start[j] = &blocks[op_array->brk_cont_array[j].start];
cfg->loop_cont[j] = &blocks[op_array->brk_cont_array[j].cont];
cfg->loop_brk[j] = &blocks[op_array->brk_cont_array[j].brk];
START_BLOCK_OP(op_array->brk_cont_array[j].start);
START_BLOCK_OP(op_array->brk_cont_array[j].cont);
START_BLOCK_OP(op_array->brk_cont_array[j].brk);
blocks[op_array->brk_cont_array[j].start].protected = 1;
blocks[op_array->brk_cont_array[j].brk].protected = 1;
j++;
}
}
op_array->last_brk_cont = j;
} else {
efree(op_array->brk_cont_array);
op_array->brk_cont_array = NULL;
op_array->last_brk_cont = 0;
}
}
/* Build CFG (Control Flow Graph) */
cur_block = blocks;
@ -517,16 +464,6 @@ static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int
/* Walk thorough all paths */
zend_access_path(start, ctx);
/* Add brk/cont paths */
if (op_array->last_brk_cont) {
int i;
for (i=0; i< op_array->last_brk_cont; i++) {
zend_access_path(cfg->loop_start[i], ctx);
zend_access_path(cfg->loop_cont[i], ctx);
zend_access_path(cfg->loop_brk[i], ctx);
}
}
/* Add exception paths */
if (op_array->last_try_catch) {
int i;
@ -1189,16 +1126,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
op_array->last_try_catch = j;
}
/* adjust loop jump targets */
if (op_array->last_brk_cont) {
int i;
for (i = 0; i< op_array->last_brk_cont; i++) {
op_array->brk_cont_array[i].start = cfg->loop_start[i]->start_opline - new_opcodes;
op_array->brk_cont_array[i].cont = cfg->loop_cont[i]->start_opline - new_opcodes;
op_array->brk_cont_array[i].brk = cfg->loop_brk[i]->start_opline - new_opcodes;
}
}
/* adjust jump targets */
for (cur_block = blocks; cur_block; cur_block = cur_block->next) {
if (!cur_block->access) {

View File

@ -117,13 +117,6 @@ 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];

View File

@ -340,29 +340,11 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
*/
case ZEND_FREE:
case ZEND_CASE: {
zend_op *m, *n;
int brk = op_array->last_brk_cont;
zend_bool in_switch = 0;
while (brk--) {
if (op_array->brk_cont_array[brk].start <= (opline - op_array->opcodes) &&
op_array->brk_cont_array[brk].brk > (opline - op_array->opcodes)) {
in_switch = 1;
break;
}
}
zend_op *m = opline;
zend_op *end = op_array->opcodes + op_array->last;
if (!in_switch) {
ZEND_ASSERT(opline->opcode == ZEND_FREE);
MAKE_NOP(opline);
zval_dtor(val);
return 1;
}
m = opline;
n = op_array->opcodes + op_array->brk_cont_array[brk].brk + 1;
while (m < n) {
if (ZEND_OP1_TYPE(m) == type &&
ZEND_OP1(m).var == var) {
while (m < end) {
if (ZEND_OP1_TYPE(m) == type && ZEND_OP1(m).var == var) {
if (m->opcode == ZEND_CASE) {
zval old_val;
ZVAL_COPY_VALUE(&old_val, val);
@ -371,6 +353,7 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
ZVAL_COPY_VALUE(val, &old_val);
} else if (m->opcode == ZEND_FREE) {
MAKE_NOP(m);
break;
} else {
ZEND_ASSERT(0);
}

View File

@ -73,9 +73,6 @@ typedef struct _zend_cfg {
zend_code_block *blocks;
zend_code_block **try;
zend_code_block **catch;
zend_code_block **loop_start;
zend_code_block **loop_cont;
zend_code_block **loop_brk;
zend_op **Tsource;
char *same_t;
} zend_cfg;

View File

@ -459,7 +459,6 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
SERIALIZE_STR(op_array->function_name);
SERIALIZE_STR(op_array->filename);
SERIALIZE_PTR(op_array->brk_cont_array);
SERIALIZE_PTR(op_array->scope);
SERIALIZE_STR(op_array->doc_comment);
SERIALIZE_PTR(op_array->try_catch_array);
@ -983,7 +982,6 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
UNSERIALIZE_STR(op_array->function_name);
UNSERIALIZE_STR(op_array->filename);
UNSERIALIZE_PTR(op_array->brk_cont_array);
UNSERIALIZE_PTR(op_array->scope);
UNSERIALIZE_STR(op_array->doc_comment);
UNSERIALIZE_PTR(op_array->try_catch_array);

View File

@ -590,10 +590,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
op_array->arg_info = arg_info;
}
if (op_array->brk_cont_array) {
zend_accel_store(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont);
}
if (op_array->scope) {
op_array->scope = zend_shared_alloc_get_xlat_entry(op_array->scope);
}

View File

@ -229,10 +229,6 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
}
}
if (op_array->brk_cont_array) {
ADD_DUP_SIZE(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont);
}
if (ZCG(accel_directives).save_comments && op_array->doc_comment) {
ADD_STRING(op_array->doc_comment);
}