From c2b6a8e3095b76b9619f2a8a79489d7439d2a072 Mon Sep 17 00:00:00 2001 From: edwin Date: Sat, 11 Nov 2006 17:08:14 +0000 Subject: [PATCH] * src/vm/jit/tools/genoffsets.c (executionstate): Renamed to executionstate_t. * src/vm/jit/asmpart.h: Likewise. * src/vm/jit/show.c (show_variable_intern): New function. Does not append ' '. Regard variables above vartop as invalid. (show_method): Only show variables up to vartop. (show_inline_info): New function. (show_basicblock): Show right number of javalocals, show inlining info at the start of blocks. (show_variable): Moved body to show_variable_intern. (show_icmd): Use show_inline_info. * src/vm/jit/inline/inline.c: Handle javalocals. * src/vm/jit/i386/codegen.c (codegen): Handle replacement points for INLINE_START, RETURN and INVOKEs. * src/vm/jit/replace.c: Many changes for making replacement work over multiple stack frames. * src/vm/jit/replace.h: Likewise. * src/vm/jit/jit.h (insinfo_inline): Added fields. (basicblock): Added field `inlineinfo`. --- src/vm/jit/asmpart.h | 4 +- src/vm/jit/i386/codegen.c | 30 +- src/vm/jit/inline/inline.c | 131 +++- src/vm/jit/jit.h | 31 +- src/vm/jit/replace.c | 1268 +++++++++++++++++++-------------- src/vm/jit/replace.h | 79 +- src/vm/jit/show.c | 77 +- src/vm/jit/tools/genoffsets.c | 14 +- 8 files changed, 1045 insertions(+), 589 deletions(-) diff --git a/src/vm/jit/asmpart.h b/src/vm/jit/asmpart.h index 3dde90b3d..a64e09b7b 100644 --- a/src/vm/jit/asmpart.h +++ b/src/vm/jit/asmpart.h @@ -30,7 +30,7 @@ Changes: Christian Thalinger Edwin Steiner - $Id: asmpart.h 5812 2006-10-20 14:22:23Z twisti $ + $Id: asmpart.h 5950 2006-11-11 17:08:14Z edwin $ */ @@ -151,7 +151,7 @@ void asm_patcher_wrapper(void); /* functions for on-stack replacement */ void asm_replacement_out(void); -void asm_replacement_in(executionstate *es); +void asm_replacement_in(executionstate_t *es); #if defined(ENABLE_THREADS) extern critical_section_node_t asm_criticalsections; diff --git a/src/vm/jit/i386/codegen.c b/src/vm/jit/i386/codegen.c index f583d6eea..6b9417ef0 100644 --- a/src/vm/jit/i386/codegen.c +++ b/src/vm/jit/i386/codegen.c @@ -30,7 +30,7 @@ Christian Ullrich Edwin Steiner - $Id: codegen.c 5932 2006-11-07 09:06:18Z twisti $ + $Id: codegen.c 5950 2006-11-11 17:08:14Z edwin $ */ @@ -523,6 +523,14 @@ bool codegen(jitdata *jd) case ICMD_INLINE_START: { insinfo_inline *insinfo = iptr->sx.s23.s3.inlineinfo; + + /* handle replacement point */ + + replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase); + replacementpoint++; + /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */ + cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */ + #if defined(ENABLE_THREADS) if (insinfo->synchronize) { /* add monitor enter code */ @@ -3031,6 +3039,13 @@ nowperformreturn: { s4 i, p; + /* handle replacement point */ + + replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase); + replacementpoint++; + /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */ + cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */ + p = cd->stackframesize; #if !defined(NDEBUG) @@ -3197,6 +3212,13 @@ nowperformreturn: case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */ case ICMD_INVOKEINTERFACE: + /* handle replacement point */ + + replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase); + replacementpoint++; + /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */ + cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */ + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { md = iptr->sx.s23.s3.um->methodref->parseddesc.md; lm = NULL; @@ -3359,6 +3381,12 @@ gen_method: break; } + /* store size of call code in replacement point */ + + if (iptr->opc != ICMD_BUILTIN) + replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase) + - (ptrint) replacementpoint[-1].pc; + /* d contains return type */ if (d != TYPE_VOID) { diff --git a/src/vm/jit/inline/inline.c b/src/vm/jit/inline/inline.c index e16e6a375..6e0b5ca93 100644 --- a/src/vm/jit/inline/inline.c +++ b/src/vm/jit/inline/inline.c @@ -28,7 +28,7 @@ Changes: - $Id: inline.c 5925 2006-11-05 23:11:27Z edwin $ + $Id: inline.c 5950 2006-11-11 17:08:14Z edwin $ */ @@ -144,6 +144,7 @@ struct inline_node { /* temporary */ inline_target_ref *refs; instruction *inline_start_instruction; + s4 *javalocals; /* XXX debug */ char *indent; @@ -412,7 +413,6 @@ static s4 *create_variable_map(inline_node *callee) s4 n_idx; s4 avail; varinfo *v; - varinfo vinfo; /* create the variable mapping */ @@ -602,6 +602,11 @@ static basicblock * create_block(inline_node *container, n_bptr->indepth = indepth; n_bptr->flags = BBFINISHED; /* XXX */ + /* set the inlineinfo of the new block */ + + if (iln->inline_start_instruction) + n_bptr->inlineinfo = iln->inline_start_instruction->sx.s23.s3.inlineinfo; + if (indepth > container->ctx->maxinoutdepth) container->ctx->maxinoutdepth = indepth; @@ -643,11 +648,11 @@ static basicblock * create_block(inline_node *container, inline_resolve_block_refs(refs, o_bptr, n_bptr); } + /* XXX for the verifier. should not be here */ + { varinfo *dv; - /* XXX for the verifier. should not be here */ - dv = DMNEW(varinfo, iln->ctx->resultjd->localcount + VERIFIER_EXTRA_LOCALS); MZERO(dv, varinfo, iln->ctx->resultjd->localcount + VERIFIER_EXTRA_LOCALS); n_bptr->inlocals = dv; @@ -657,6 +662,24 @@ static basicblock * create_block(inline_node *container, } +static s4 *translate_javalocals(inline_node *iln, s4 *javalocals) +{ + s4 *jl; + s4 i, j; + + jl = DMNEW(s4, iln->jd->maxlocals); + + for (i=0; ijd->maxlocals; ++i) { + j = javalocals[i]; + if (j != UNUSED) + j = inline_translate_variable(iln->ctx->resultjd, iln->jd, iln->varmap, j); + jl[i] = j; + } + + return jl; +} + + static basicblock * create_body_block(inline_node *iln, basicblock *o_bptr, s4 *varmap) { @@ -678,6 +701,10 @@ static basicblock * create_body_block(inline_node *iln, o_bptr->invars[i]); } + /* translate javalocals info */ + + n_bptr->javalocals = translate_javalocals(iln, o_bptr->javalocals); + return n_bptr; } @@ -687,7 +714,6 @@ static basicblock * create_epilog_block(inline_node *caller, inline_node *callee basicblock *n_bptr; s4 retcount; s4 idx; - varinfo vinfo; /* number of return variables */ @@ -708,6 +734,13 @@ static basicblock * create_epilog_block(inline_node *caller, inline_node *callee varmap[callee->callerins->dst.varindex] = idx; } + /* set javalocals */ + + n_bptr->javalocals = DMNEW(s4, caller->jd->maxlocals); + MCOPY(n_bptr->javalocals, caller->javalocals, s4, caller->jd->maxlocals); + + /* set block flags & type */ + n_bptr->flags = /* XXX original block flags */ BBFINISHED; n_bptr->type = BBTYPE_STD; @@ -916,11 +949,30 @@ static s4 emit_inlining_prolog(inline_node *iln, insinfo->outer = iln->m; insinfo->synclocal = callee->synclocal; insinfo->synchronize = callee->synchronize; + insinfo->javalocals_start = NULL; + insinfo->javalocals_end = NULL; + + /* info about stack vars live at the INLINE_START */ + + insinfo->throughcount = callee->n_passthroughcount; + insinfo->stackvarscount = callee->n_selfpassthroughcount; + insinfo->stackvars = DMNEW(s4, callee->n_selfpassthroughcount); + for (i=0; in_selfpassthroughcount; ++i) + insinfo->stackvars[i] = iln->varmap[callee->n_passthroughvars[i]]; + + /* info about the surrounding inlining */ + + if (iln->inline_start_instruction) + insinfo->parent = iln->inline_start_instruction->sx.s23.s3.inlineinfo; + else + insinfo->parent = NULL; + + /* finish the INLINE_START instruction */ n_ins->opc = ICMD_INLINE_START; n_ins->sx.s23.s3.inlineinfo = insinfo; n_ins->line = o_iptr->line; - iln->inline_start_instruction = n_ins; + callee->inline_start_instruction = n_ins; DOLOG( printf("%sprolog: ", iln->indent); show_icmd(iln->ctx->resultjd, n_ins, false, SHOW_STACK); printf("\n"); ); @@ -932,9 +984,10 @@ static s4 emit_inlining_prolog(inline_node *iln, static void emit_inlining_epilog(inline_node *iln, inline_node *callee, instruction *o_iptr) { instruction *n_ins; + s4 *jl; assert(iln && callee && o_iptr); - assert(iln->inline_start_instruction); + assert(callee->inline_start_instruction); /* INLINE_END instruction */ @@ -942,9 +995,15 @@ static void emit_inlining_epilog(inline_node *iln, inline_node *callee, instruct assert((n_ins - iln->inlined_iinstr) < iln->cumul_instructioncount); n_ins->opc = ICMD_INLINE_END; - n_ins->sx.s23.s3.inlineinfo = iln->inline_start_instruction->sx.s23.s3.inlineinfo; + n_ins->sx.s23.s3.inlineinfo = callee->inline_start_instruction->sx.s23.s3.inlineinfo; n_ins->line = o_iptr->line; + /* set the javalocals */ + + jl = DMNEW(s4, iln->jd->maxlocals); + MCOPY(jl, iln->javalocals, s4, iln->jd->maxlocals); + n_ins->sx.s23.s3.inlineinfo->javalocals_end = jl; + DOLOG( printf("%sepilog: ", iln->indent); show_icmd(iln->ctx->resultjd, n_ins, false, SHOW_STACK); printf("\n"); ); } @@ -1074,6 +1133,28 @@ clone_call: } break; } + + /* XXX move this to dataflow section? */ + + switch (n_iptr->opc) { + case ICMD_ISTORE: + case ICMD_LSTORE: + case ICMD_FSTORE: + case ICMD_DSTORE: + case ICMD_ASTORE: + /* XXX share code with stack.c */ + j = n_iptr->dst.varindex; + i = n_iptr->sx.s23.s3.javaindex; + if (n_iptr->flags.bits & INS_FLAG_RETADDR) + iln->javalocals[i] = UNUSED; + else + iln->javalocals[i] = j; + if (n_iptr->flags.bits & INS_FLAG_KILL_PREV) + iln->javalocals[i-1] = UNUSED; + if (n_iptr->flags.bits & INS_FLAG_KILL_NEXT) + iln->javalocals[i+1] = UNUSED; + break; + } } @@ -1118,6 +1199,10 @@ static void rewrite_method(inline_node *iln) iln->inlined_iinstr_cursor = iln->inlined_iinstr; iln->inlined_basicblocks_cursor = iln->inlined_basicblocks; + /* allocate temporary buffers */ + + iln->javalocals = DMNEW(s4, iln->jd->maxlocals); + /* loop over basic blocks */ o_bptr = iln->jd->basicblocks; @@ -1172,14 +1257,29 @@ static void rewrite_method(inline_node *iln) /* enter it in the blockmap */ inline_block_translation(iln, o_bptr, n_bptr); + + /* initialize the javalocals */ + + MCOPY(iln->javalocals, n_bptr->javalocals, s4, iln->jd->maxlocals); } else { + s4 *jl; + /* continue caller block */ n_bptr = iln->inlined_basicblocks_cursor - 1; icount = n_bptr->icount; + + /* translate the javalocals */ + + jl = translate_javalocals(iln, o_bptr->javalocals); + iln->inline_start_instruction->sx.s23.s3.inlineinfo->javalocals_start = jl; + + MCOPY(iln->javalocals, jl, s4, iln->jd->maxlocals); } + /* iterate over the ICMDs of this block */ + retcount = 0; retidx = UNUSED; @@ -1559,7 +1659,6 @@ static void inline_write_exception_handlers(inline_node *master, inline_node *il builtintable_entry *bte; s4 exvar; s4 syncvar; - varinfo vinfo; s4 i; child = iln->children; @@ -1646,8 +1745,8 @@ static bool test_inlining(inline_node *iln, jitdata *jd, s4 i; - static int debug_verify_inlined_code = 1; /* XXX */ #if !defined(NDEBUG) + static int debug_verify_inlined_code = 1; /* XXX */ static int debug_compile_inlined_code_counter = 0; #endif @@ -1658,6 +1757,7 @@ static bool test_inlining(inline_node *iln, jitdata *jd, *resultjd = jd; n_ins = DMNEW(instruction, iln->cumul_instructioncount); + MZERO(n_ins, instruction, iln->cumul_instructioncount); iln->inlined_iinstr = n_ins; n_bb = DMNEW(basicblock, iln->cumul_basicblockcount); @@ -1690,6 +1790,7 @@ static bool test_inlining(inline_node *iln, jitdata *jd, /* extra variables for verification (DEBUG) */ +#if !defined(NDEBUG) if (debug_verify_inlined_code) { n_jd->vartop += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + 100 /* XXX m->maxstack */; if (n_jd->vartop > n_jd->varcount) { @@ -1698,6 +1799,7 @@ static bool test_inlining(inline_node *iln, jitdata *jd, n_jd->varcount = n_jd->vartop; } } +#endif /* write inlined code */ @@ -1766,7 +1868,7 @@ static bool test_inlining(inline_node *iln, jitdata *jd, inline_interface_variables(iln); -#if defined(ENABLE_VERIFIER) +#if defined(ENABLE_VERIFIER) && !defined(NDEBUG) if (debug_verify_inlined_code) { debug_verify_inlined_code = 0; DOLOG( printf("VERIFYING INLINED RESULT...\n"); fflush(stdout); ); @@ -1839,7 +1941,6 @@ static bool inline_analyse_callee(inline_node *caller, bool isstatic; s4 i, j; basicblock *bptr; - instruction *iptr; /* create an inline tree node */ @@ -2136,9 +2237,10 @@ static bool inline_inline_intern(methodinfo *m, inline_node *iln) if (0 && strncmp(callee->class->name->text, "java/", 5) != 0 && strncmp(callee->class->name->text, "gnu/", 4) != 0 + && strstr(callee->class->name->text, "compress") != NULL ) { - printf("SPECULATIVE INLINE: "); method_println(callee); + DOLOG( printf("SPECULATIVE INLINE: "); method_println(callee); ); speculative = true; goto maybe_inline; } @@ -2154,8 +2256,9 @@ maybe_inline: goto dont_inline; } } - +#if 0 force_inline: +#endif if (!inline_analyse_callee(iln, callee, bptr, iptr, diff --git a/src/vm/jit/jit.h b/src/vm/jit/jit.h index f50f5e2b6..52ad4f64a 100644 --- a/src/vm/jit/jit.h +++ b/src/vm/jit/jit.h @@ -30,7 +30,7 @@ Changes: Christian Thalinger Edwin Steiner - $Id: jit.h 5923 2006-11-05 22:46:11Z edwin $ + $Id: jit.h 5950 2006-11-11 17:08:14Z edwin $ */ @@ -62,6 +62,7 @@ typedef struct exception_entry exception_entry; #include "vm/jit/codegen-common.h" #include "vm/jit/reg.h" #include "vm/jit/stacktrace.h" +#include "vm/jit/replace.h" #if defined(ENABLE_INLINING) # include "vm/jit/inline/inline.h" @@ -402,15 +403,30 @@ struct instruction { /* for ICMD_INLINE_START and ICMD_INLINE_END */ struct insinfo_inline { - methodinfo *method; /* the inlined method starting/ending here */ - methodinfo *outer; /* the outer method suspended/resumed here */ - s4 startmpc; /* machine code offset of start of inlining */ - s4 synclocal; /* local index used for synchronization */ - bool synchronize; /* true if synchronization is needed */ + /* fields copied from the inlining tree ----------------------------------*/ + insinfo_inline *parent; /* insinfo of the surrounding inlining, if any*/ + methodinfo *method; /* the inlined method starting/ending here */ + methodinfo *outer; /* the outer method suspended/resumed here */ + s4 synclocal; /* local index used for synchronization */ + bool synchronize; /* true if synchronization is needed */ + s4 throughcount; /* total # of pass-through variables */ + s4 stackvarscount; /* source stackdepth at INLINE_START */ + s4 *stackvars; /* stack vars at INLINE_START */ + + /* fields set by inlining ------------------------------------------------*/ + s4 *javalocals_start; /* javalocals at start of inlined body */ + s4 *javalocals_end; /* javalocals after inlined body */ + + /* fields set by replacement point creation ------------------------------*/ + rplpoint *rp; /* replacement point at INLINE_START */ + + /* fields set by the codegen ---------------------------------------------*/ + s4 startmpc; /* machine code offset of start of inlining */ }; + /* basicblock *****************************************************************/ - + /* flags */ #define BBDELETED -2 @@ -466,6 +482,7 @@ struct basicblock { basicblock *original; /* block of which this block is a clone */ /* NULL for the original block itself */ methodinfo *method; /* method this block belongs to */ + insinfo_inline *inlineinfo; /* inlineinfo for the start of this block */ s4 mpc; /* machine code pc at start of block */ }; diff --git a/src/vm/jit/replace.c b/src/vm/jit/replace.c index 3f7ee7a50..44437aa39 100644 --- a/src/vm/jit/replace.c +++ b/src/vm/jit/replace.c @@ -54,10 +54,19 @@ #include "native/include/java_lang_String.h" + +/*** configuration of native stack slot size **********************************/ + +/* XXX this should be in md-abi.h files, probably */ + #if defined(HAS_4BYTE_STACKSLOT) -#define SIZE_OF_STACKSLOT 4 +#define SIZE_OF_STACKSLOT 4 +#define STACK_SLOTS_PER_FLOAT 2 +typedef u4 stackslot_t; #else -#define SIZE_OF_STACKSLOT 8 +#define SIZE_OF_STACKSLOT 8 +#define STACK_SLOTS_PER_FLOAT 1 +typedef u8 stackslot_t; #endif @@ -67,10 +76,31 @@ #define TOP_IS_ON_STACK 1 #define TOP_IS_IN_ITMP1 2 + +/* replace_create_replacement_point ******************************************** + + Create a replacement point. + + IN: + jd...............current jitdata + iinfo............inlining info for the current position + rp...............pre-allocated (uninitialized) rplpoint + type.............RPLPOINT_TYPE constant + *pra.............current rplalloc pointer + javalocals.......the javalocals at the current point + stackvars........the stack variables at the current point + stackdepth.......the stack depth at the current point + + OUT: + *rpa.............points to the next free rplalloc + +*******************************************************************************/ + static void replace_create_replacement_point(jitdata *jd, + insinfo_inline *iinfo, rplpoint *rp, + s4 type, rplalloc **pra, - basicblock *bptr, s4 *javalocals, s4 *stackvars, s4 stackdepth) @@ -80,22 +110,30 @@ static void replace_create_replacement_point(jitdata *jd, varinfo *v; s4 index; + static s4 fake_id = 0; + ra = *pra; /* there will be a replacement point at the start of this block */ + rp->method = (iinfo) ? iinfo->method : jd->m; rp->pc = NULL; /* set by codegen */ rp->outcode = NULL; /* set by codegen */ - rp->code = jd->code; + rp->callsize = 0; /* set by codegen */ rp->target = NULL; rp->regalloc = ra; rp->flags = 0; - rp->type = (bptr != NULL) ? bptr->type : -1; + rp->type = type; + rp->id = ++fake_id; /* XXX need a real invariant id */ - /* store local allocation info */ + /* XXX unify these two fields */ + rp->code = jd->code; + rp->parent = (iinfo) ? iinfo->rp : NULL; + + /* store local allocation info of javalocals */ if (javalocals) { - for (i = 0; i < jd->maxlocals; ++i) { + for (i = 0; i < rp->method->maxlocals; ++i) { index = javalocals[i]; if (index == UNUSED) continue; @@ -109,6 +147,8 @@ static void replace_create_replacement_point(jitdata *jd, } } + /* store allocation info of java stack vars */ + for (i = 0; i < stackdepth; ++i) { v = VAR(stackvars[i]); ra->flags = v->flags & (INMEMORY); @@ -118,6 +158,8 @@ static void replace_create_replacement_point(jitdata *jd, ra++; } + /* total number of allocations */ + rp->regalloccount = ra - rp->regalloc; *pra = ra; @@ -129,10 +171,7 @@ static void replace_create_replacement_point(jitdata *jd, Create the replacement points for the given code. IN: - code.............codeinfo where replacement points should be stored - code->rplpoints must be NULL. - code->rplpointcount must be 0. - rd...............registerdata containing allocation info. + jd...............current jitdata, must not have any replacement points OUT: code->rplpoints.......set to the list of replacement points @@ -150,23 +189,24 @@ static void replace_create_replacement_point(jitdata *jd, bool replace_create_replacement_points(jitdata *jd) { - codeinfo *code; - registerdata *rd; - basicblock *bptr; - int count; - methodinfo *m; - rplpoint *rplpoints; - rplpoint *rp; - int alloccount; - int globalcount; - rplalloc *regalloc; - rplalloc *ra; - int i; - instruction *iptr; - instruction *iend; - s4 *javalocals; - methoddesc *md; - s4 j; + codeinfo *code; + registerdata *rd; + basicblock *bptr; + int count; + methodinfo *m; + rplpoint *rplpoints; + rplpoint *rp; + int alloccount; + rplalloc *regalloc; + rplalloc *ra; + int i; + instruction *iptr; + instruction *iend; + s4 *javalocals; + methoddesc *md; + s4 j; + insinfo_inline *iinfo; + insinfo_inline *calleeinfo; /* get required compiler data */ @@ -174,7 +214,7 @@ bool replace_create_replacement_points(jitdata *jd) rd = jd->rd; /* assert that we wont overwrite already allocated data */ - + assert(code); assert(code->m); assert(code->rplpoints == NULL); @@ -194,22 +234,36 @@ bool replace_create_replacement_points(jitdata *jd) for (bptr = jd->basicblocks; bptr; bptr = bptr->next) { + /* skip dead code */ + if (bptr->flags < BBFINISHED) continue; - if (bptr->bitflags & BBFLAG_REPLACEMENT) { + /* get info about this block */ + + m = bptr->method; + iinfo = bptr->inlineinfo; + + /* initialize javalocals at the start of this block */ - /* there will be a replacement point at the start of this block */ - + if (bptr->javalocals) + MCOPY(javalocals, bptr->javalocals, s4, m->maxlocals); + else + for (i=0; imaxlocals; ++i) + javalocals[i] = UNUSED; + + /* create replacement points at targets of backward branches */ + + if (bptr->bitflags & BBFLAG_REPLACEMENT) { count++; alloccount += bptr->indepth; - for (i=0; imaxlocals; ++i) + for (i=0; imaxlocals; ++i) if (bptr->javalocals[i] != UNUSED) alloccount++; } - MCOPY(javalocals, bptr->javalocals, s4, jd->maxlocals); + /* iterate over the instructions */ iptr = bptr->iinstr; iend = iptr + bptr->icount; @@ -222,10 +276,12 @@ bool replace_create_replacement_points(jitdata *jd) case ICMD_INVOKEINTERFACE: INSTRUCTION_GET_METHODDESC(iptr, md); count++; - for (i=0; imaxlocals; ++i) + for (i=0; imaxlocals; ++i) if (javalocals[i] != UNUSED) alloccount++; alloccount += iptr->s1.argcount - md->paramcount; + if (iinfo) + alloccount -= iinfo->throughcount; break; case ICMD_ISTORE: @@ -252,103 +308,82 @@ bool replace_create_replacement_points(jitdata *jd) case ICMD_DRETURN: case ICMD_ARETURN: alloccount += 1; - /* FALLTHROUGH */ - + /* FALLTHROUGH! */ case ICMD_RETURN: count++; break; - } - } - } - /* if no points were found, there's nothing to do */ - - if (!count) - return true; + case ICMD_INLINE_START: + iinfo = iptr->sx.s23.s3.inlineinfo; - /* count global register allocations */ + count++; + for (i=0; imaxlocals; ++i) + if (javalocals[i] != UNUSED) + alloccount++; + alloccount += iinfo->stackvarscount; - globalcount = 0; + m = iinfo->method; + if (iinfo->javalocals_start) + MCOPY(javalocals, iinfo->javalocals_start, s4, m->maxlocals); + break; -#if 0 - for (i=0; imaxlocals; ++i) { - indexused = false; - for (t=0; t<5; ++t) { -#if defined(ENABLE_INTRP) - if (!opt_intrp) { -#endif - if (jd->local_map[5*i + t] != UNUSED) { - globalcount++; - indexused = true; - } -#if defined(ENABLE_INTRP) + case ICMD_INLINE_END: + iinfo = iptr->sx.s23.s3.inlineinfo; + m = iinfo->outer; + if (iinfo->javalocals_end) + MCOPY(javalocals, iinfo->javalocals_end, s4, m->maxlocals); + iinfo = iinfo->parent; + break; } -#endif } - if (!indexused) - globalcount++; /* dummy rplalloc */ } -#endif - alloccount += globalcount; + /* if no points were found, there's nothing to do */ - /* allocate replacement point array and allocation array */ - - rplpoints = MNEW(rplpoint,count); - regalloc = MNEW(rplalloc,alloccount); - ra = regalloc; + if (!count) + return true; - /* store global register allocations */ + /* allocate replacement point array and allocation array */ -#if 0 - for (i=0; imaxlocals; ++i) { - indexused = false; - for (t=0; t<5; ++t) { -#if defined(ENABLE_INTRP) - if (!opt_intrp) { -#endif - if (jd->local_map[5*i + t] != UNUSED) { - v = VAR(jd->local_map[5*i + t]); - ra->flags = v->flags & (INMEMORY); - ra->regoff = v->vv.regoff; - ra->type = t; - ra->next = (indexused) ? 0 : 1; - ra++; - indexused = true; - } -#if defined(ENABLE_INTRP) - } -#endif - } - if (!indexused) { - /* dummy rplalloc */ - ra->type = -1; - ra->flags = 0; - ra->regoff = 0; - ra->next = 1; - ra++; - } - } -#endif + rplpoints = MNEW(rplpoint, count); + regalloc = MNEW(rplalloc, alloccount); + ra = regalloc; /* initialize replacement point structs */ rp = rplpoints; + /* XXX try to share code with the counting loop! */ + for (bptr = jd->basicblocks; bptr; bptr = bptr->next) { + /* skip dead code */ + if (bptr->flags < BBFINISHED) continue; + /* get info about this block */ + + m = bptr->method; + iinfo = bptr->inlineinfo; + + /* initialize javalocals at the start of this block */ + + if (bptr->javalocals) + MCOPY(javalocals, bptr->javalocals, s4, m->maxlocals); + else + for (i=0; imaxlocals; ++i) + javalocals[i] = UNUSED; + + /* create replacement points at targets of backward branches */ + if (bptr->bitflags & BBFLAG_REPLACEMENT) { - replace_create_replacement_point(jd, rp, &ra, - bptr, + replace_create_replacement_point(jd, iinfo, rp++, + bptr->type, &ra, bptr->javalocals, bptr->invars, bptr->indepth); - - rp++; } - MCOPY(javalocals, bptr->javalocals, s4, jd->maxlocals); + /* iterate over the instructions */ iptr = bptr->iinstr; iend = iptr + bptr->icount; @@ -361,11 +396,11 @@ bool replace_create_replacement_points(jitdata *jd) case ICMD_INVOKEINTERFACE: INSTRUCTION_GET_METHODDESC(iptr, md); - replace_create_replacement_point(jd, rp, &ra, - NULL, + i = (iinfo) ? iinfo->throughcount : 0; + replace_create_replacement_point(jd, iinfo, rp++, + RPLPOINT_TYPE_CALL, &ra, javalocals, iptr->sx.s23.s2.args + md->paramcount, - iptr->s1.argcount - md->paramcount); - rp++; + iptr->s1.argcount - md->paramcount - i); break; case ICMD_ISTORE: @@ -391,17 +426,38 @@ bool replace_create_replacement_points(jitdata *jd) case ICMD_FRETURN: case ICMD_DRETURN: case ICMD_ARETURN: - replace_create_replacement_point(jd, rp, &ra, - NULL, + replace_create_replacement_point(jd, iinfo, rp++, + RPLPOINT_TYPE_RETURN, &ra, NULL, &(iptr->s1.varindex), 1); - rp++; break; case ICMD_RETURN: - replace_create_replacement_point(jd, rp, &ra, - NULL, + replace_create_replacement_point(jd, iinfo, rp++, + RPLPOINT_TYPE_RETURN, &ra, NULL, NULL, 0); - rp++; + break; + + case ICMD_INLINE_START: + calleeinfo = iptr->sx.s23.s3.inlineinfo; + + calleeinfo->rp = rp; + replace_create_replacement_point(jd, iinfo, rp++, + RPLPOINT_TYPE_INLINE, &ra, + javalocals, + calleeinfo->stackvars, calleeinfo->stackvarscount); + + iinfo = calleeinfo; + m = iinfo->method; + if (iinfo->javalocals_start) + MCOPY(javalocals, iinfo->javalocals_start, s4, m->maxlocals); + break; + + case ICMD_INLINE_END: + iinfo = iptr->sx.s23.s3.inlineinfo; + m = iinfo->outer; + if (iinfo->javalocals_end) + MCOPY(javalocals, iinfo->javalocals_end, s4, m->maxlocals); + iinfo = iinfo->parent; break; } } @@ -413,7 +469,7 @@ bool replace_create_replacement_points(jitdata *jd) code->rplpointcount = count; code->regalloc = regalloc; code->regalloccount = alloccount; - code->globalcount = globalcount; + code->globalcount = 0; code->savedintcount = INT_SAV_CNT - rd->savintreguse; code->savedfltcount = FLT_SAV_CNT - rd->savfltreguse; code->memuse = rd->memuse; @@ -424,6 +480,7 @@ bool replace_create_replacement_points(jitdata *jd) return true; } + /* replace_free_replacement_points ********************************************* Free memory used by replacement points. @@ -450,6 +507,7 @@ void replace_free_replacement_points(codeinfo *code) code->globalcount = 0; } + /* replace_activate_replacement_point ****************************************** Activate a replacement point. When this function returns, the @@ -465,20 +523,21 @@ void replace_free_replacement_points(codeinfo *code) void replace_activate_replacement_point(rplpoint *rp,rplpoint *target) { assert(rp->target == NULL); - -#ifndef NDEBUG + +#if !defined(NDEBUG) printf("activate replacement point: "); - replace_replacement_point_println(rp); + replace_replacement_point_println(rp, 0); fflush(stdout); #endif - + rp->target = target; - + #if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT) md_patch_replacement_point(rp); #endif } + /* replace_deactivate_replacement_point **************************************** Deactivate a replacement point. When this function returns, the @@ -493,42 +552,40 @@ void replace_activate_replacement_point(rplpoint *rp,rplpoint *target) void replace_deactivate_replacement_point(rplpoint *rp) { assert(rp->target); - -#ifndef NDEBUG + +#if !defined(NDEBUG) printf("deactivate replacement point: "); - replace_replacement_point_println(rp); + replace_replacement_point_println(rp, 0); fflush(stdout); #endif - + rp->target = NULL; - + #if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT) md_patch_replacement_point(rp); #endif } -/* replace_read_executionstate ************************************************* - Read the given executions state and translate it to a source state. +/* replace_read_value ********************************************************** + + Read a value with the given allocation from the execution state. IN: - rp...............replacement point at which `es` was taken es...............execution state - ss...............where to put the source state + sp...............stack pointer of the execution state (XXX eliminate?) + ra...............allocation + javaval..........where to put the value OUT: - *ss..............the source state derived from the execution state + *javaval.........the value *******************************************************************************/ -inline static void replace_read_value(executionstate *es, -#ifdef HAS_4BYTE_STACKSLOT - u4 *sp, -#else - u8 *sp, -#endif - rplalloc *ra, - u8 *javaval) +static void replace_read_value(executionstate_t *es, + stackslot_t *sp, + rplalloc *ra, + u8 *javaval) { if (ra->flags & INMEMORY) { /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */ @@ -554,14 +611,23 @@ inline static void replace_read_value(executionstate *es, } } -inline static void replace_write_value(executionstate *es, -#ifdef HAS_4BYTE_STACKSLOT - u4 *sp, -#else - u8 *sp, -#endif - rplalloc *ra, - u8 *javaval) + +/* replace_write_value ********************************************************* + + Write a value to the given allocation in the execution state. + + IN: + es...............execution state + sp...............stack pointer of the execution state (XXX eliminate?) + ra...............allocation + *javaval.........the value + +*******************************************************************************/ + +static void replace_write_value(executionstate_t *es, + stackslot_t *sp, + rplalloc *ra, + u8 *javaval) { if (ra->flags & INMEMORY) { /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */ @@ -587,36 +653,41 @@ inline static void replace_write_value(executionstate *es, } } -static void replace_read_executionstate(rplpoint *rp,executionstate *es, - sourcestate *ss) + +/* replace_read_executionstate ************************************************* + + Read the given executions state and translate it to a source state. + + IN: + rp...............replacement point at which `es` was taken + es...............execution state + ss...............where to put the source state + + OUT: + *ss..............the source state derived from the execution state + +*******************************************************************************/ + +static void replace_read_executionstate(rplpoint *rp,executionstate_t *es, + sourcestate_t *ss) { - methodinfo *m; - codeinfo *code; - int count; - int i; - rplalloc *ra; - methoddesc *md; - int topslot; -#ifdef HAS_4BYTE_STACKSLOT - u4 *sp; - u4 *basesp; -#else - u8 *sp; - u8 *basesp; -#endif + methodinfo *m; + codeinfo *code; + int count; + int i; + rplalloc *ra; + sourceframe_t *frame; + int topslot; + stackslot_t *sp; + stackslot_t *basesp; code = rp->code; - m = code->m; - md = m->parseddesc; + m = rp->method; topslot = TOP_IS_NORMAL; - /* stack pointers */ + /* stack pointer */ -#ifdef HAS_4BYTE_STACKSLOT - sp = (u4*) es->sp; -#else - sp = (u8*) es->sp; -#endif + sp = (stackslot_t *) es->sp; /* on some architectures the returnAddress is passed on the stack by JSR */ @@ -639,23 +710,30 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es, } /* calculate base stack pointer */ - + basesp = sp + code_get_stack_frame_size(code); - ss->stackbase = (u1*) basesp; + /* create the source frame */ + + frame = DNEW(sourceframe_t); + frame->up = ss->frames; + frame->method = rp->method; + frame->id = rp->id; + + ss->frames = frame; /* read local variables */ - count = m->maxlocals; /* XXX inlining */ - ss->javalocalcount = count; - ss->javalocals = DMNEW(u8, count); - ss->javalocaltype = DMNEW(u1, count); + count = m->maxlocals; + frame->javalocalcount = count; + frame->javalocals = DMNEW(u8, count); + frame->javalocaltype = DMNEW(u1, count); -#ifndef NDEBUG +#if !defined(NDEBUG) /* mark values as undefined */ for (i=0; ijavalocals[i] = (u8) 0x00dead0000dead00ULL; - ss->javalocaltype[i] = TYPE_VOID; + frame->javalocals[i] = (u8) 0x00dead0000dead00ULL; + frame->javalocaltype[i] = TYPE_VOID; } /* some entries in the intregs array are not meaningful */ @@ -664,22 +742,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es, #ifdef REG_PV es->intregs[REG_PV ] = (u8) 0x11dead1111dead11ULL; #endif -#endif /* NDEBUG */ - -#if 0 - ra = code->regalloc; - - i = -1; - for (allocs = code->globalcount; allocs--; ra++) { - if (ra->next) - i++; - t = ra->type; - if (t == -1) - continue; /* dummy rplalloc */ - - replace_read_value(es,sp,ra,ss->javalocals + (5*i+t)); - } -#endif +#endif /* !defined(NDEBUG) */ /* read javalocals */ @@ -687,33 +750,36 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es, ra = rp->regalloc; while (count && (i = ra->index) >= 0) { - ss->javalocaltype[i] = ra->type; - replace_read_value(es, sp, ra, ss->javalocals + i); + assert(i < m->maxlocals); + frame->javalocaltype[i] = ra->type; + replace_read_value(es, sp, ra, frame->javalocals + i); ra++; count--; } /* read stack slots */ - ss->javastackdepth = count; - ss->javastack = DMNEW(u8, count); - ss->javastacktype = DMNEW(u1, count); + frame->javastackdepth = count; + frame->javastack = DMNEW(u8, count); + frame->javastacktype = DMNEW(u1, count); -#ifndef NDEBUG +#if !defined(NDEBUG) /* mark values as undefined */ - for (i=0; ijavastack[i] = (u8) 0x00dead0000dead00ULL; -#endif - + for (i=0; ijavastack[i] = (u8) 0x00dead0000dead00ULL; + frame->javastacktype[i] = TYPE_VOID; + } +#endif /* !defined(NDEBUG) */ + i = 0; /* the first stack slot is special in SBR and EXH blocks */ if (topslot == TOP_IS_ON_STACK) { assert(count); - - ss->javastack[i] = sp[-1]; - ss->javastacktype[i] = TYPE_ADR; /* XXX RET */ + + frame->javastack[i] = sp[-1]; + frame->javastacktype[i] = TYPE_ADR; /* XXX RET */ count--; i++; ra++; @@ -721,67 +787,33 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es, else if (topslot == TOP_IS_IN_ITMP1) { assert(count); - ss->javastack[i] = es->intregs[REG_ITMP1]; - ss->javastacktype[i] = TYPE_ADR; /* XXX RET */ + frame->javastack[i] = es->intregs[REG_ITMP1]; + frame->javastacktype[i] = TYPE_ADR; /* XXX RET */ count--; i++; ra++; } - + /* read remaining stack slots */ - + for (; count--; ra++, i++) { assert(ra->index == -1); - replace_read_value(es,sp,ra,ss->javastack + i); - ss->javastacktype[i] = ra->type; - } - - /* read unused callee saved int regs */ - - count = INT_SAV_CNT; - for (i=0; count > code->savedintcount; ++i) { - assert(i < INT_REG_CNT); - if (nregdescint[i] == REG_SAV) - ss->savedintregs[--count] = es->intregs[i]; - } - - /* read saved int regs */ - - for (i=0; isavedintcount; ++i) { - ss->savedintregs[i] = *--basesp; - } - - /* read unused callee saved flt regs */ - - count = FLT_SAV_CNT; - for (i=0; count > code->savedfltcount; ++i) { - assert(i < FLT_REG_CNT); - if (nregdescfloat[i] == REG_SAV) - ss->savedfltregs[--count] = es->fltregs[i]; - } - - /* read saved flt regs */ - - for (i=0; isavedfltcount; ++i) { -#ifdef HAS_4BYTE_STACKSLOT - basesp -= 2; -#else - basesp--; -#endif - ss->savedfltregs[i] = *(u8*)basesp; + replace_read_value(es,sp,ra,frame->javastack + i); + frame->javastacktype[i] = ra->type; } /* read slots used for synchronization */ count = code_get_sync_slot_count(code); - ss->syncslotcount = count; - ss->syncslots = DMNEW(u8,count); + frame->syncslotcount = count; + frame->syncslots = DMNEW(u8,count); for (i=0; isyncslots[i] = sp[code->memuse + i]; + frame->syncslots[i] = sp[code->memuse + i]; } } + /* replace_write_executionstate ************************************************ Translate the given source state into an execution state. @@ -797,38 +829,35 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es, *******************************************************************************/ -static void replace_write_executionstate(rplpoint *rp,executionstate *es, - sourcestate *ss) +static void replace_write_executionstate(rplpoint *rp, + executionstate_t *es, + sourcestate_t *ss) { - methodinfo *m; - codeinfo *code; - int count; - int i; - rplalloc *ra; - methoddesc *md; - int topslot; -#ifdef HAS_4BYTE_STACKSLOT - u4 *sp; - u4 *basesp; -#else - u8 *sp; - u8 *basesp; -#endif + methodinfo *m; + codeinfo *code; + int count; + int i; + rplalloc *ra; + sourceframe_t *frame; + int topslot; + stackslot_t *sp; + stackslot_t *basesp; code = rp->code; - m = code->m; - md = m->parseddesc; + m = rp->method; topslot = TOP_IS_NORMAL; - + + /* pop a source frame */ + + frame = ss->frames; + assert(frame); + ss->frames = frame->up; + /* calculate stack pointer */ - -#ifdef HAS_4BYTE_STACKSLOT - basesp = (u4*) ss->stackbase; -#else - basesp = (u8*) ss->stackbase; -#endif - - sp = basesp - code_get_stack_frame_size(code); + + sp = (stackslot_t *) es->sp; + + basesp = sp + code_get_stack_frame_size(code); /* on some architectures the returnAddress is passed on the stack by JSR */ @@ -837,56 +866,27 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es, topslot = TOP_IS_ON_STACK; /* XXX */ } #endif - + /* in some cases the top stack slot is passed in REG_ITMP1 */ if ( (rp->type == BBTYPE_EXH) #if defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) - || (rp->type == BBTYPE_SBR) /* XXX */ + || (rp->type == BBTYPE_SBR) /* XXX */ #endif ) { topslot = TOP_IS_IN_ITMP1; } - /* in debug mode, invalidate stack frame first */ - -#ifndef NDEBUG - for (i=0; i<(basesp - sp); ++i) { - sp[i] = 0xdeaddeadU; - } -#endif - -#if 0 - /* write local variables */ - - count = m->maxlocals; /* XXX inlining */ - - ra = code->regalloc; - - i = -1; - for (allocs = code->globalcount; allocs--; ra++) { - if (ra->next) - i++; - - assert(i >= 0 && i < m->maxlocals); - - t = ra->type; - if (t == -1) - continue; /* dummy rplalloc */ - - replace_write_value(es,sp,ra,ss->javalocals + (5*i+t)); - } -#endif - /* write javalocals */ ra = rp->regalloc; count = rp->regalloccount; while (count && (i = ra->index) >= 0) { - assert(ra->type == ss->javalocaltype[i]); - replace_write_value(es, sp, ra, ss->javalocals + i); + assert(i < m->maxlocals); + assert(ra->type == frame->javalocaltype[i]); + replace_write_value(es, sp, ra, frame->javalocals + i); count--; ra++; } @@ -899,9 +899,9 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es, if (topslot == TOP_IS_ON_STACK) { assert(count); - - assert(ss->javastacktype[i] == TYPE_ADR); - sp[-1] = ss->javastack[i]; + + assert(frame->javastacktype[i] == TYPE_ADR); + sp[-1] = frame->javastack[i]; count--; i++; ra++; @@ -909,64 +909,29 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es, else if (topslot == TOP_IS_IN_ITMP1) { assert(count); - assert(ss->javastacktype[i] == TYPE_ADR); - assert(ss->javastacktype[i] == TYPE_ADR); - es->intregs[REG_ITMP1] = ss->javastack[i]; + assert(frame->javastacktype[i] == TYPE_ADR); + assert(frame->javastacktype[i] == TYPE_ADR); + es->intregs[REG_ITMP1] = frame->javastack[i]; count--; i++; ra++; } /* write remaining stack slots */ - + for (; count--; ra++, i++) { assert(ra->index == -1); - assert(ra->type == ss->javastacktype[i]); - replace_write_value(es,sp,ra,ss->javastack + i); - } - - /* write unused callee saved int regs */ - - count = INT_SAV_CNT; - for (i=0; count > code->savedintcount; ++i) { - assert(i < INT_REG_CNT); - if (nregdescint[i] == REG_SAV) - es->intregs[i] = ss->savedintregs[--count]; - } - - /* write saved int regs */ - - for (i=0; isavedintcount; ++i) { - *--basesp = ss->savedintregs[i]; - } - - /* write unused callee saved flt regs */ - - count = FLT_SAV_CNT; - for (i=0; count > code->savedfltcount; ++i) { - assert(i < FLT_REG_CNT); - if (nregdescfloat[i] == REG_SAV) - es->fltregs[i] = ss->savedfltregs[--count]; - } - - /* write saved flt regs */ - - for (i=0; isavedfltcount; ++i) { -#ifdef HAS_4BYTE_STACKSLOT - basesp -= 2; -#else - basesp--; -#endif - *(u8*)basesp = ss->savedfltregs[i]; + assert(ra->type == frame->javastacktype[i]); + replace_write_value(es,sp,ra,frame->javastack + i); } /* write slots used for synchronization */ count = code_get_sync_slot_count(code); - assert(count == ss->syncslotcount); + assert(count == frame->syncslotcount); for (i=0; imemuse + i] = ss->syncslots[i]; + sp[code->memuse + i] = frame->syncslots[i]; } /* set new pc */ @@ -975,30 +940,80 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es, } -void replace_pop_activation_record(executionstate *es, sourcestate *ss) +/* replace_pop_activation_record *********************************************** + + Peel a stack frame from the execution state. + + *** This function imitates the effects of the method epilog *** + *** and returning from the method call. *** + + IN: + es...............execution state + + OUT: + *es..............the execution state after popping the stack frame + +*******************************************************************************/ + +bool replace_pop_activation_record(executionstate_t *es) { u1 *ra; u1 *pv; s4 reg; s4 i; + codeinfo *code; + stackslot_t *basesp; assert(es->code); - /* restore saved registers */ + /* read the return address */ + + ra = md_stacktrace_get_returnaddress(es->sp, + SIZE_OF_STACKSLOT * es->code->stackframesize); + + printf("return address: %p\n", (void*)ra); + + /* find the new codeinfo */ + + pv = md_codegen_get_pv_from_pc(ra); + + printf("PV = %p\n", (void*) pv); + + if (pv == NULL) + return false; + + code = *(codeinfo **)(pv + CodeinfoPointer); + + printf("CODE = %p\n", (void*) code); + + if (code == NULL) + return false; + + /* calculate the base of the stack frame */ + + basesp = (stackslot_t *)es->sp + es->code->stackframesize; + + /* restore saved int registers */ reg = INT_REG_CNT; - for (i=0; icode->savedintcount; ++i) { while (nregdescint[--reg] != REG_SAV) ; - es->intregs[reg] = ss->savedintregs[i]; + es->intregs[reg] = *--basesp; } - /* read the return address */ + /* restore saved flt registers */ - ra = md_stacktrace_get_returnaddress(es->sp, - SIZE_OF_STACKSLOT * es->code->stackframesize); + /* XXX align? */ + reg = FLT_REG_CNT; + for (i=0; icode->savedfltcount; ++i) { + while (nregdescfloat[--reg] != REG_SAV) + ; + basesp -= STACK_SLOTS_PER_FLOAT; + es->fltregs[reg] = *(u8*)basesp; + } - printf("return address: %p\n", (void*)ra); + /* set the new pc */ es->pc = ra; @@ -1007,14 +1022,159 @@ void replace_pop_activation_record(executionstate *es, sourcestate *ss) es->sp += SIZE_OF_STACKSLOT * es->code->stackframesize; es->sp += SIZE_OF_STACKSLOT; /* skip return address */ - /* find the new codeinfo */ - - pv = md_codegen_get_pv_from_pc(es->pc); es->pv = pv; + es->code = code; + +#if !defined(NDEBUG) + /* for debugging */ + for (i=0; iintregs[i] = 0x33dead3333dead33ULL; + for (i=0; ifltregs[i] = 0x33dead3333dead33ULL; +#endif /* !defined(NDEBUG) */ + + return true; +} + + +/* replace_push_activation_record ********************************************** + + Push a stack frame onto the execution state. + + *** This function imitates the effects of a call and the *** + *** method prolog of the callee. *** + + IN: + es...............execution state + rpcall...........the replacement point at the call site + calleecode.......the codeinfo of the callee + + OUT: + *es..............the execution state after pushing the stack frame + +*******************************************************************************/ + +void replace_push_activation_record(executionstate_t *es, + rplpoint *rpcall, + codeinfo *calleecode) +{ + s4 reg; + s4 i; + stackslot_t *basesp; + + /* write the return address */ + + *((stackslot_t *)es->sp) = (stackslot_t) (rpcall->pc + rpcall->callsize); + + es->sp -= SIZE_OF_STACKSLOT; + + /* we move into a new code unit */ - if (pv) { - es->code = *(codeinfo **)(pv + CodeinfoPointer); + es->code = calleecode; + + /* set the new pc XXX not needed */ + + es->pc = es->code->entrypoint; + + /* build the stackframe */ + + basesp = (stackslot_t *) es->sp; + es->sp -= SIZE_OF_STACKSLOT * es->code->stackframesize; + + /* in debug mode, invalidate stack frame first */ + +#if !defined(NDEBUG) + { + stackslot_t *sp = (stackslot_t *) es->sp; + for (i=0; i<(basesp - sp); ++i) { + sp[i] = 0xdeaddeadU; + } } +#endif + + /* save int registers */ + + reg = INT_REG_CNT; + for (i=0; icode->savedintcount; ++i) { + while (nregdescint[--reg] != REG_SAV) + ; + *--basesp = es->intregs[reg]; + +#if !defined(NDEBUG) + es->intregs[reg] = 0x44dead4444dead44ULL; +#endif + } + + /* save flt registers */ + + /* XXX align? */ + reg = FLT_REG_CNT; + for (i=0; icode->savedfltcount; ++i) { + while (nregdescfloat[--reg] != REG_SAV) + ; + basesp -= STACK_SLOTS_PER_FLOAT; + *(u8*)basesp = es->fltregs[reg]; + +#if !defined(NDEBUG) + es->fltregs[reg] = 0x44dead4444dead44ULL; +#endif + } + + /* set the PV */ + + es->pv = es->code->entrypoint; +} + + +/* replace_find_replacement_point ********************************************** + + Find the replacement point in the given code corresponding to the + position given in the source frame. + + IN: + code.............the codeinfo in which to search the rplpoint + ss...............the source state defining the position to look for + + RETURN VALUE: + the replacement point + +*******************************************************************************/ + +rplpoint * replace_find_replacement_point(codeinfo *code, sourcestate_t *ss) +{ + sourceframe_t *frame; + methodinfo *m; + rplpoint *rp; + s4 i; + + assert(ss); + + frame = ss->frames; + assert(frame); + +#if !defined(NDEBUG) + printf("searching replacement point for:\n"); + replace_source_frame_println(frame); +#endif + + m = frame->method; + +#if !defined(NDEBUG) + printf("code = %p\n", (void*)code); +#endif + + rp = code->rplpoints; + i = code->rplpointcount; + while (i--) { + if (rp->id == frame->id) + return rp; + rp++; + } + + assert(0); + return NULL; /* NOT REACHED */ } @@ -1032,16 +1192,17 @@ void replace_pop_activation_record(executionstate *es, sourcestate *ss) *******************************************************************************/ -void replace_me(rplpoint *rp,executionstate *es) +void replace_me(rplpoint *rp, executionstate_t *es) { - rplpoint *target; - sourcestate ss; - s4 dumpsize; - rplpoint *candidate; - s4 i; + rplpoint *target; + sourcestate_t ss; + s4 dumpsize; + rplpoint *candidate; + codeinfo *code; + s4 i; es->code = rp->code; - + /* mark start of dump memory area */ dumpsize = dump_size(); @@ -1053,49 +1214,97 @@ void replace_me(rplpoint *rp,executionstate *es) /* XXX DEBUG turn off self-replacement */ if (target == rp) replace_deactivate_replacement_point(rp); - -#ifndef NDEBUG + +#if !defined(NDEBUG) printf("replace_me(%p,%p)\n",(void*)rp,(void*)es); fflush(stdout); - replace_replacement_point_println(rp); + replace_replacement_point_println(rp, 0); replace_executionstate_println(es); #endif /* read execution state of old code */ - replace_read_executionstate(rp,es,&ss); - -#ifndef NDEBUG - replace_sourcestate_println(&ss); -#endif + ss.frames = NULL; /* XXX testing */ + candidate = rp; do { - replace_pop_activation_record(es, &ss); - replace_executionstate_println(es); - candidate = NULL; - rp = es->code->rplpoints; - for (i=0; icode->rplpointcount; ++i, ++rp) - if (rp->pc <= es->pc) - candidate = rp; - - if (candidate) { - replace_read_executionstate(candidate,es,&ss); - replace_sourcestate_println(&ss); +#if !defined(NDEBUG) + printf("recovering source state for:\n"); + replace_replacement_point_println(candidate, 1); +#endif + + replace_read_executionstate(candidate,es,&ss); + + if (candidate->parent) { + printf("INLINED!\n"); + candidate = candidate->parent; + assert(candidate->type == RPLPOINT_TYPE_INLINE); + } + else { + printf("UNWIND\n"); + if (!replace_pop_activation_record(es)) { + printf("BREAKING\n"); + break; + } +#if !defined(NDEBUG) + replace_executionstate_println(es); +#endif + candidate = NULL; + rp = es->code->rplpoints; + for (i=0; icode->rplpointcount; ++i, ++rp) + if (rp->pc <= es->pc) + candidate = rp; + if (!candidate) + printf("NO CANDIDATE!\n"); + else { + printf("found replacement point.\n"); + assert(candidate->type == RPLPOINT_TYPE_CALL); + } } } while (candidate); +#if !defined(NDEBUG) + replace_sourcestate_println(&ss); +#endif + /* write execution state of new code */ - replace_write_executionstate(target,es,&ss); +#if !defined(NDEBUG) + replace_executionstate_println(es); +#endif + + code = es->code; - es->code = target->code; -#ifndef NDEBUG + while (ss.frames) { + + candidate = replace_find_replacement_point(code, &ss); + +#if !defined(NDEBUG) + printf("creating execution state for:\n"); + replace_replacement_point_println(candidate, 1); +#endif + + replace_write_executionstate(candidate, es, &ss); + if (ss.frames == NULL) + break; + + if (candidate->type == RPLPOINT_TYPE_CALL) { + code = ss.frames->method->code; + assert(code); + replace_push_activation_record(es, candidate, code); + } +#if !defined(NDEBUG) + replace_executionstate_println(es); +#endif + } + +#if !defined(NDEBUG) replace_executionstate_println(es); #endif - + /* release dump area */ dump_release(dumpsize); @@ -1105,9 +1314,10 @@ void replace_me(rplpoint *rp,executionstate *es) #if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT) asm_replacement_in(es); #endif - abort(); + abort(); /* NOT REACHED */ } + /* replace_replacement_point_println ******************************************* Print replacement point info. @@ -1117,23 +1327,39 @@ void replace_me(rplpoint *rp,executionstate *es) *******************************************************************************/ -#ifndef NDEBUG +#if !defined(NDEBUG) static const char *type_char = "IJFDA"; #define TYPECHAR(t) (((t) >= 0 && (t) <= 4) ? type_char[t] : '?') -void replace_replacement_point_println(rplpoint *rp) +static char *replace_type_str[] = { + "STD", + "EXH", + "SBR", + "CALL", + "INLINE", + "RETURN" +}; + +void replace_replacement_point_println(rplpoint *rp, int depth) { int j; - if (!rp) { + if (!rp) { printf("(rplpoint *)NULL\n"); return; } - printf("rplpoint %p pc:%p out:%p target:%p mcode:%016llx type:%01d flags:%01x\n\t\tra:%d = [", - (void*)rp,rp->pc,rp->outcode,(void*)rp->target, - (unsigned long long)rp->mcode,rp->type,rp->flags,rp->regalloccount); + for (j=0; jpc,rp->callsize,rp->outcode,(void*)rp->target, + (unsigned long long)rp->mcode,replace_type_str[rp->type],rp->flags, + (void*)rp->parent); + for (j=0; jregalloccount); for (j=0; jregalloccount; ++j) { if (j) @@ -1145,13 +1371,17 @@ void replace_replacement_point_println(rplpoint *rp) show_allocation(rp->regalloc[j].type, rp->regalloc[j].flags, rp->regalloc[j].regoff); } - printf("]\n\t\tmethod: "); - method_print(rp->code->m); + printf("]\n"); + for (j=0; jmethod); printf("\n"); } #endif + /* replace_show_replacement_points ********************************************* Print replacement point info. @@ -1161,29 +1391,20 @@ void replace_replacement_point_println(rplpoint *rp) *******************************************************************************/ -#ifndef NDEBUG +#if !defined(NDEBUG) void replace_show_replacement_points(codeinfo *code) { int i; + int depth; rplpoint *rp; - + rplpoint *parent; + if (!code) { printf("(codeinfo *)NULL\n"); return; } printf("\treplacement points: %d\n",code->rplpointcount); -#if 0 - printf("\tglobal allocations: %d = [",code->globalcount); - - for (i=0; iglobalcount; ++i) - printf("%c%1c%01x:%02d", - (code->regalloc[i].next) ? '^' : ' ', - TYPECHAR(code->regalloc[i].type), - code->regalloc[i].flags,code->regalloc[i].regoff); - - printf("]\n"); -#endif printf("\ttotal allocations : %d\n",code->regalloccount); printf("\tsaved int regs : %d\n",code->savedintcount); @@ -1196,13 +1417,19 @@ void replace_show_replacement_points(codeinfo *code) rp = code->rplpoints + i; assert(rp->code == code); - - printf("\t"); - replace_replacement_point_println(rp); + + depth = 1; + parent = rp->parent; + while (parent) { + depth++; + parent = parent->parent; + } + replace_replacement_point_println(rp, depth); } } #endif + /* replace_executionstate_println ********************************************** Print execution state @@ -1212,40 +1439,44 @@ void replace_show_replacement_points(codeinfo *code) *******************************************************************************/ -#ifndef NDEBUG -void replace_executionstate_println(executionstate *es) +#if !defined(NDEBUG) +void replace_executionstate_println(executionstate_t *es) { int i; int slots; -#ifdef HAS_4BYTE_STACKSLOT - u4 *sp; -#else - u8 *sp; -#endif + stackslot_t *sp; - if (!es) { - printf("(executionstate *)NULL\n"); + if (!es) { + printf("(executionstate_t *)NULL\n"); return; } - printf("executionstate %p:\n",(void*)es); - printf("\tpc = %p\n",(void*)es->pc); - printf("\tsp = %p\n",(void*)es->sp); - printf("\tpv = %p\n",(void*)es->pv); + printf("executionstate_t:\n"); + printf("\tpc = %p",(void*)es->pc); + printf(" sp = %p",(void*)es->sp); + printf(" pv = %p\n",(void*)es->pv); #if defined(ENABLE_DISASSEMBLER) for (i=0; iintregs[i]); + if (i%4 == 0) + printf("\t"); + else + printf(" "); + printf("%-3s = %016llx",regs[i],(unsigned long long)es->intregs[i]); + if (i%4 == 3) + printf("\n"); } for (i=0; ifltregs[i]); + if (i%4 == 0) + printf("\t"); + else + printf(" "); + printf("F%02d = %016llx",i,(unsigned long long)es->fltregs[i]); + if (i%4 == 3) + printf("\n"); } #endif -#ifdef HAS_4BYTE_STACKSLOT - sp = (u4*) es->sp; -#else - sp = (u8*) es->sp; -#endif + sp = (stackslot_t *) es->sp; if (es->code) slots = code_get_stack_frame_size(es->code); @@ -1253,14 +1484,23 @@ void replace_executionstate_println(executionstate *es) slots = 0; if (slots) { - printf("\tstack slots(+1) at sp:\n"); + printf("\tstack slots(+1) at sp:"); for (i=0; i= slots) + putchar('('); #ifdef HAS_4BYTE_STACKSLOT - printf("\t\t%08lx\n",(unsigned long)*sp++); + printf("%08lx",(unsigned long)*sp++); #else - printf("\t\t%016llx\n",(unsigned long long)*sp++); + printf("%016llx",(unsigned long long)*sp++); #endif + if (i >= slots) + putchar(')'); } + printf("\n"); } printf("\tcode: %p", (void*)es->code); @@ -1303,91 +1543,87 @@ void java_value_print(s4 type, u8 value) printf(" %lld", (long long) value); } } -#endif /* defined(NDEBUG) */ +#endif /* !defined(NDEBUG) */ -/* replace_sourcestate_println ************************************************* - - Print source state - - IN: - ss...............the source state to print - -*******************************************************************************/ -#ifndef NDEBUG -void replace_sourcestate_println(sourcestate *ss) +#if !defined(NDEBUG) +void replace_source_frame_println(sourceframe_t *frame) { - int i; - int t; - int reg; - - if (!ss) { - printf("(sourcestate *)NULL\n"); - return; - } + s4 i; + s4 t; - printf("sourcestate %p: stackbase=%p\n",(void*)ss,(void*)ss->stackbase); + printf("\t"); + method_println(frame->method); + printf("\n"); - printf("\tlocals (%d):\n",ss->javalocalcount); - for (i=0; ijavalocalcount; ++i) { - t = ss->javalocaltype[i]; - if (t == TYPE_VOID) { - printf("\tlocal[ %2d] = void\n",i); - } - else { - printf("\tlocal[%c%2d] = ",TYPECHAR(t),i); - java_value_print(t, ss->javalocals[i]); - printf("\n"); + if (frame->javalocalcount) { + printf("\tlocals (%d):\n",frame->javalocalcount); + for (i=0; ijavalocalcount; ++i) { + t = frame->javalocaltype[i]; + if (t == TYPE_VOID) { + printf("\tlocal[ %2d] = void\n",i); + } + else { + printf("\tlocal[%c%2d] = ",TYPECHAR(t),i); + java_value_print(t, frame->javalocals[i]); + printf("\n"); + } } + printf("\n"); } - printf("\n"); - - printf("\tstack (depth %d):\n",ss->javastackdepth); - for (i=0; ijavastackdepth; ++i) { - printf("\tstack[%2d] = ",i); - java_value_print(ss->javastacktype[i], ss->javastack[i]); + if (frame->javastackdepth) { + printf("\tstack (depth %d):\n",frame->javastackdepth); + for (i=0; ijavastackdepth; ++i) { + printf("\tstack[%2d] = ",i); + java_value_print(frame->javastacktype[i], frame->javastack[i]); + printf("\n"); + } printf("\n"); } - printf("\n"); - - printf("\tsaved int registers (%d):\n",INT_SAV_CNT); - reg = INT_REG_CNT; - for (i=0; isavedintregs[i] != 0x00dead0000dead00ULL) { -#if defined(ENABLE_DISASSEMBLER) - printf("\t%-3s = ",regs[reg]); + if (frame->syncslotcount) { + printf("\tsynchronization slots (%d):\n",frame->syncslotcount); + for (i=0; isyncslotcount; ++i) { + printf("\tslot[%2d] = ",i); +#ifdef HAS_4BYTE_STACKSLOT + printf("%08lx\n",(unsigned long) frame->syncslots[i]); +#else + printf("%016llx\n",(unsigned long long) frame->syncslots[i]); #endif - printf("%016llx\n",(unsigned long long) ss->savedintregs[i]); } + printf("\n"); } +} +#endif /* !defined(NDEBUG) */ - printf("\n"); - printf("\tsaved float registers (%d):\n",FLT_SAV_CNT); - for (i=0; isavedfltregs[i] != 0x00dead0000dead00ULL) { - printf("\tsavedfltreg[%2d] = ",i); - printf("%016llx\n",(unsigned long long) ss->savedfltregs[i]); - } +/* replace_sourcestate_println ************************************************* + + Print source state + + IN: + ss...............the source state to print + +*******************************************************************************/ + +#if !defined(NDEBUG) +void replace_sourcestate_println(sourcestate_t *ss) +{ + int i; + sourceframe_t *frame; + + if (!ss) { + printf("(sourcestate_t *)NULL\n"); + return; } - - printf("\n"); - printf("\tsynchronization slots (%d):\n",ss->syncslotcount); - for (i=0; isyncslotcount; ++i) { - printf("\tslot[%2d] = ",i); -#ifdef HAS_4BYTE_STACKSLOT - printf("%08lx\n",(unsigned long) ss->syncslots[i]); -#else - printf("%016llx\n",(unsigned long long) ss->syncslots[i]); -#endif + printf("sourcestate_t:\n"); + + for (i=0, frame = ss->frames; frame != NULL; frame = frame->up, ++i) { + printf(" frame %d:\n", i); + replace_source_frame_println(frame); } - - printf("\n"); } #endif diff --git a/src/vm/jit/replace.h b/src/vm/jit/replace.h index 15a7125fd..0cd6b2d10 100644 --- a/src/vm/jit/replace.h +++ b/src/vm/jit/replace.h @@ -39,8 +39,9 @@ /* forward typedefs ***********************************************************/ typedef struct rplpoint rplpoint; -typedef struct executionstate executionstate; -typedef struct sourcestate sourcestate; +typedef struct executionstate_t executionstate_t; +typedef struct sourcestate_t sourcestate_t; +typedef struct sourceframe_t sourceframe_t; #include "config.h" #include "vm/types.h" @@ -70,24 +71,39 @@ struct rplalloc { #error value of INMEMORY is too big to fit in rplalloc.flags #endif + +/* XXX what to do about overlapping rplpoints? */ +#define RPLPOINT_TYPE_STD BBTYPE_STD +#define RPLPOINT_TYPE_EXH BBTYPE_EXH +#define RPLPOINT_TYPE_SBR BBTYPE_SBR +#define RPLPOINT_TYPE_CALL 3 +#define RPLPOINT_TYPE_INLINE 4 +#define RPLPOINT_TYPE_RETURN 5 + + /* An `rplpoint` represents a replacement point in a compiled method */ struct rplpoint { u1 *pc; /* machine code PC of this point */ - u1 *outcode; /* pointer to replacement-out code */ - codeinfo *code; /* codeinfo this point belongs to */ - rplpoint *target; /* target of the replacement */ - u8 mcode; /* saved maching code for patching */ + u1 *outcode; /* pointer to replacement-out code */ /* XXX only for trappable rps */ + methodinfo *method; /* source method this point is in */ + rplpoint *target; /* target of the replacement */ /* XXX remove? */ + codeinfo *code; /* codeinfo this point belongs to */ /* XXX unify with parent */ + rplpoint *parent; /* rplpoint of the inlined body */ /* XXX unify with code */ rplalloc *regalloc; /* pointer to register index table */ + u8 mcode; /* saved maching code for patching */ /* XXX only for trappable rps */ + s4 id; /* id of the rplpoint within method */ + s4 callsize; /* size of call code in bytes */ unsigned int regalloccount:24; /* number of local allocations */ - unsigned int type:4; /* BBTYPE_... constant */ + unsigned int type:4; /* RPLPOINT_TYPE_... constant */ unsigned int flags:8; /* OR of RPLPOINT_... constants */ }; + /* An `executionsstate` represents the state of a thread as it reached */ /* an replacement point or is about to enter one. */ -struct executionstate { +struct executionstate_t { u1 *pc; /* program counter */ u1 *sp; /* stack pointer within method */ u1 *pv; /* procedure value. NULL means */ @@ -96,29 +112,34 @@ struct executionstate { u8 intregs[INT_REG_CNT]; /* register values */ u8 fltregs[FLT_REG_CNT]; /* register values */ - codeinfo *code; + codeinfo *code; /* codeinfo corresponding to the pv */ }; -/* `sourcestate` will probably only be used for debugging */ -struct sourcestate { - u8 *javastack; - u1 *javastacktype; - s4 javastackdepth; +struct sourceframe_t { + sourceframe_t *up; /* source frame above this one */ - u8 *javalocals; - u1 *javalocaltype; - s4 javalocalcount; + methodinfo *method; /* method this frame is in */ + s4 id; - u8 savedintregs[INT_SAV_CNT + 1]; /* XXX */ - u8 savedfltregs[FLT_SAV_CNT + 1]; /* XXX */ + u8 *javastack; /* values of stack vars */ + u1 *javastacktype; /* types of stack vars */ + s4 javastackdepth; /* number of stack vars */ - u8 *syncslots; - s4 syncslotcount; + u8 *javalocals; /* values of javalocals */ + u1 *javalocaltype; /* types of javalocals */ + s4 javalocalcount; /* number of javalocals */ - u1 *stackbase; + u8 *syncslots; + s4 syncslotcount; /* XXX do we need more than one? */ }; + +struct sourcestate_t { + sourceframe_t *frames; /* list of source frames, from bottom up */ +}; + + /*** prototypes ********************************************************/ bool replace_create_replacement_points(jitdata *jd); @@ -128,16 +149,16 @@ void replace_activate_replacement_point(rplpoint *rp,rplpoint *target); void replace_deactivate_replacement_point(rplpoint *rp); void replace_activate(codeinfo *code,codeinfo *target); -void replace_pop_activation_record(executionstate *es, - sourcestate *ss); +bool replace_pop_activation_record(executionstate_t *es); -void replace_me(rplpoint *rp,executionstate *es); +void replace_me(rplpoint *rp,executionstate_t *es); -#ifndef NDEBUG +#if !defined(NDEBUG) void replace_show_replacement_points(codeinfo *code); -void replace_replacement_point_println(rplpoint *rp); -void replace_executionstate_println(executionstate *es); -void replace_sourcestate_println(sourcestate *ss); +void replace_replacement_point_println(rplpoint *rp, int depth); +void replace_executionstate_println(executionstate_t *es); +void replace_sourcestate_println(sourcestate_t *ss); +void replace_source_frame_println(sourceframe_t *frame); #endif /* machine dependent functions (code in ARCH_DIR/md.c) */ diff --git a/src/vm/jit/show.c b/src/vm/jit/show.c index 1dd2fd34e..9655b00ca 100644 --- a/src/vm/jit/show.c +++ b/src/vm/jit/show.c @@ -66,6 +66,13 @@ static java_objectheader *show_global_lock; #endif +/* prototypes *****************************************************************/ + +#if !defined(NDEBUG) +static void show_variable_intern(jitdata *jd, s4 index, int stage); +#endif + + /* show_init ******************************************************************* Initialized the show subsystem (called by jit_init). @@ -325,7 +332,7 @@ void show_method(jitdata *jd, int stage) #else printf(" M%02d = 0x%02x(sp): ", i, i * 8); #endif - for (j = 0; j < jd->varcount; ++j) { + for (j = 0; j < jd->vartop; ++j) { varinfo *v = VAR(j); if ((v->flags & INMEMORY) && (v->vv.regoff == i)) { show_variable(jd, j, irstage); @@ -389,6 +396,36 @@ void show_method(jitdata *jd, int stage) #endif /* !defined(NDEBUG) */ +#if !defined(NDEBUG) && defined(ENABLE_INLINING) +static void show_inline_info(jitdata *jd, insinfo_inline *ii, s4 opcode, s4 stage) +{ + s4 *jl; + s4 n; + + printf("(pt %d+%d st ", ii->throughcount - ii->stackvarscount, + ii->stackvarscount); + show_variable_array(jd, ii->stackvars, ii->stackvarscount, stage); + + if (opcode == ICMD_INLINE_START || opcode == ICMD_INLINE_END) { + printf(" jl "); + jl = (opcode == ICMD_INLINE_START) ? ii->javalocals_start : ii->javalocals_end; + n = (opcode == ICMD_INLINE_START) ? ii->method->maxlocals : ii->outer->maxlocals; + show_variable_array(jd, jl, n, stage); + } + + printf(") "); + +#if 0 + printf("("); + method_print(ii->outer); + printf(" ==> "); +#endif + + method_print(ii->method); +} +#endif /* !defined(NDEBUG) && defined(ENABLE_INLINING) */ + + /* show_basicblock ************************************************************* Print the intermediate representation of a basic block. @@ -478,10 +515,18 @@ void show_basicblock(jitdata *jd, basicblock *bptr, int stage) printf("IN: "); show_variable_array(jd, bptr->invars, bptr->indepth, irstage); printf(" javalocals: "); - show_variable_array(jd, bptr->javalocals, jd->maxlocals, irstage); + show_variable_array(jd, bptr->javalocals, bptr->method->maxlocals, irstage); printf("\n"); } +#if defined(ENABLE_INLINING) + if (bptr->inlineinfo) { + printf("inlineinfo: "); + show_inline_info(jd, bptr->inlineinfo, -1, irstage); + printf("\n"); + } +#endif /* defined(ENABLE_INLINING) */ + iptr = bptr->iinstr; for (i = 0; i < bptr->icount; i++, iptr++) { @@ -741,12 +786,18 @@ void show_allocation(s4 type, s4 flags, s4 regoff) } void show_variable(jitdata *jd, s4 index, int stage) +{ + show_variable_intern(jd, index, stage); + putchar(' '); +} + +static void show_variable_intern(jitdata *jd, s4 index, int stage) { char type; char kind; varinfo *v; - if (index < 0 || index >= jd->varcount) { + if (index < 0 || index >= jd->vartop) { printf("", index); return; } @@ -790,8 +841,6 @@ void show_variable(jitdata *jd, s4 index, int stage) show_allocation(v->type, v->flags, v->vv.regoff); putchar(')'); } - putchar(' '); - fflush(stdout); } void show_variable_array(jitdata *jd, s4 *vars, int n, int stage) @@ -806,11 +855,11 @@ void show_variable_array(jitdata *jd, s4 *vars, int n, int stage) printf("["); for (i=0; isx.s23.s3.inlineinfo; - printf("("); - method_print(ii->outer); - printf(" ==> "); - method_print(ii->method); - printf(")"); + show_inline_info(jd, ii, opcode, stage); } #endif break; @@ -1318,7 +1363,6 @@ void show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage) } break; - case ICMD_ARETURN: case ICMD_FRETURN: case ICMD_IRETURN: case ICMD_DRETURN: @@ -1326,8 +1370,15 @@ void show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage) SHOW_S1(iptr); break; + case ICMD_ARETURN: case ICMD_ATHROW: SHOW_S1(iptr); + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + /* XXX this needs more work */ +#if 0 + unresolved_class_debug_dump(iptr->sx.s23.s2.uc, stdout); +#endif + } break; case ICMD_COPY: diff --git a/src/vm/jit/tools/genoffsets.c b/src/vm/jit/tools/genoffsets.c index f738b46bc..12227a190 100644 --- a/src/vm/jit/tools/genoffsets.c +++ b/src/vm/jit/tools/genoffsets.c @@ -28,7 +28,7 @@ Changes: Edwin Steiner - $Id: genoffsets.c 4643 2006-03-16 18:38:42Z edwin $ + $Id: genoffsets.c 5950 2006-11-11 17:08:14Z edwin $ */ @@ -58,7 +58,7 @@ int main(int argc, char **argv) printf("#define sizevmarg %3d\n", (s4) sizeof(vm_arg)); printf("#define sizestackframeinfo %3d\n", (s4) sizeof(stackframeinfo)); - printf("#define sizeexecutionstate %3d\n", (s4) sizeof(executionstate)); + printf("#define sizeexecutionstate %3d\n", (s4) sizeof(executionstate_t)); printf("\n\n/* define some offsets */\n\n"); @@ -82,11 +82,11 @@ int main(int argc, char **argv) printf("#define offcast_super_diffval %3d\n", (s4) OFFSET(castinfo, super_diffval)); printf("#define offcast_sub_baseval %3d\n", (s4) OFFSET(castinfo, sub_baseval)); - printf("#define offes_pc %3d\n", (s4) OFFSET(executionstate, pc)); - printf("#define offes_sp %3d\n", (s4) OFFSET(executionstate, sp)); - printf("#define offes_pv %3d\n", (s4) OFFSET(executionstate, pv)); - printf("#define offes_intregs %3d\n", (s4) OFFSET(executionstate, intregs)); - printf("#define offes_fltregs %3d\n", (s4) OFFSET(executionstate, fltregs)); + printf("#define offes_pc %3d\n", (s4) OFFSET(executionstate_t, pc)); + printf("#define offes_sp %3d\n", (s4) OFFSET(executionstate_t, sp)); + printf("#define offes_pv %3d\n", (s4) OFFSET(executionstate_t, pv)); + printf("#define offes_intregs %3d\n", (s4) OFFSET(executionstate_t, intregs)); + printf("#define offes_fltregs %3d\n", (s4) OFFSET(executionstate_t, fltregs)); /* everything is ok */ -- 2.25.1