static void typestate_save_invars(verifier_state *state) { s4 i, index; s4 *pindex; LOG("saving invars"); if (!state->savedindices) { LOG("allocating savedindices buffer"); pindex = DMNEW(s4, state->m->maxstack); state->savedindices = pindex; index = state->numlocals + VERIFIER_EXTRA_VARS; for (i=0; i<state->m->maxstack; ++i) *pindex++ = index++; } /* save types */ typecheck_copy_types(state, state->bptr->invars, state->savedindices, state->bptr->indepth); /* set the invars of the block to the saved variables */ /* and remember the original invars */ state->savedinvars = state->bptr->invars; state->bptr->invars = state->savedindices; }
static void op_stack_init(op_stack_t *stack, unsigned max, bool *perror_flag) { op_stack_slot_t *it; stack->elements = DMNEW(op_stack_slot_t, max * 2); stack->max = max; stack->start = stack->elements + max; stack->end = stack->elements + max + max; for (it = stack->elements; it != stack->start; ++it) { *it = OP_STACK_SLOT_UNKNOWN; } stack->ptr = stack->start; stack->bottom = stack->start; stack->perror_flag = perror_flag; }
bool typecheck(jitdata *jd) { methodinfo *meth; codegendata *cd; varinfo *savedlocals; verifier_state state; /* current state of the verifier */ s4 i; s4 t; /* collect statistics */ #ifdef TYPECHECK_STATISTICS int count_iterations = 0; TYPECHECK_COUNT(stat_typechecked); TYPECHECK_COUNT_FREQ(stat_locals,jd->maxlocals,STAT_LOCALS); TYPECHECK_COUNT_FREQ(stat_blocks,cdata->method->basicblockcount/10,STAT_BLOCKS); TYPECHECK_COUNTIF(cdata->method->exceptiontablelength != 0,stat_methods_with_handlers); state.stat_maythrow = false; #endif /* get required compiler data */ meth = jd->m; cd = jd->cd; /* some logging on entry */ LOGSTR("\n==============================================================================\n"); DOLOG( show_method(jd, SHOW_STACK) ); LOGSTR("\n==============================================================================\n"); LOGMETHOD("Entering typecheck: ",cd->method); /* initialize the verifier state */ state.m = meth; state.jd = jd; state.cd = cd; state.basicblockcount = jd->basicblockcount; state.basicblocks = jd->basicblocks; state.savedindices = NULL; state.savedinvars = NULL; /* check that the basicblock numbers are valid */ #if !defined(NDEBUG) jit_check_basicblock_numbers(jd); #endif /* check if this method is an instance initializer method */ state.initmethod = (state.m->name == utf_init); /* initialize the basic block flags for the following CFG traversal */ typecheck_init_flags(&state, BBFINISHED); /* number of local variables */ /* In <init> methods we use an extra local variable to indicate whether */ /* the 'this' reference has been initialized. */ /* TYPE_VOID...means 'this' has not been initialized, */ /* TYPE_INT....means 'this' has been initialized. */ state.numlocals = state.jd->localcount; state.validlocals = state.numlocals; if (state.initmethod) state.numlocals++; /* VERIFIER_EXTRA_LOCALS */ state.reverselocalmap = DMNEW(s4, state.validlocals); for (i=0; i<jd->maxlocals; ++i) for (t=0; t<5; ++t) { s4 varindex = jd->local_map[5*i + t]; if (varindex >= 0) state.reverselocalmap[varindex] = i; } DOLOG( LOG("reverselocalmap:"); for (i=0; i<state.validlocals; ++i) { LOG2(" %i => javaindex %i", i, state.reverselocalmap[i]); });
state.reverselocalmap[varindex] = i; } DOLOG( LOG("reverselocalmap:"); for (i=0; i<state.validlocals; ++i) { LOG2(" %i => javaindex %i", i, state.reverselocalmap[i]); }); /* allocate the buffer of active exception handlers */ state.handlers = DMNEW(exception_entry*, state.jd->exceptiontablelength + 1); /* save local variables */ savedlocals = DMNEW(varinfo, state.numlocals); MCOPY(savedlocals, jd->var, varinfo, state.numlocals); /* initialized local variables of first block */ if (!typecheck_init_locals(&state, true)) return false; /* initialize invars of exception handlers */ state.exinvars = state.numlocals; VAR(state.exinvars)->type = TYPE_ADR; typeinfo_init_classinfo(&(VAR(state.exinvars)->typeinfo), class_java_lang_Throwable); /* changed later */ LOG("Exception handler stacks set.\n");
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; }
void reg_setup(jitdata *jd) { methodinfo *m; registerdata *rd; s4 i; /* get required compiler data */ m = jd->m; rd = jd->rd; /* setup the integer register table */ rd->tmpintregs = DMNEW(s4, INT_TMP_CNT); rd->savintregs = DMNEW(s4, INT_SAV_CNT); rd->freeargintregs = DMNEW(s4, INT_ARG_CNT); rd->freetmpintregs = DMNEW(s4, INT_TMP_CNT); rd->freesavintregs = DMNEW(s4, INT_SAV_CNT); rd->argintreguse = 0; rd->tmpintreguse = 0; rd->savintreguse = 0; for (i = 0; i < INT_REG_CNT; i++) { switch (nregdescint[i]) { case REG_RET: rd->intreg_ret = i; break; case REG_SAV: rd->savintregs[rd->savintreguse++] = i; break; case REG_TMP: rd->tmpintregs[rd->tmpintreguse++] = i; break; } } assert(rd->savintreguse == INT_SAV_CNT); assert(rd->tmpintreguse == INT_TMP_CNT); #ifdef HAS_ADDRESS_REGISTER_FILE /* setup the address register table */ rd->argadrregs = DMNEW(s4, ADR_ARG_CNT); rd->tmpadrregs = DMNEW(s4, ADR_TMP_CNT); rd->savadrregs = DMNEW(s4, ADR_SAV_CNT); rd->freeargadrregs = DMNEW(s4, ADR_ARG_CNT); rd->freetmpadrregs = DMNEW(s4, ADR_TMP_CNT); rd->freesavadrregs = DMNEW(s4, ADR_SAV_CNT); /*rd->adrreg_argnum = 0; XXX ask twisti */ rd->argadrreguse = 0; rd->tmpadrreguse = 0; rd->savadrreguse = 0; for (i = 0; i < ADR_REG_CNT; i++) { switch (nregdescadr[i]) { case REG_RET: rd->adrreg_ret = i; break; case REG_SAV: rd->savadrregs[rd->savadrreguse++] = i; break; case REG_TMP: rd->tmpadrregs[rd->tmpadrreguse++] = i; break; case REG_ARG: rd->argadrregs[rd->argadrreguse++] = i; break; } } assert(rd->savadrreguse == ADR_SAV_CNT); assert(rd->tmpadrreguse == ADR_TMP_CNT); assert(rd->argadrreguse == ADR_ARG_CNT); #endif /* setup the float register table */ rd->tmpfltregs = DMNEW(s4, FLT_TMP_CNT); rd->savfltregs = DMNEW(s4, FLT_SAV_CNT); rd->freeargfltregs = DMNEW(s4, FLT_ARG_CNT); rd->freetmpfltregs = DMNEW(s4, FLT_TMP_CNT); rd->freesavfltregs = DMNEW(s4, FLT_SAV_CNT); rd->argfltreguse = 0; rd->tmpfltreguse = 0; rd->savfltreguse = 0; for (i = 0; i < FLT_REG_CNT; i++) { switch (nregdescfloat[i]) { case REG_RET: rd->fltreg_ret = i; break; case REG_SAV: rd->savfltregs[rd->savfltreguse++] = i; break; case REG_TMP: rd->tmpfltregs[rd->tmpfltreguse++] = i; break; } } assert(rd->savfltreguse == FLT_SAV_CNT); assert(rd->tmpfltreguse == FLT_TMP_CNT); rd->freemem = DMNEW(s4, m->maxstack); #if defined(HAS_4BYTE_STACKSLOT) rd->freemem_2 = DMNEW(s4, m->maxstack); #endif #if defined(SPECIALMEMUSE) # if defined(__DARWIN__) /* 6*4=24 byte linkage area + 8*4=32 byte minimum parameter Area */ rd->memuse = LA_SIZE_IN_POINTERS + INT_ARG_CNT; # else rd->memuse = LA_SIZE_IN_POINTERS; # endif #else rd->memuse = 0; /* init to zero -> analyse_stack will set it to a higher */ /* value, if appropriate */ #endif /* Set rd->arg*reguse to *_ARG_CNBT to not use unused argument */ /* registers as temp registers */ #if defined(HAS_ADDRESS_REGISTER_FILE) rd->argadrreguse = 0; #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */ rd->argintreguse = 0; rd->argfltreguse = 0; }