From 39f19b8d3d706e6d650966a77b60644fe702d5ee Mon Sep 17 00:00:00 2001 From: christian Date: Thu, 16 Feb 2006 19:39:36 +0000 Subject: [PATCH] * src/vm/jit/stack.h (COPY): Prevent setting varkind to STACKVAR for stackslots copied by DUPx and SWAP. (DUP) Likewise. * src/vm/jit/stack.c (analyse_stack): Copy elimination and needed conflict resolution was implemented as described in the CACAO paper. As "potential exception throwing instruction" for now only INVOKE*s are regarded. Conflict resolution over DUPx and SWAP should be refined to be less conservative. * src/vm/jit/jit.c (jit_init): Stackreq for JAVA_IINC is set to 0 again, since no dummy stackslot is needed anymore for conflict resolution with XSTORE. * src/vm/jit/allocator/simplereg.c (interface_regalloc): Reuse unused float and int argument registers for interfaces, too. (reg_free_temp): Regard the new stackslot flag STCOPY, before freeing a register/memory location. (reg_alloc_dup): New function to allocate, if possible, the same register/memory location for stackslot copied by DUPx and SWAP. (allocate_scratch_registers): The new function reg_alloc_dup is used now for allocation at ICMD_DUPx and ICMD_SWAP, if possible. * src/vm/jit/jit.h: Added STCOPY as stackslot flag to mark simultanously live stackslots with same register after DUPx and SWAP. * doc/stack.txt: Updated invariants to show the change with IINC (no dummy stacklot anymore). --- doc/stack.txt | 6 + src/vm/jit/allocator/simplereg.c | 258 +++++++++++++++++++++++++------ src/vm/jit/jit.c | 8 +- src/vm/jit/jit.h | 6 +- src/vm/jit/stack.c | 142 +++++++++++++++-- src/vm/jit/stack.h | 33 ++-- 6 files changed, 371 insertions(+), 82 deletions(-) diff --git a/doc/stack.txt b/doc/stack.txt index e973ad39b..603b87556 100644 --- a/doc/stack.txt +++ b/doc/stack.txt @@ -42,6 +42,12 @@ The following invariants hold at all time for the stack representation: 6) References can only go to lower memory addresses. That is, for each stack slot sp: (sp->prev == NULL) or (sp->prev < sp) + + 7) If an instruction produces any stackslots, iptr->dst points to the highest-address + stackslot produced + Corollary: if iptr->dst points to curstack or below, the instruction does + not produce any stackslots + ATTENTION: The instack of a block and the slots produced within the block are *not* guaranteed to be adjacent (see figure below)! diff --git a/src/vm/jit/allocator/simplereg.c b/src/vm/jit/allocator/simplereg.c index cf71e9707..9dd50db5d 100644 --- a/src/vm/jit/allocator/simplereg.c +++ b/src/vm/jit/allocator/simplereg.c @@ -32,7 +32,7 @@ Michael Starzinger Edwin Steiner - $Id: simplereg.c 4454 2006-02-06 00:02:50Z edwin $ + $Id: simplereg.c 4524 2006-02-16 19:39:36Z christian $ */ @@ -70,6 +70,13 @@ static void allocate_scratch_registers(methodinfo *m, registerdata *rd); void regalloc(methodinfo *m, codegendata *cd, registerdata *rd) { + /* There is a problem with the use of unused float argument registers in */ + /* leafmethods for stackslots on c7 (3* Dual Core AMD Opteron(tm) */ + /* Processor 270) - runtime for the jvm98 _mtrt benchmark is heaviliy */ + /* increased. This could be prevented by setting rd->argfltreguse to */ + /* FLT_ARG_CNT before calling allocate_scratch_registers and setting it */ + /* back to the original value before calling local_regalloc. */ + interface_regalloc(m, cd, rd); allocate_scratch_registers(m, rd); local_regalloc(m, cd, rd); @@ -159,8 +166,7 @@ static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY; v->regoff = rd->interfaces[s][fltalloc].regoff; - } else if (!m->isleafmethod - && (rd->argfltreguse < FLT_ARG_CNT)) { + } else if (rd->argfltreguse < FLT_ARG_CNT) { v->regoff = rd->argfltregs[rd->argfltreguse++]; } else if (rd->tmpfltreguse > 0) { v->regoff = rd->tmpfltregs[--rd->tmpfltreguse]; @@ -208,9 +214,8 @@ static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) v->regoff = rd->interfaces[s][intalloc].regoff; } else - if (!m->isleafmethod && - (rd->argintreguse - + intregsneeded < INT_ARG_CNT)) { + if (rd->argintreguse + intregsneeded + < INT_ARG_CNT) { #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS) if (intregsneeded) v->regoff=PACK_REGS( @@ -932,7 +937,10 @@ static void reg_new_temp_func(registerdata *rd, stackptr s) } -#define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s) +#define reg_free_temp(rd,s) if ((s->varkind == TEMPVAR) && (!(s->flags & STCOPY))) reg_free_temp_func(rd, s) + +/* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */ +/* alive using this reg/memory location */ static void reg_free_temp_func(registerdata *rd, stackptr s) { @@ -1021,7 +1029,30 @@ static void reg_free_temp_func(registerdata *rd, stackptr s) } } - +static bool reg_alloc_dup(stackptr src, stackptr dst) { + /* only copy TEMPVARS, do not mess with STACKVAR, */ + /* LOCALVAR, or ARGVAR */ + if ((src->varkind == TEMPVAR) && (dst->varkind == TEMPVAR)) { + /* can not allocate a REG_TMP to a REG_SAV Slot */ + if (src->flags & INMEMORY) { + dst->regoff = src->regoff; + dst->flags |= INMEMORY; + return true; + } else if ((src->flags & SAVEDVAR) == (dst->flags & SAVEDVAR)) { + dst->regoff = src->regoff; + dst->flags |= src->flags & SAVEDTMP; + dst->flags |= src->flags & TMPARG; + return true; + } else if ((dst->flags & SAVEDVAR) == 0) { + /* can only use a REG_SAV as REG_TMP! */ + dst->regoff = src->regoff; + dst->flags |= SAVEDTMP; + return true; + } + } + /* no copy possible - allocate a new reg/memory location*/ + return false; +} static void allocate_scratch_registers(methodinfo *m, registerdata *rd) { @@ -1212,73 +1243,210 @@ static void allocate_scratch_registers(methodinfo *m, registerdata *rd) /* pop 0 push 1 dup */ case ICMD_DUP: - reg_new_temp(rd, dst); + /* src === dst->prev (identical Stackslot Element) */ + /* src --> dst (copied value, take same reg/mem) */ + + if (!reg_alloc_dup(src, dst)) { + reg_new_temp(rd, dst); + } else { + dst->flags |= STCOPY; + } break; /* pop 0 push 2 dup */ case ICMD_DUP2: - reg_new_temp(rd, dst->prev); - reg_new_temp(rd, dst); + /* src->prev === dst->prev->prev->prev (identical Stackslot Element) */ + /* src === dst->prev->prev (identical Stackslot Element) */ + /* src->prev --> dst->prev (copied value, take same reg/mem) */ + /* src --> dst (copied value, take same reg/mem) */ + + if (!reg_alloc_dup(src->prev, dst->prev)) { + reg_new_temp(rd, dst->prev); + } else { + dst->prev->flags |= STCOPY; + } + if (!reg_alloc_dup(src, dst)) { + reg_new_temp(rd, dst); + } else { + dst->flags |= STCOPY; + } break; /* pop 2 push 3 dup */ case ICMD_DUP_X1: - reg_free_temp(rd, src); - reg_new_temp(rd, dst); - reg_free_temp(rd, src->prev); - reg_new_temp(rd, dst->prev); - reg_new_temp(rd, dst->prev->prev); + /* src->prev --> dst->prev (copied value, take same reg/mem) */ + /* src --> dst (copied value, take same reg/mem) */ + /* src --> dst->prev->prev (copied value, take same reg/mem) */ + + { + bool ret, ret1; + if (!(ret = reg_alloc_dup(src, dst->prev->prev))) { + reg_new_temp(rd, dst->prev->prev); + } + if (!(ret1 = reg_alloc_dup(src, dst))) { + reg_new_temp(rd, dst); + } + if (!(ret || ret1)) { + /* no reallocation was possible -> free src */ + reg_free_temp(rd, src); + } + if (ret && ret1) { + dst->flags |= STCOPY; + } + if (!reg_alloc_dup(src->prev, dst->prev)) { + reg_free_temp(rd, src->prev); + reg_new_temp(rd, dst->prev); + } + } break; /* pop 3 push 4 dup */ case ICMD_DUP_X2: - reg_free_temp(rd, src); - reg_new_temp(rd, dst); - reg_free_temp(rd, src->prev); - reg_new_temp(rd, dst->prev); - reg_free_temp(rd, src->prev->prev); - reg_new_temp(rd, dst->prev->prev); - reg_new_temp(rd, dst->prev->prev->prev); + /* src->prev->prev --> dst->prev->prev */ + /* src->prev --> dst->prev */ + /* src --> dst */ + /* src --> dst->prev->prev->prev */ + + { + bool ret, ret1; + if (!(ret = reg_alloc_dup(src, dst->prev->prev->prev))) { + reg_new_temp(rd, dst->prev->prev->prev); + } + if (!(ret1 = reg_alloc_dup(src, dst))) { + reg_new_temp(rd, dst); + } + if (!(ret || ret1)) { + /* no reallocation was possible -> free src */ + reg_free_temp(rd, src); + } + if (ret && ret1) { + dst->flags |= STCOPY; + } + if (!reg_alloc_dup(src->prev, dst->prev)) { + reg_free_temp(rd, src->prev); + reg_new_temp(rd, dst->prev); + } + if (!reg_alloc_dup(src->prev->prev, dst->prev->prev)) { + reg_free_temp(rd, src->prev->prev); + reg_new_temp(rd, dst->prev->prev); + } + } break; /* pop 3 push 5 dup */ case ICMD_DUP2_X1: - reg_free_temp(rd, src); - reg_new_temp(rd, dst); - reg_free_temp(rd, src->prev); - reg_new_temp(rd, dst->prev); - reg_free_temp(rd, src->prev->prev); - reg_new_temp(rd, dst->prev->prev); - reg_new_temp(rd, dst->prev->prev->prev); - reg_new_temp(rd, dst->prev->prev->prev->prev); + /* src->prev->prev --> dst->prev->prev */ + /* src->prev --> dst->prev */ + /* src --> dst */ + /* src->prev --> dst->prev->prev->prev->prev */ + /* src --> dst->prev->prev->prev */ + + { + bool ret, ret1; + if (!(ret = reg_alloc_dup(src, dst->prev->prev->prev))) { + reg_new_temp(rd, dst->prev->prev->prev); + } + if (!(ret1 = reg_alloc_dup(src, dst))) { + reg_new_temp(rd, dst); + } + if (!(ret || ret1)) { + /* no reallocation was possible -> free src */ + reg_free_temp(rd, src); + } + if (ret && ret1) { + dst->flags |= STCOPY; + } + + if (!(ret = reg_alloc_dup(src->prev, dst->prev->prev->prev->prev))) { + reg_new_temp(rd, dst->prev->prev->prev->prev); + } + if (!(ret1 = reg_alloc_dup(src->prev, dst->prev))) { + reg_new_temp(rd, dst->prev); + } + if (!(ret || ret1)) { + /* no reallocation was possible -> free src->prev */ + reg_free_temp(rd, src->prev); + } + if (ret && ret1) { + dst->prev->flags |= STCOPY; + } + + if (!reg_alloc_dup(src->prev->prev, dst->prev->prev)) { + reg_free_temp(rd, src->prev->prev); + reg_new_temp(rd, dst->prev->prev); + } + } break; /* pop 4 push 6 dup */ case ICMD_DUP2_X2: - reg_free_temp(rd, src); - reg_new_temp(rd, dst); - reg_free_temp(rd, src->prev); - reg_new_temp(rd, dst->prev); - reg_free_temp(rd, src->prev->prev); - reg_new_temp(rd, dst->prev->prev); - reg_free_temp(rd, src->prev->prev->prev); - reg_new_temp(rd, dst->prev->prev->prev); - reg_new_temp(rd, dst->prev->prev->prev->prev); - reg_new_temp(rd, dst->prev->prev->prev->prev->prev); + /* src->prev->prev->prev --> dst->prev->prev->prev */ + /* src->prev->prev --> dst->prev->prev */ + /* src->prev --> dst->prev */ + /* src --> dst */ + /* src->prev --> dst->prev->prev->prev->prev->prev */ + /* src --> dst->prev->prev->prev->prev */ + + { + bool ret, ret1; + if (!(ret = reg_alloc_dup(src, dst->prev->prev->prev->prev))) { + reg_new_temp(rd, dst->prev->prev->prev->prev); + } + if (!(ret1 = reg_alloc_dup(src, dst))) { + reg_new_temp(rd, dst); + } + if (!(ret || ret1)) { + /* no reallocation was possible -> free src */ + reg_free_temp(rd, src); + } + if (ret && ret1) { + dst->flags |= STCOPY; + } + + if (!(ret = reg_alloc_dup(src->prev, dst->prev->prev->prev->prev->prev))) { + reg_new_temp(rd, dst->prev->prev->prev->prev->prev); + } + if (!(ret1 = reg_alloc_dup(src->prev, dst->prev))) { + reg_new_temp(rd, dst->prev); + } + if (!(ret || ret1)) { + /* no reallocation was possible -> free src->prev */ + reg_free_temp(rd, src->prev); + } + if (ret && ret1) { + dst->prev->flags |= STCOPY; + } + + if (!reg_alloc_dup(src->prev->prev, dst->prev->prev)) { + reg_free_temp(rd, src->prev->prev); + reg_new_temp(rd, dst->prev->prev); + } + if (!reg_alloc_dup(src->prev->prev->prev, dst->prev->prev->prev)) { + reg_free_temp(rd, src->prev->prev->prev); + reg_new_temp(rd, dst->prev->prev->prev); + } + } break; /* pop 2 push 2 swap */ case ICMD_SWAP: - reg_free_temp(rd, src); - reg_new_temp(rd, dst->prev); - reg_free_temp(rd, src->prev); - reg_new_temp(rd, dst); + /* src --> dst->prev (copy) */ + /* src->prev --> dst (copy) */ + + if (!reg_alloc_dup(src, dst->prev)) { + reg_free_temp(rd, src); + reg_new_temp(rd, dst->prev); + } + if (!reg_alloc_dup(src->prev, dst->prev)) { + reg_free_temp(rd, src->prev); + reg_new_temp(rd, dst); + } break; /* pop 2 push 1 */ diff --git a/src/vm/jit/jit.c b/src/vm/jit/jit.c index 31758e47b..df5d2e40e 100644 --- a/src/vm/jit/jit.c +++ b/src/vm/jit/jit.c @@ -31,7 +31,7 @@ Christian Thalinger Christian Ullrich - $Id: jit.c 4478 2006-02-07 17:22:13Z edwin $ + $Id: jit.c 4524 2006-02-16 19:39:36Z christian $ */ @@ -1270,11 +1270,7 @@ void jit_init(void) stackreq[JAVA_IFNONNULL] = 0; stackreq[JAVA_GOTO_W] = 0; stackreq[JAVA_BREAKPOINT] = 0; - - /* we need one dummy stack slot for IINC in order to */ - /* avoid that the modified local variable is */ - /* kept on the stack (see stack.c, ICMD_IINC) */ - stackreq[JAVA_IINC] = 1; + stackreq[JAVA_IINC] = 0; stackreq[JAVA_SWAP] = 2; stackreq[JAVA_DUP2] = 2; diff --git a/src/vm/jit/jit.h b/src/vm/jit/jit.h index 32220a044..95bdbe181 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 4476 2006-02-07 16:47:44Z edwin $ + $Id: jit.h 4524 2006-02-16 19:39:36Z christian $ */ @@ -94,7 +94,9 @@ typedef struct subroutineinfo subroutineinfo; #define SAVEDVAR 1 /* variable has to survive method invocations */ #define INMEMORY 2 /* variable stored in memory */ #define SAVEDTMP 4 /* temporary variable using a saved register */ -#define TMPARG 8 /* temporary variable using a argument register */ +#define TMPARG 8 /* temporary variable using a arg register */ +#define STCOPY 16 /* there is another stackslot alive */ + /* using the same register/memory location */ /* variable kinds */ diff --git a/src/vm/jit/stack.c b/src/vm/jit/stack.c index c39034347..2b22f3be2 100644 --- a/src/vm/jit/stack.c +++ b/src/vm/jit/stack.c @@ -30,7 +30,7 @@ Christian Thalinger Christian Ullrich - $Id: stack.c 4455 2006-02-06 01:02:59Z edwin $ + $Id: stack.c 4524 2006-02-16 19:39:36Z christian $ */ @@ -127,7 +127,7 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) stackptr curstack; stackptr new; stackptr copy; - int opcode, i, len, loops; + int opcode, i, j, len, loops; int superblockend, repeat, deadcode; instruction *iptr; basicblock *bptr; @@ -135,6 +135,12 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) s4 *s4ptr; void **tptr; s4 *argren; + s4 *last_store;/* instruction index of last XSTORE */ + /* [ local_index * 5 + type ] */ + s4 last_pei; /* instruction index of last possible exception */ + /* used for conflict resolution for copy */ + /* elimination (XLOAD, IINC, XSTORE) */ + s4 last_dupx; builtintable_entry *bte; unresolved_method *um; @@ -147,6 +153,8 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) argren = DMNEW(s4, cd->maxlocals); /* table for argument renaming */ for (i = 0; i < cd->maxlocals; i++) argren[i] = i; + + last_store = DMNEW(s4 , cd->maxlocals * 5); new = m->stack; loops = 0; @@ -276,6 +284,12 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) iptr = bptr->iinstr; b_index = bptr - m->basicblocks; + last_pei = -1; + last_dupx = -1; + for( i = 0; i < cd->maxlocals; i++) + for( j = 0; j < 5; j++) + last_store[5 * i + j] = -1; + bptr->stack = new; while (--len >= 0) { @@ -1101,6 +1115,8 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) count_store_depth[i]++; } #endif + last_store[5 * iptr->op1 + TYPE_INT] = bptr->icount - len - 1; + copy = curstack; i = stackdepth - 1; while (copy) { @@ -1112,12 +1128,6 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) i--; copy = copy->prev; } - - /* allocate a dummy stack slot to keep ISTORE from */ - /* marking its input stack as a LOCALVAR, since we */ - /* change the value of the local variable here. */ - NEWSTACK0(TYPE_INT); - POP(TYPE_INT); SETDST; break; @@ -1152,6 +1162,7 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) count_store_depth[i]++; } #endif + /* check for conflicts as described in Figure 5.2 */ copy = curstack->prev; i = stackdepth - 2; while (copy) { @@ -1163,10 +1174,107 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) i--; copy = copy->prev; } - if ((new - curstack) == 1) { - curstack->varkind = LOCALVAR; - curstack->varnum = iptr->op1; - }; + + /* do not change instack Stackslots */ + /* it won't improve performance if we copy the interface */ + /* at the BB begin or here, and lsra relies that no */ + /* instack stackslot is marked LOCALVAR */ + if (curstack->varkind == STACKVAR) + goto _possible_conflict; + + /* check for a DUPX,SWAP while the lifetime of curstack */ + /* and as creator curstack */ + if (last_dupx != -1) { + /* we have to look at the dst stack of DUPX */ + /* == src Stack of PEI */ + copy = bptr->iinstr[last_dupx].dst; + /* + if (last_pei == 0) + copy = bptr->instack; + else + copy = bptr->iinstr[last_pei-1].dst; + */ + if ((copy != NULL) && (curstack <= copy)) { + /* curstack alive at or created by DUPX */ + + /* TODO:.... */ + /* now look, if there is a LOCALVAR at anyone of */ + /* the src stacklots used by DUPX */ + + goto _possible_conflict; + } + } + + /* check for a PEI while the lifetime of curstack */ + if (last_pei != -1) { + /* && there are exception handler in this method */ + /* when this is checked prevent ARGVAR from */ + /* overwriting LOCALVAR!!! */ + + /* we have to look at the stack _before_ the PEI! */ + /* == src Stack of PEI */ + if (last_pei == 0) + copy = bptr->instack; + else + copy = bptr->iinstr[last_pei-1].dst; + if ((copy != NULL) && (curstack <= copy)) { + /* curstack alive at PEI */ + goto _possible_conflict; + } + } + + /* check if there is a possible conflicting XSTORE */ + if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] != -1) { + /* we have to look at the stack _before_ the XSTORE! */ + /* == src Stack of XSTORE */ + if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] == 0) + copy = bptr->instack; + else + copy = bptr->iinstr[last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] - 1].dst; + if ((copy != NULL) && (curstack <= copy)) { + /* curstack alive at Last Store */ + goto _possible_conflict; + } + } + + /* check if there is a conflict with a XLOAD */ + /* this is done indirectly by looking if a Stackslot is */ + /* marked LOCALVAR and is live while curstack is live */ + /* see figure 5.3 */ + + /* First check "above" stackslots of the instack */ + copy = curstack + 1; + for(;(copy <= bptr->instack); copy++) + if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) { + goto _possible_conflict; + } + + /* "intra" Basic Block Stackslots are allocated above */ + /* bptr->stack (see doc/stack.txt), so if curstack + 1 */ + /* is an instack, copy could point now to the stackslots */ + /* of an inbetween analysed Basic Block */ + if (copy < bptr->stack) + copy = bptr->stack; + while (copy < new) { + if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) { + goto _possible_conflict; + } + copy++; + } + /* no conflict - mark the Stackslot as LOCALVAR */ + curstack->varkind = LOCALVAR; + curstack->varnum = iptr->op1; + + goto _local_join; + _possible_conflict: + if ((curstack->varkind == LOCALVAR) + && (curstack->varnum == iptr->op1)) { + curstack->varkind = TEMPVAR; + curstack->varnum = stackdepth-1; + } + _local_join: + last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] = bptr->icount - len - 1; + STORE(opcode - ICMD_ISTORE); break; @@ -1510,11 +1618,13 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) } } #endif + last_dupx = bptr->icount - len - 1; COUNT(count_dup_instruction); DUP; break; case ICMD_DUP2: + last_dupx = bptr->icount - len - 1; REQUIRE_1; if (IS_2_WORD_TYPE(curstack->type)) { /* ..., cat2 */ @@ -1555,10 +1665,12 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) } } #endif + last_dupx = bptr->icount - len - 1; DUP_X1; break; case ICMD_DUP2_X1: + last_dupx = bptr->icount - len - 1; REQUIRE_2; if (IS_2_WORD_TYPE(curstack->type)) { /* ..., ????, cat2 */ @@ -1592,6 +1704,7 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) /* pop 3 push 4 dup */ case ICMD_DUP_X2: + last_dupx = bptr->icount - len - 1; REQUIRE_2; if (IS_2_WORD_TYPE(curstack->prev->type)) { /* ..., cat2, ???? */ @@ -1623,6 +1736,7 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) break; case ICMD_DUP2_X2: + last_dupx = bptr->icount - len - 1; REQUIRE_2; if (IS_2_WORD_TYPE(curstack->type)) { /* ..., ????, cat2 */ @@ -1682,6 +1796,7 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) /* pop 2 push 2 swap */ case ICMD_SWAP: + last_dupx = bptr->icount - len - 1; #ifdef TYPECHECK_STACK_COMPCAT if (opt_verify) { REQUIRE_2; @@ -2010,6 +2125,9 @@ methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd) /* {COUNT(count_check_null);} */ _callhandling: + + last_pei = bptr->icount - len - 1; + i = md->paramcount; if (md->memuse > rd->memuse) diff --git a/src/vm/jit/stack.h b/src/vm/jit/stack.h index 0c00a278c..712b3678a 100644 --- a/src/vm/jit/stack.h +++ b/src/vm/jit/stack.h @@ -28,7 +28,7 @@ Changes: Christian Ullrich - $Id: stack.h 4483 2006-02-11 21:25:45Z christian $ + $Id: stack.h 4524 2006-02-16 19:39:36Z christian $ */ @@ -174,23 +174,18 @@ curstack = curstack->prev; \ } while (0) -/******************************************************* -Quick Fix to prevent dependence problems of local vars -varnum is not set to the according position within the stack -like it is done normaly in stack.c --> if this shows to be a problem this can be solved in all the -DUP* and SWAP Macros -TODO: dependences should be prevented as described in the -CACAO JVM Paper -Interface Stackslots (STACKVAR) are not allowed to be copied. -ARGVAR are taken out, too. -*******************************************************/ +/* Do not copy Interface Stackslots over DUPx, Swaps! */ #define COPY(s,d) \ do { \ (d)->flags = 0; \ (d)->type = (s)->type; \ - (d)->varkind = TEMPVAR; \ - (d)->varnum = 0; \ + if ( (s)->varkind != STACKVAR) { \ + (d)->varkind = (s)->varkind; \ + (d)->varnum = (s)->varnum; \ + } else { \ + (d)->varkind = TEMPVAR; \ + (d)->varnum = 0; \ + } \ } while (0) @@ -340,10 +335,14 @@ ARGVAR are taken out, too. SETDST; \ } while (0) -/* Same dependency quick fix as at COPY */ +/* Do not copy Interface Stackslots over DUP! */ #define DUP {REQUIRE_1; \ - NEWSTACK(CURTYPE,TEMPVAR,stackdepth-1);SETDST; \ - stackdepth++; INC_LIFETIMES(1);} + if (CURKIND != STACKVAR) { \ + NEWSTACK(CURTYPE,CURKIND,curstack->varnum); \ + } else { \ + NEWSTACK(CURTYPE, TEMPVAR, stackdepth); \ + } \ + SETDST; stackdepth++; INC_LIFETIMES(1);} #define SWAP {REQUIRE_2;COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\ new[0].prev=curstack;new[1].prev=new;\ curstack=new+1;new+=2;SETDST;} -- 2.25.1