* src/vm/jit/replace.h (executionstate_t): Added 'ra' field for return
authorEdwin Steiner <edwin.steiner@gmx.net>
Wed, 20 Feb 2008 22:53:44 +0000 (23:53 +0100)
committerEdwin Steiner <edwin.steiner@gmx.net>
Wed, 20 Feb 2008 22:53:44 +0000 (23:53 +0100)
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.

src/vm/jit/alpha/linux/md-os.c
src/vm/jit/powerpc/linux/md-os.c
src/vm/jit/replace.c
src/vm/jit/replace.h

index b6c9cd8cb8f0282093ce14ebfb19131d8f0bc7de..1cbe4d26e4e0f7158f6b4ec6c0097f7c07634815 100644 (file)
@@ -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
 
index f7c78127169267787b329349073101d6a7d0e7d1..bb238bef5037e7c413b133da7e287a9c53c16c35 100644 (file)
@@ -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
index 1149d45afa788b6cbf8cc9217dc6c22d252a47f5..68cc8e5a6ad06ca0d4202fc1e8452a910f8e324d 100644 (file)
@@ -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; i<INT_REG_CNT; ++i) {
                if (i%4 == 0)
@@ -3322,6 +3323,8 @@ void replace_executionstate_println(executionstate_t *es)
        if (es->code != 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);
index 1037494089415627dff83b2a26fc6f60d5c56783..12135a971d9a5b8d3be0042743682702b6932744 100644 (file)
@@ -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 */