* src/vm/jit/x86_64/asmpart.S (asm_replacement_out): Added pv.
* src/vm/jit/replace.c (replace_read_executionstate)
(replace_write_executionstate): Prepared for alpha. Some cleanup.
* src/vm/jit/replace.c (replace_write_executionstate):
Calculate stack pointer from given stack base.
(replace_executionstate_println): Added pv.
(replace_sourcestate_println): Added stackbase.
* src/vm/jit/replace.h (executionstate): Added pv.
(sourcestate): Added stackbase.
* src/vm/jit/tools/genoffsets.c (main): Added offes_pv.
* doc/stack_frames.txt: Clarifications.
| u8[] ^ callee-saved float registers
| u4[] ^ callee-saved integer registers
V
| u8[] ^ callee-saved float registers
| u4[] ^ callee-saved integer registers
V
-| >>>> sp on method entry <<<<
+| >>>> sp on method entry, stack base for replacement <<<<
|
V u4 return address
| u4[] arguments on stack
|
V u4 return address
| u4[] arguments on stack
| u8[] v arguments for calling methods \__ rd->memuse slots
V u8[] v local variable slots allocated on stack /
|
| u8[] v arguments for calling methods \__ rd->memuse slots
V u8[] v local variable slots allocated on stack /
|
-| u8 synchronized object / saved return value (only for synched methods)
-V u8 alignment dummy slot (in non-leaf methods to ensure
+| u8 v synchronized object / saved return value (only for synched methods)
+V u8[0..1] alignment dummy slot (in non-leaf methods to ensure
| 16-byte alignment of stack)
| u8[] ^ callee-saved float registers
V u8[] ^ callee-saved integer registers
|
| 16-byte alignment of stack)
| u8[] ^ callee-saved float registers
V u8[] ^ callee-saved integer registers
|
-| >>>> sp on method entry <<<<
+| >>>> sp on method entry, stack base for replacement <<<<
V
| u8 return address
| u8[] arguments on stack
V
| u8 return address
| u8[] arguments on stack
V
| u8[] ^ callee-saved float registers
| u8[] ^ callee-saved integer registers
V
| u8[] ^ callee-saved float registers
| u8[] ^ callee-saved integer registers
+V
+| >>>> !!!replacement code regards this point as stack base!!! <<<<
+|
V u8 ^ saved return address (only for non-leaf methods)
|
| >>>> sp on method entry <<<<
V u8 ^ saved return address (only for non-leaf methods)
|
| >>>> sp on method entry <<<<
Changes: Joseph Wenninger
Edwin Steiner
Changes: Joseph Wenninger
Edwin Steiner
- $Id: asmpart.S 4623 2006-03-16 00:05:18Z edwin $
+ $Id: asmpart.S 4643 2006-03-16 18:38:42Z edwin $
add $(sizeexecutionstate + REPLACEMENT_ROOM + 4),itmp1
mov itmp1,(offes_sp)(sp)
add $(sizeexecutionstate + REPLACEMENT_ROOM + 4),itmp1
mov itmp1,(offes_sp)(sp)
+ /* pv must be looked up via AVL tree */
+ movl $0,(offes_pv)(sp)
+
/* call replace_me */
mov -4(itmp1),itmp1 /* rplpoint * */
push sp /* arg1: execution state */
/* call replace_me */
mov -4(itmp1),itmp1 /* rplpoint * */
push sp /* arg1: execution state */
#include "vm/jit/disass.h"
#include "arch.h"
#include "vm/jit/disass.h"
#include "arch.h"
+/*** constants used internally ************************************************/
+
+#define TOP_IS_NORMAL 0
+#define TOP_IS_ON_STACK 1
+#define TOP_IS_IN_ITMP1 2
+
/* replace_create_replacement_points *******************************************
Create the replacement points for the given code.
/* replace_create_replacement_points *******************************************
Create the replacement points for the given code.
int allocs;
rplalloc *ra;
methoddesc *md;
int allocs;
rplalloc *ra;
methoddesc *md;
#ifdef HAS_4BYTE_STACKSLOT
u4 *sp;
u4 *basesp;
#ifdef HAS_4BYTE_STACKSLOT
u4 *sp;
u4 *basesp;
code = rp->code;
m = code->m;
md = m->parseddesc;
code = rp->code;
m = code->m;
md = m->parseddesc;
+ topslot = TOP_IS_NORMAL;
- /* calculate stack pointers */
#ifdef HAS_4BYTE_STACKSLOT
sp = (u4*) es->sp;
#ifdef HAS_4BYTE_STACKSLOT
sp = (u4*) es->sp;
sp = (u8*) es->sp;
#endif
sp = (u8*) es->sp;
#endif
- /* XXX only on i386? */
- if (rp->type == BBTYPE_SBR)
+ /* on some architectures the returnAddress is passed on the stack by JSR */
+
+#if defined(__I386__) || defined(__X86_64__)
+ if (rp->type == BBTYPE_SBR) {
+ topslot = TOP_IS_ON_STACK;
+ }
+#endif
+
+ /* in some cases the top stack slot is passed in REG_ITMP1 */
+
+ if ( (rp->type == BBTYPE_EXH)
+#if defined(__ALPHA__)
+ || (rp->type == BBTYPE_SBR)
+#endif
+ )
+ {
+ topslot = TOP_IS_IN_ITMP1;
+ }
+
+ /* calculate base stack pointer */
basesp = sp + code_get_stack_frame_size(code);
basesp = sp + code_get_stack_frame_size(code);
+ ss->stackbase = (u1*) basesp;
+
/* read local variables */
count = m->maxlocals;
/* read local variables */
count = m->maxlocals;
/* mark values as undefined */
for (i=0; i<count*5; ++i)
ss->javalocals[i] = (u8) 0x00dead0000dead00ULL;
/* mark values as undefined */
for (i=0; i<count*5; ++i)
ss->javalocals[i] = (u8) 0x00dead0000dead00ULL;
+
+ /* some entries in the intregs array are not meaningful */
+ es->intregs[REG_ITMP3] = (u8) 0x11dead1111dead11ULL;
+ es->intregs[REG_SP ] = (u8) 0x11dead1111dead11ULL;
+#ifdef REG_PV
+ es->intregs[REG_PV ] = (u8) 0x11dead1111dead11ULL;
ss->javastackdepth = count;
ss->javastack = DMNEW(u8,count);
ss->javastackdepth = count;
ss->javastack = DMNEW(u8,count);
+#ifndef NDEBUG
+ /* mark values as undefined */
+ for (i=0; i<count; ++i)
+ ss->javastack[i] = (u8) 0x00dead0000dead00ULL;
+#endif
+
i = 0;
ra = rp->regalloc;
/* the first stack slot is special in SBR and EXH blocks */
i = 0;
ra = rp->regalloc;
/* the first stack slot is special in SBR and EXH blocks */
- if (rp->type == BBTYPE_SBR) {
+ if (topslot == TOP_IS_ON_STACK) {
assert(count);
ss->javastack[i] = sp[-1];
assert(count);
ss->javastack[i] = sp[-1];
- else if (rp->type == BBTYPE_EXH) {
+ else if (topslot == TOP_IS_IN_ITMP1) {
- ss->javastack[i] = es->intregs[REG_ITMP1]; /* XXX all platforms? */
+ ss->javastack[i] = es->intregs[REG_ITMP1];
+ /* read remaining stack slots */
+
for (; count--; ra++, i++) {
assert(ra->next);
for (; count--; ra++, i++) {
assert(ra->next);
ss->savedintregs[i] = *--basesp;
}
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; i<code->savedfltcount; ++i) {
/* read saved flt regs */
for (i=0; i<code->savedfltcount; ++i) {
ss->savedfltregs[i] = *(u8*)basesp;
}
ss->savedfltregs[i] = *(u8*)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 slots used for synchronization */
count = code_get_sync_slot_count(code);
/* read slots used for synchronization */
count = code_get_sync_slot_count(code);
*******************************************************************************/
*******************************************************************************/
-static void replace_write_executionstate(rplpoint *rp,executionstate *es,sourcestate *ss)
+static void replace_write_executionstate(rplpoint *rp,executionstate *es,
+ sourcestate *ss)
{
methodinfo *m;
codeinfo *code;
{
methodinfo *m;
codeinfo *code;
int allocs;
rplalloc *ra;
methoddesc *md;
int allocs;
rplalloc *ra;
methoddesc *md;
#ifdef HAS_4BYTE_STACKSLOT
u4 *sp;
u4 *basesp;
#ifdef HAS_4BYTE_STACKSLOT
u4 *sp;
u4 *basesp;
m = code->m;
md = m->parseddesc;
m = code->m;
md = m->parseddesc;
- /* calculate stack pointers */
-
+ /* calculate stack pointer */
+
#ifdef HAS_4BYTE_STACKSLOT
#ifdef HAS_4BYTE_STACKSLOT
+ basesp = (u4*) ss->stackbase;
+ basesp = (u8*) ss->stackbase;
+
+ sp = basesp - code_get_stack_frame_size(code);
- if (rp->type == BBTYPE_SBR)
- sp++;
+ /* on some architectures the returnAddress is passed on the stack by JSR */
+
+#if defined(__I386__) || defined(__X86_64__)
+ if (rp->type == BBTYPE_SBR) {
+ topslot = TOP_IS_ON_STACK;
+ }
+#endif
- basesp = sp + code_get_stack_frame_size(code);
+ /* in some cases the top stack slot is passed in REG_ITMP1 */
+
+ if ( (rp->type == BBTYPE_EXH)
+#if defined(__ALPHA__)
+ || (rp->type == BBTYPE_SBR)
+#endif
+ )
+ {
+ topslot = TOP_IS_IN_ITMP1;
+ }
/* in debug mode, invalidate stack frame first */
/* in debug mode, invalidate stack frame first */
/* the first stack slot is special in SBR and EXH blocks */
/* the first stack slot is special in SBR and EXH blocks */
- if (rp->type == BBTYPE_SBR) {
+ if (topslot == TOP_IS_ON_STACK) {
assert(count);
sp[-1] = ss->javastack[i];
assert(count);
sp[-1] = ss->javastack[i];
- else if (rp->type == BBTYPE_EXH) {
+ else if (topslot == TOP_IS_IN_ITMP1) {
- es->intregs[REG_ITMP1] = ss->javastack[i]; /* XXX all platforms? */
+ es->intregs[REG_ITMP1] = ss->javastack[i];
+
+ /* write remaining stack slots */
for (; count--; ra++, i++) {
assert(ra->next);
for (; count--; ra++, i++) {
assert(ra->next);
printf("executionstate %p:\n",(void*)es);
printf("\tpc = %p\n",(void*)es->pc);
printf("\tsp = %p\n",(void*)es->sp);
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);
for (i=0; i<INT_REG_CNT; ++i) {
printf("\t%-3s = %016llx\n",regs[i],(unsigned long long)es->intregs[i]);
}
for (i=0; i<INT_REG_CNT; ++i) {
printf("\t%-3s = %016llx\n",regs[i],(unsigned long long)es->intregs[i]);
}
- printf("sourcestate %p:\n",(void*)ss);
+ printf("sourcestate %p: stackbase=%p\n",(void*)ss,(void*)ss->stackbase);
printf("\tlocals (%d):\n",ss->javalocalcount);
for (i=0; i<ss->javalocalcount; ++i) {
printf("\tlocals (%d):\n",ss->javalocalcount);
for (i=0; i<ss->javalocalcount; ++i) {
struct executionstate {
u1 *pc; /* program counter */
u1 *sp; /* stack pointer within method */
struct executionstate {
u1 *pc; /* program counter */
u1 *sp; /* stack pointer within method */
+ u1 *pv; /* procedure value. NULL means */
+ /* search the AVL tree */
u8 intregs[INT_REG_CNT]; /* register values */
u8 fltregs[FLT_REG_CNT]; /* register values */
u8 intregs[INT_REG_CNT]; /* register values */
u8 fltregs[FLT_REG_CNT]; /* register values */
u8 *syncslots;
s4 syncslotcount;
u8 *syncslots;
s4 syncslotcount;
};
/*** prototypes ********************************************************/
};
/*** prototypes ********************************************************/
- $Id: genoffsets.c 4623 2006-03-16 00:05:18Z edwin $
+ $Id: genoffsets.c 4643 2006-03-16 18:38:42Z edwin $
printf("#define offes_pc %3d\n", (s4) OFFSET(executionstate, pc));
printf("#define offes_sp %3d\n", (s4) OFFSET(executionstate, sp));
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_intregs %3d\n", (s4) OFFSET(executionstate, intregs));
printf("#define offes_fltregs %3d\n", (s4) OFFSET(executionstate, fltregs));
- $Id: asmpart.S 4623 2006-03-16 00:05:18Z edwin $
+ $Id: asmpart.S 4643 2006-03-16 18:38:42Z edwin $
add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
mov itmp1,(offes_sp)(sp)
add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
mov itmp1,(offes_sp)(sp)
+ /* pv must be looked up via AVL tree */
+ movq $0,(offes_pv)(sp)
+
/* call replace_me */
mov -8(itmp1),a0 /* rplpoint * */
mov sp,a1 /* arg1: execution state */
/* call replace_me */
mov -8(itmp1),a0 /* rplpoint * */
mov sp,a1 /* arg1: execution state */