void dseg_addlinenumber_inline_end(codegendata *cd, instruction *iptr) { linenumberref *lr; linenumberref *prev; insinfo_inline *insinfo; insinfo = iptr->sx.s23.s3.inlineinfo; assert(insinfo); lr = DNEW(linenumberref); /* special entry containing the methodinfo * */ lr->linenumber = (-3) - iptr->line; lr->tablepos = 0; lr->targetmpc = (ptrint) insinfo->method; lr->next = cd->linenumberreferences; prev = lr; lr = DNEW(linenumberref); /* end marker with PC of start of body */ lr->linenumber = (-1); lr->tablepos = 0; lr->targetmpc = insinfo->startmpc; lr->next = prev; cd->linenumberreferences = lr; }
static s4 dseg_add_address_intern(codegendata *cd, void *value, u4 flags) { dsegentry *de; /* Increase data segment size, which is also the displacement into the data segment. */ #if SIZEOF_VOID_P == 8 cd->dseglen = MEMORY_ALIGN(cd->dseglen + 8, 8); #else cd->dseglen += 4; #endif /* allocate new entry */ de = DNEW(dsegentry); de->type = TYPE_ADR; de->flags = flags; de->disp = -(cd->dseglen); de->val.a = value; de->next = cd->dseg; /* insert into the chain */ cd->dseg = de; return de->disp; }
static s4 dseg_add_float_intern(codegendata *cd, float value, u4 flags) { dsegentry *de; /* Increase data segment size, which is also the displacement into the data segment. */ cd->dseglen += 4; /* allocate new entry */ de = DNEW(dsegentry); de->type = TYPE_FLT; de->flags = flags; de->disp = -(cd->dseglen); de->val.f = value; de->next = cd->dseg; /* insert into the chain */ cd->dseg = de; return de->disp; }
static s4 dseg_add_double_intern(codegendata *cd, double value, u4 flags) { dsegentry *de; /* Increase data segment size, which is also the displacement into the data segment. */ cd->dseglen = MEMORY_ALIGN(cd->dseglen + 8, 8); /* allocate new entry */ de = DNEW(dsegentry); de->type = TYPE_DBL; de->flags = flags; de->disp = -(cd->dseglen); de->val.d = value; de->next = cd->dseg; /* insert into the chain */ cd->dseg = de; return de->disp; }
void dseg_adddata(codegendata *cd) { dataref *dr; dr = DNEW(dataref); dr->datapos = cd->mcodeptr - cd->mcodebase; dr->next = cd->datareferences; cd->datareferences = dr; }
void dseg_add_target(codegendata *cd, basicblock *target) { jumpref *jr; jr = DNEW(jumpref); jr->tablepos = dseg_add_unique_address(cd, NULL); jr->target = target; jr->next = cd->jumpreferences; cd->jumpreferences = jr; }
chain *chain_dnew(void) { chain *c; c = DNEW(chain); c->usedump = 1; c->first = NULL; c->last = NULL; c->active = NULL; return c; }
/******************************************************************************* wl_new IN: int size size of worklist RETURN: worklist * new worklist *******************************************************************************/ worklist *wl_new(int size) { worklist *w; w = DNEW(worklist); w->W_stack = DMNEW(int, size); w->W_top = 0; w->W_bv = bv_new(size); #ifdef WL_DEBUG_CHECK w->size = size; #endif return w; }
void dseg_addlinenumber(codegendata *cd, u2 linenumber) { linenumberref *lr; lr = DNEW(linenumberref); lr->linenumber = linenumber; lr->tablepos = 0; lr->targetmpc = cd->mcodeptr - cd->mcodebase; lr->next = cd->linenumberreferences; cd->linenumberreferences = lr; }
list_t *list_create_dump(s4 nodeoffset) { list_t *l; l = DNEW(list_t); l->first = NULL; l->last = NULL; l->nodeoffset = nodeoffset; l->size = 0; return l; }
void dseg_addlinenumber_inline_start(codegendata *cd, instruction *iptr) { linenumberref *lr; insinfo_inline *insinfo; ptrint mpc; lr = DNEW(linenumberref); lr->linenumber = (-2); /* marks start of inlined method */ lr->tablepos = 0; lr->targetmpc = (mpc = (u1 *) cd->mcodeptr - cd->mcodebase); lr->next = cd->linenumberreferences; cd->linenumberreferences = lr; insinfo = iptr->sx.s23.s3.inlineinfo; insinfo->startmpc = mpc; /* store for corresponding INLINE_END */ }
void basicblock_work_list_insert(basicblock_work_list_t *lst, s4 bytecode_index) { basicblock_work_item_t *it, *item; /* If the destination is already present in the list, do nothing. */ FOR_EACH_BASICBLOCK_WORK_LIST(lst, it) { if (it->bytecode_index == bytecode_index) { return; } } item = DNEW(basicblock_work_item_t); item->bytecode_index = bytecode_index; item->next = NULL; if (lst->first == NULL) { lst->first = item; lst->last = item; } else { lst->last->next = item; lst->last = item; } }
void chain_addafter(chain *c, void *element) { chainlink *active; chainlink *newlink; active = c->active; if (c->usedump) { newlink = DNEW(chainlink); } else { newlink = NEW(chainlink); } newlink->element = element; if (active) { newlink->next = active->next; newlink->prev = active; active->next = newlink; if (newlink->next) { newlink->next->prev = newlink; } else { c->last = newlink; } } else { newlink->next = NULL; newlink->prev = NULL; c->active = newlink; c->first = newlink; c->last = newlink; } }
static void bc_escape_analysis_init(bc_escape_analysis_t *be, methodinfo *m, bool verbose, int depth) { u2 p; int l; int a; u1 *ite; u1 t; unsigned n; int ret_val_is_adr; be->method = m; be->stack = DNEW(op_stack_t); op_stack_init(be->stack, m->maxstack, &(be->fatal_error)); be->basicblocks = DNEW(basicblock_work_list_t); basicblock_work_list_init(be->basicblocks); be->local_to_adr_param_size = m->parseddesc->paramslots; be->local_to_adr_param = DMNEW(op_stack_slot_t, m->parseddesc->paramslots); /* Count number of address parameters a. */ for (p = 0, l = 0, a = 0; p < m->parseddesc->paramcount; ++p) { t = m->parseddesc->paramtypes[p].type; if (t == TYPE_ADR) { be->local_to_adr_param[l] = op_stack_slot_create_param(a); a += 1; l += 1; } else if (IS_2_WORD_TYPE(t)) { be->local_to_adr_param[l] = OP_STACK_SLOT_UNKNOWN; be->local_to_adr_param[l + 1] = OP_STACK_SLOT_UNKNOWN; l += 2; } else { be->local_to_adr_param[l] = OP_STACK_SLOT_UNKNOWN; l += 1; } } assert(l == be->local_to_adr_param_size); ret_val_is_adr = m->parseddesc->returntype.type == TYPE_ADR ? 1 : 0; /* Allocate param_escape on heap. */ be->param_escape_size = a; n = a + ret_val_is_adr; if (n == 0) { /* Use some non-NULL value. */ be->param_escape = (u1 *)1; } else { be->param_escape = MNEW(u1, n); be->param_escape += ret_val_is_adr; } for (ite = be->param_escape; ite != be->param_escape + n; ++ite) { *ite = escape_state_to_u1(ESCAPE_NONE); } if (ret_val_is_adr) { be->param_escape[-1] = escape_state_to_u1(ESCAPE_NONE); } be->adr_param_dirty = DNEW(bit_vector_t); bit_vector_init(be->adr_param_dirty, a); be->adr_param_returned= DNEW(bit_vector_t); bit_vector_init(be->adr_param_returned, a); be->non_escaping_adr_params = be->param_escape_size; #if BC_ESCAPE_VERBOSE be->verbose = verbose; #endif be->depth = depth; be->fatal_error = false; }
static void bc_escape_analysis_perform_intern(methodinfo *m, int depth) { bc_escape_analysis_t *be; bool verbose = false; #if BC_ESCAPE_VERBOSE if (verbose) { dprintf( depth, "=== BC escape analysis of %s/%s at depth %d ===\n", m->clazz->name.begin(), m->name.begin(), depth ); } #endif if (depth >= 3) { return; } if (m->paramescape != NULL) { #if BC_ESCAPE_VERBOSE if (verbose) { dprintf(depth, "Escape info for method already available.\n"); } #endif return; } if ((m->flags & ACC_METHOD_EA) != 0) { #if BC_ESCAPE_VERBOSE if (verbose) { dprintf(depth, "Detected recursion, aborting.\n"); } #endif return; } if (m->jcode == NULL) { #if BC_ESCAPE_VERBOSE if (verbose) { dprintf(depth, "No bytecode for callee.\n"); } #endif return; } if (m->jcodelength > 250) { #if BC_ESCAPE_VERBOSE if (verbose) { dprintf(depth, "Bytecode too long: %d.\n", m->jcodelength); } #endif return; } be = DNEW(bc_escape_analysis_t); bc_escape_analysis_init(be, m, verbose, depth); m->flags |= ACC_METHOD_EA; bc_escape_analysis_analyze(be); #if BC_ESCAPE_VERBOSE if (be->verbose) { dprintf( depth, "%s/%s: Non-escaping params: %d\n", m->clazz->name.begin(), m->name.begin(), be->non_escaping_adr_params ); } #endif m->flags &= ~ACC_METHOD_EA; }