* src/vm/jit/executionstate.c (executionstate_pop_stackframe): Moved here from
authorMichael Starzinger <michi@complang.tuwien.ac.at>
Wed, 4 Nov 2009 17:32:33 +0000 (18:32 +0100)
committerMichael Starzinger <michi@complang.tuwien.ac.at>
Wed, 4 Nov 2009 17:32:33 +0000 (18:32 +0100)
replacement, was previously called md_pop_stackframe. This is needed for stack
unwinding in C, so this is the right place to put it.
* src/vm/jit/executionstate.h: Added prototype for above function.
* src/vm/jit/replace.cpp: See above.

src/vm/jit/executionstate.c
src/vm/jit/executionstate.h
src/vm/jit/replace.cpp

index 2a7958deac3b2af7435d49cc681d3e32e694d865..c37bb05f4f7c3d00b3a5e0286eb06291f1245586 100644 (file)
@@ -28,6 +28,8 @@
 #include <stdint.h>
 #include <stdio.h>
 
+#include "arch.h"
+#include "md.h"
 #include "md-abi.h"
 
 #include "vm/descriptor.hpp"
 #include "vm/jit/executionstate.h"
 
 
+/**
+ * Restore callee-saved registers (including the RA register),
+ * set the stack pointer to the next stackframe,
+ * set the PC to the return address of the popped frame.
+ *
+ * *** This function imitates the effects of the method epilog ***
+ * *** and returning from the method call.                     ***
+ *
+ * @param es Execution state to be modified.
+ *        NOTE: es->code and es->pv are NOT updated.
+ */
+void executionstate_pop_stackframe(executionstate_t *es)
+{
+       int32_t reg;
+       int32_t i;
+
+       // Sanity checks.
+       assert(es->code != NULL);
+
+       // Calculate the size of the stackframe.
+       int32_t framesize = md_stacktrace_get_framesize(es->code);
+
+       // Read the return address.
+       uint8_t* ra;
+#if STACKFRAME_LEAFMETHODS_RA_REGISTER
+       if (code_is_leafmethod(es->code))
+               ra = es->ra;
+       else
+#endif
+               ra = (u1*) md_stacktrace_get_returnaddress(es->sp, framesize);
+
+       // Calculate the base of the stack frame.
+       uintptr_t sp     = (uintptr_t) es->sp;
+       uintptr_t basesp = sp + es->code->stackframesize * SIZE_OF_STACKSLOT;
+
+       // Restore return address, if part of frame.
+#if STACKFRAME_RA_TOP_OF_FRAME
+# if STACKFRAME_LEAFMETHODS_RA_REGISTER
+       if (!code_is_leafmethod(es->code)) {
+# endif
+               basesp -= 1 * SIZE_OF_STACKSLOT;
+               es->ra = *((uint8_t**) basesp);
+# if STACKFRAME_LEAFMETHODS_RA_REGISTER
+       }
+# endif
+#endif /* STACKFRAME_RA_TOP_OF_FRAME */
+
+       // Restore return address, if inside linkage area.
+#if STACKFRAME_RA_LINKAGE_AREA
+# if STACKFRAME_LEAFMETHODS_RA_REGISTER
+       if (!code_is_leafmethod(es->code))
+# endif
+               es->ra = *((uint8_t**) (basesp + LA_LR_OFFSET));
+#endif /* STACKFRAME_RA_LINKAGE_AREA */
+
+       // Restore saved int registers.
+       reg = INT_REG_CNT;
+       for (i=0; i<es->code->savedintcount; ++i) {
+               while (nregdescint[--reg] != REG_SAV)
+                       ;
+               basesp -= 1 * SIZE_OF_STACKSLOT;
+               es->intregs[reg] = *((uintptr_t*) basesp);
+       }
+
+       // Restore saved flt registers.
+       // XXX align?
+       reg = FLT_REG_CNT;
+       for (i=0; i<es->code->savedfltcount; ++i) {
+               while (nregdescfloat[--reg] != REG_SAV)
+                       ;
+               basesp -= STACK_SLOTS_PER_FLOAT * SIZE_OF_STACKSLOT;
+               es->fltregs[reg] = *((double*) basesp);
+       }
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       // Restore saved adr registers.
+       reg = ADR_REG_CNT;
+       for (i=0; i<es->code->savedadrcount; ++i) {
+               while (nregdescadr[--reg] != REG_SAV)
+                       ;
+               basesp -= 1 * SIZE_OF_STACKSLOT;
+               es->adrregs[reg] = *((uintptr_t*) basesp);
+       }
+#endif
+
+       // Adjust the stackpointer.
+       es->sp += framesize;
+#if STACKFRMAE_RA_BETWEEN_FRAMES
+       es->sp += SIZEOF_VOID_P; /* skip return address */
+#endif
+
+       // Set the program counter to the return address.
+       es->pc = ra;
+
+       // In debugging mode clobber non-saved registers.
+#if !defined(NDEBUG)
+       for (i=0; i<INT_REG_CNT; ++i)
+               if (nregdescint[i] != REG_SAV)
+                       es->intregs[i] = (ptrint) 0x33dead3333dead33ULL;
+       for (i=0; i<FLT_REG_CNT; ++i)
+               if (nregdescfloat[i] != REG_SAV)
+                       *(u8*)&(es->fltregs[i]) = 0x33dead3333dead33ULL;
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i=0; i<ADR_REG_CNT; ++i)
+               if (nregdescadr[i] != REG_SAV)
+                       es->adrregs[i] = (ptrint) 0x33dead3333dead33ULL;
+# endif
+#endif /* !defined(NDEBUG) */
+}
+
+
 /* executionstate_sanity_check *************************************************
 
    Perform some sanity checks for the md_executionstate_read and
index 59e14ea4be23ef7e8ce7c6c47e12e0feff8842f5..08dcc5dd8250b87885112e2b9a918e7b472e3e21 100644 (file)
@@ -41,6 +41,13 @@ typedef struct executionstate_t executionstate_t;
 #include "vm/jit/code.hpp"
 
 
+/* configuration of native stack slot size ************************************/
+
+#define SIZE_OF_STACKSLOT      8
+#define STACK_SLOTS_PER_FLOAT  1
+typedef uint64_t stackslot_t;
+
+
 /* executionstate_t ************************************************************
 
    An execution-state represents the state of a thread containing all
@@ -72,6 +79,8 @@ struct executionstate_t {
 extern "C" {
 #endif
 
+void executionstate_pop_stackframe(executionstate_t *es);
+
 #if !defined(NDEBUG)
 void executionstate_sanity_check(void *context);
 void executionstate_println(executionstate_t *es);
index 67878da59d2d4a8af0c9e90bf100f315f75b124e..8b080b8753bc3680a072e088f41f9c5335d2634b 100644 (file)
 #endif
 
 
-/*** configuration of native stack slot size **********************************/
-
-/* XXX this should be in md-abi.h files, probably */
-
-#define SIZE_OF_STACKSLOT      8
-#define STACK_SLOTS_PER_FLOAT  1
-typedef u8 stackslot_t;
-
-
 /*** debugging ****************************************************************/
 
 #if !defined(NDEBUG)
@@ -1461,132 +1452,6 @@ static void replace_write_executionstate(rplpoint *rp,
 }
 
 
-/* md_pop_stackframe ***********************************************************
-
-   Restore callee-saved registers (including the RA register),
-   set the stack pointer to the next stackframe,
-   set the PC to the return address of the popped frame.
-
-   *** 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
-                        NOTE: es->code and es->pv are NOT updated.
-
-*******************************************************************************/
-
-void md_pop_stackframe(executionstate_t *es)
-{
-       u1 *ra;
-       s4 framesize;
-       s4 reg;
-       s4 i;
-       stackslot_t *basesp;
-       stackslot_t *sp;
-
-       assert(es->code);
-
-       /* calculate the size of the stackframe */
-
-       framesize = md_stacktrace_get_framesize(es->code);
-
-       /* read the return address */
-
-#if STACKFRAME_LEAFMETHODS_RA_REGISTER
-       if (code_is_leafmethod(es->code))
-               ra = es->ra;
-       else
-#endif
-               ra = (u1*) md_stacktrace_get_returnaddress(es->sp, framesize);
-
-       /* calculate the base of the stack frame */
-
-       sp = (stackslot_t *) es->sp;
-       basesp = sp + es->code->stackframesize;
-
-       /* restore return address, if part of frame */
-
-#if STACKFRAME_RA_TOP_OF_FRAME
-# if STACKFRAME_LEAFMETHODS_RA_REGISTER
-       if (!code_is_leafmethod(es->code))
-# endif
-               es->ra = (u1*) (ptrint) *--basesp;
-#endif /* STACKFRAME_RA_TOP_OF_FRAME */
-
-#if STACKFRAME_RA_LINKAGE_AREA
-# if STACKFRAME_LEAFMETHODS_RA_REGISTER
-       if (!code_is_leafmethod(es->code))
-# endif
-               es->ra = *((uint8_t**) ((intptr_t) basesp + LA_LR_OFFSET));
-#endif /* STACKFRAME_RA_LINKAGE_AREA */
-
-       /* restore saved int registers */
-
-       reg = INT_REG_CNT;
-       for (i=0; i<es->code->savedintcount; ++i) {
-               while (nregdescint[--reg] != REG_SAV)
-                       ;
-               basesp -= 1;
-               es->intregs[reg] = *((uintptr_t*) basesp);
-       }
-
-       /* restore saved flt registers */
-
-       /* XXX align? */
-       reg = FLT_REG_CNT;
-       for (i=0; i<es->code->savedfltcount; ++i) {
-               while (nregdescfloat[--reg] != REG_SAV)
-                       ;
-               basesp -= STACK_SLOTS_PER_FLOAT;
-               es->fltregs[reg] = *((double*) basesp);
-       }
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       /* restore saved adr registers */
-
-       reg = ADR_REG_CNT;
-       for (i=0; i<es->code->savedadrcount; ++i) {
-               while (nregdescadr[--reg] != REG_SAV)
-                       ;
-               basesp -= 1;
-               es->adrregs[reg] = *((uintptr_t*) basesp);
-       }
-#endif
-
-       /* adjust the stackpointer */
-
-       es->sp += framesize;
-#if STACKFRMAE_RA_BETWEEN_FRAMES
-       es->sp += SIZEOF_VOID_P; /* skip return address */
-#endif
-
-       /* set the program counter to the return address */
-
-       es->pc = ra;
-
-       /* in debugging mode clobber non-saved registers */
-
-#if !defined(NDEBUG)
-       /* for debugging */
-       for (i=0; i<INT_REG_CNT; ++i)
-               if (nregdescint[i] != REG_SAV)
-                       es->intregs[i] = (ptrint) 0x33dead3333dead33ULL;
-       for (i=0; i<FLT_REG_CNT; ++i)
-               if (nregdescfloat[i] != REG_SAV)
-                       *(u8*)&(es->fltregs[i]) = 0x33dead3333dead33ULL;
-# if defined(HAS_ADDRESS_REGISTER_FILE)
-       for (i=0; i<ADR_REG_CNT; ++i)
-               if (nregdescadr[i] != REG_SAV)
-                       es->adrregs[i] = (ptrint) 0x33dead3333dead33ULL;
-# endif
-#endif /* !defined(NDEBUG) */
-}
-
-
 /* md_push_stackframe **********************************************************
 
    Save the given return address, build the new stackframe,
@@ -1767,7 +1632,7 @@ u1* replace_pop_activation_record(executionstate_t *es,
 
        /* pop the stackframe */
 
-       md_pop_stackframe(es);
+       executionstate_pop_stackframe(es);
 
        ra = es->pc;