static void typecheck_invalidate_locals(verifier_state *state, s4 index, bool twoword) { s4 javaindex; s4 t; s4 varindex; jitdata *jd = state->jd; s4 *localmap = jd->local_map; varinfo *vars = jd->var; javaindex = state->reverselocalmap[index]; /* invalidate locals of two-word type at index javaindex-1 */ if (javaindex > 0) { localmap += 5 * (javaindex-1); for (t=0; t<5; ++t) { varindex = *localmap++; if (varindex >= 0 && IS_2_WORD_TYPE(vars[varindex].type)) { LOG1("invalidate local %d", varindex); vars[varindex].type = TYPE_VOID; } } } else { localmap += 5 * javaindex; } /* invalidate locals at index javaindex */ for (t=0; t<5; ++t) { varindex = *localmap++; if (varindex >= 0) { LOG1("invalidate local %d", varindex); vars[varindex].type = TYPE_VOID; } } /* if a two-word type is written, invalidate locals at index javaindex+1 */ if (twoword) { for (t=0; t<5; ++t) { varindex = *localmap++; if (varindex >= 0) { LOG1("invalidate local %d", varindex); vars[varindex].type = TYPE_VOID; } } } }
void md_return_alloc(jitdata *jd, stackptr stackslot) { methodinfo *m; registerdata *rd; methoddesc *md; /* get required compiler data */ m = jd->m; rd = jd->rd; md = m->parseddesc; /* In Leafmethods Local Vars holding parameters are precolored to their argument register -> so leafmethods with paramcount > 0 could already use R3 == a00! */ if (!jd->isleafmethod || (md->paramcount == 0)) { /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has not to survive method invokations. */ if (!(stackslot->flags & SAVEDVAR)) { VAR(stackslot->varnum)->flags = PREALLOC; if (IS_INT_LNG_TYPE(md->returntype.type)) { if (!IS_2_WORD_TYPE(md->returntype.type)) { if (rd->argintreguse < 1) rd->argintreguse = 1; VAR(stackslot->varnum)->vv.regoff = REG_RESULT; } else { if (rd->argintreguse < 2) rd->argintreguse = 2; VAR(stackslot->varnum)->vv.regoff = REG_RESULT_PACKED; } } else { if (rd->argfltreguse < 1) rd->argfltreguse = 1; VAR(stackslot->varnum)->vv.regoff = REG_FRESULT; } } } }
void md_param_alloc(methoddesc *md) { paramdesc *pd; s4 i; s4 iarg; s4 farg; s4 stacksize; /* set default values */ iarg = 0; farg = 0; stacksize = LA_SIZE_IN_POINTERS; /* get params field of methoddesc */ pd = md->params; for (i = 0; i < md->paramcount; i++, pd++) { switch (md->paramtypes[i].type) { case TYPE_INT: case TYPE_ADR: if (iarg < INT_ARG_CNT) { pd->inmemory = false; pd->regoff = abi_registers_integer_argument[iarg]; iarg++; } else { pd->inmemory = true; pd->regoff = stacksize; stacksize++; } break; case TYPE_LNG: if (iarg < INT_ARG_CNT - 1) { _ALIGN(iarg); pd->inmemory = false; pd->regoff = PACK_REGS(abi_registers_integer_argument[iarg + 1], abi_registers_integer_argument[iarg]); iarg += 2; } else { _ALIGN(stacksize); pd->inmemory = true; pd->regoff = stacksize; iarg = INT_ARG_CNT; stacksize += 2; } break; case TYPE_FLT: if (farg < FLT_ARG_CNT) { pd->inmemory = false; pd->regoff = abi_registers_float_argument[farg]; farg++; } else { pd->inmemory = true; pd->regoff = stacksize; stacksize++; } break; case TYPE_DBL: if (farg < FLT_ARG_CNT) { pd->inmemory = false; pd->regoff = abi_registers_float_argument[farg]; farg++; } else { _ALIGN(stacksize); pd->inmemory = true; pd->regoff = stacksize; stacksize += 2; } break; default: assert(0); } } /* Since R3/R4, F1 (==A0/A1, A0) are used for passing return values, this argument register usage has to be regarded, too. */ if (IS_INT_LNG_TYPE(md->returntype.type)) { if (iarg < (IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1)) iarg = IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1; } else { if (IS_FLT_DBL_TYPE(md->returntype.type)) if (farg < 1) farg = 1; } /* fill register and stack usage */ md->argintreguse = iarg; md->argfltreguse = farg; md->memuse = stacksize; }
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; }