From: Edwin Steiner Date: Wed, 20 Feb 2008 22:53:44 +0000 (+0100) Subject: * src/vm/jit/replace.h (executionstate_t): Added 'ra' field for return X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=33dabc695b6d67fd7081dbfbb7e7c7c798a6dc50;p=cacao.git * src/vm/jit/replace.h (executionstate_t): Added 'ra' field for return address register. Otherwise replacement code for the PowerPC gets very ugly, as the LR is not part of the intregs on PowerPC. * src/vm/jit/replace.c (replace_executionstate_println): Added print statements. (replace_sanity_check_read_write): Check 'ra' field. * src/vm/jit/alpha/linux/md-os.c (md_replace_executionstate_read): Use new 'ra' field. (md_replace_executionstate_write): Likewise. * src/vm/jit/powerpc/linux/md-os.c (md_replace_executionstate_read): Implemented for PowerPC/Linux. (md_replace_executionstate_write): Likewise. --- diff --git a/src/vm/jit/alpha/linux/md-os.c b/src/vm/jit/alpha/linux/md-os.c index b6c9cd8cb..1cbe4d26e 100644 --- a/src/vm/jit/alpha/linux/md-os.c +++ b/src/vm/jit/alpha/linux/md-os.c @@ -228,6 +228,7 @@ void md_replace_executionstate_read(executionstate_t *es, void *context) es->pc = (u1 *) _mc->sc_pc; es->sp = (u1 *) _mc->sc_regs[REG_SP]; es->pv = (u1 *) _mc->sc_regs[REG_PV]; + es->ra = (u1 *) _mc->sc_regs[REG_RA]; /* read integer registers */ for (i = 0; i < INT_REG_CNT; i++) @@ -274,6 +275,7 @@ void md_replace_executionstate_write(executionstate_t *es, void *context) _mc->sc_pc = (ptrint) es->pc; _mc->sc_regs[REG_SP] = (ptrint) es->sp; _mc->sc_regs[REG_PV] = (ptrint) es->pv; + _mc->sc_regs[REG_RA] = (ptrint) es->ra; } #endif diff --git a/src/vm/jit/powerpc/linux/md-os.c b/src/vm/jit/powerpc/linux/md-os.c index f7c781271..bb238bef5 100644 --- a/src/vm/jit/powerpc/linux/md-os.c +++ b/src/vm/jit/powerpc/linux/md-os.c @@ -300,6 +300,92 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p) #endif +/* md_replace_executionstate_read ********************************************** + + Read the given context into an executionstate for Replacement. + +*******************************************************************************/ + +#if defined(ENABLE_REPLACEMENT) +void md_replace_executionstate_read(executionstate_t *es, void *context) +{ + ucontext_t *_uc; + mcontext_t *_mc; + unsigned long *_gregs; + s4 i; + + _uc = (ucontext_t *) context; + +#if defined(__UCLIBC__) +#error Please port md_replace_executionstate_read to __UCLIBC__ +#else + _mc = _uc->uc_mcontext.uc_regs; + _gregs = _mc->gregs; +#endif + + /* read special registers */ + es->pc = (u1 *) _gregs[PT_NIP]; + es->sp = (u1 *) _gregs[REG_SP]; + es->pv = (u1 *) _gregs[REG_PV]; + es->ra = (u1 *) _gregs[PT_LNK]; + + /* read integer registers */ + for (i = 0; i < INT_REG_CNT; i++) + es->intregs[i] = _gregs[i]; + + /* read float registers */ + /* Do not use the assignment operator '=', as the type of + * the _mc->fpregs[i] can cause invalid conversions. */ + + assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs)); + memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs)); +} +#endif + + +/* md_replace_executionstate_write ********************************************* + + Write the given executionstate back to the context for Replacement. + +*******************************************************************************/ + +#if defined(ENABLE_REPLACEMENT) +void md_replace_executionstate_write(executionstate_t *es, void *context) +{ + ucontext_t *_uc; + mcontext_t *_mc; + unsigned long *_gregs; + s4 i; + + _uc = (ucontext_t *) context; + +#if defined(__UCLIBC__) +#error Please port md_replace_executionstate_read to __UCLIBC__ +#else + _mc = _uc->uc_mcontext.uc_regs; + _gregs = _mc->gregs; +#endif + + /* write integer registers */ + for (i = 0; i < INT_REG_CNT; i++) + _gregs[i] = es->intregs[i]; + + /* write float registers */ + /* Do not use the assignment operator '=', as the type of + * the _mc->fpregs[i] can cause invalid conversions. */ + + assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs)); + memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs)); + + /* write special registers */ + _gregs[PT_NIP] = (ptrint) es->pc; + _gregs[REG_SP] = (ptrint) es->sp; + _gregs[REG_PV] = (ptrint) es->pv; + _gregs[PT_LNK] = (ptrint) es->ra; +} +#endif + + /* md_critical_section_restart ************************************************* Search the critical sections tree for a matching section and set diff --git a/src/vm/jit/replace.c b/src/vm/jit/replace.c index 1149d45af..68cc8e5a6 100644 --- a/src/vm/jit/replace.c +++ b/src/vm/jit/replace.c @@ -3250,9 +3250,10 @@ void replace_executionstate_println(executionstate_t *es) } printf("executionstate_t:\n"); - printf("\tpc = %p",(void*)es->pc); - printf(" sp = %p",(void*)es->sp); - printf(" pv = %p\n",(void*)es->pv); + printf("\tpc = %p ",(void*)es->pc); + printf(" sp = %p ",(void*)es->sp); + printf(" pv = %p ",(void*)es->pv); + printf(" ra = %p\n",(void*)es->ra); #if defined(ENABLE_DISASSEMBLER) for (i=0; icode != NULL) { printf(" stackframesize=%d ", es->code->stackframesize); method_print(es->code->m); + if (code_is_leafmethod(es->code)) + printf(" leaf"); } printf("\n"); @@ -3612,6 +3615,7 @@ static void replace_sanity_check_read_write(void *context) es2.pc = es1.pc; es2.sp = es1.sp; es2.pv = es1.pv; + es2.ra = es1.ra; es2.code = es1.code; for (i = 0; i < INT_REG_CNT; ++i) es2.intregs[i] = es1.intregs[i]; @@ -3647,6 +3651,14 @@ static void replace_sanity_check_read_write(void *context) assert(es3.adrregs[i] == es1.adrregs[i]); #endif + /* i386 and x86_64 do not have an RA register */ + +#if defined(__I386__) || defined(__X86_64__) + assert(es3.ra != es1.ra); +#else + assert(es3.ra == es1.ra); +#endif + /* "code" is not set by the md_* functions */ assert(es3.code != es1.code); diff --git a/src/vm/jit/replace.h b/src/vm/jit/replace.h index 103749408..12135a971 100644 --- a/src/vm/jit/replace.h +++ b/src/vm/jit/replace.h @@ -149,6 +149,7 @@ struct executionstate_t { u1 *sp; /* stack pointer within method */ u1 *pv; /* procedure value. NULL means */ /* search the AVL tree */ + u1 *ra; /* return address / link register */ ptrint intregs[INT_REG_CNT]; /* register values */ double fltregs[FLT_REG_CNT]; /* register values */