mirror of
https://github.com/php/php-src.git
synced 2024-11-24 10:24:11 +08:00
Removed op_array->brk_cont_array
This commit is contained in:
parent
ae5e58b598
commit
883b73c56e
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user