Exemple #1
0
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;
}
Exemple #3
0
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]);
		});
Exemple #4
0
				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;
}
Exemple #6
0
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;
}