* Merged executionstate branch.
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Tue, 22 Apr 2008 11:53:13 +0000 (13:53 +0200)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Tue, 22 Apr 2008 11:53:13 +0000 (13:53 +0200)
src/vm/jit/Makefile.am
src/vm/jit/alpha/linux/md-os.c
src/vm/jit/executionstate.c [new file with mode: 0644]
src/vm/jit/executionstate.h [new file with mode: 0644]
src/vm/jit/i386/darwin/md-os.c
src/vm/jit/i386/linux/md-os.c
src/vm/jit/powerpc/linux/md-os.c
src/vm/jit/replace.c
src/vm/jit/replace.h
src/vm/jit/x86_64/linux/md-os.c

index 04201005f68383d1855d758ce7f3c99d628baa9a..c44f0129e57414a011bf69ab01d8158e4242651b 100644 (file)
@@ -151,6 +151,8 @@ libjit_la_SOURCES = \
        emit-common.h \
        exceptiontable.c \
        exceptiontable.h \
+       executionstate.c \
+       executionstate.h \
        icmdtable.inc \
        jit.c \
        jit.h \
index c080a7bc22a6837b633a89beb10aed9d5030f08a..08a85f07e6e33425b3983a0792dc28df980f44e0 100644 (file)
 #include "vm/signallocal.h"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
 #include "vm/jit/stacktrace.h"
 
+#include "vmcore/system.h"
+
 
 /* md_signal_handler_sigsegv ***************************************************
 
@@ -204,18 +207,17 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-/* md_replace_executionstate_read **********************************************
+/* md_executionstate_read ******************************************************
 
-   Read the given context into an executionstate for Replacement.
+   Read the given context into an executionstate.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_read(executionstate_t *es, void *context)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
-       s4          i;
+       int         i;
 
        _uc = (ucontext_t *) context;
        _mc = &_uc->uc_mcontext;
@@ -235,23 +237,21 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
         * the _mc->sc_fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs));
-       memcpy(&es->fltregs, &_mc->sc_fpregs, sizeof(_mc->sc_fpregs));
+       system_memcpy(&es->fltregs, &_mc->sc_fpregs, sizeof(_mc->sc_fpregs));
 }
-#endif
 
 
-/* md_replace_executionstate_write *********************************************
+/* md_executionstate_write *****************************************************
 
-   Write the given executionstate back to the context for Replacement.
+   Write the given executionstate back to the context.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_write(executionstate_t *es, void *context)
+void md_executionstate_write(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
-       s4          i;
+       int         i;
 
        _uc = (ucontext_t *) context;
        _mc = &_uc->uc_mcontext;
@@ -265,7 +265,7 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
         * the _mc->sc_fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs));
-       memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs));
+       system_memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs));
 
        /* write special registers */
        _mc->sc_pc           = (ptrint) es->pc;
@@ -273,7 +273,6 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
        _mc->sc_regs[REG_PV] = (ptrint) es->pv;
        _mc->sc_regs[REG_RA] = (ptrint) es->ra;
 }
-#endif
 
 
 /* md_critical_section_restart *************************************************
diff --git a/src/vm/jit/executionstate.c b/src/vm/jit/executionstate.c
new file mode 100644 (file)
index 0000000..f9a7e1d
--- /dev/null
@@ -0,0 +1,258 @@
+/* src/vm/jit/executionstate.c - execution-state handling
+
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "md-abi.h"
+
+#include "vm/jit/abi.h"
+#include "vm/jit/executionstate.h"
+
+#include "vmcore/descriptor.h"
+#include "vmcore/system.h"
+
+
+/* executionstate_sanity_check *************************************************
+
+   Perform some sanity checks for the md_executionstate_read and
+   md_executionstate_write functions.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void executionstate_sanity_check(void *context)
+{
+    /* estimate a minimum for the context size */
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+#define MINIMUM_CONTEXT_SIZE  (SIZEOF_VOID_P    * ADR_REG_CNT \
+                                      + sizeof(double) * FLT_REG_CNT \
+                                                          + sizeof(int)    * INT_REG_CNT)
+#else
+#define MINIMUM_CONTEXT_SIZE  (SIZEOF_VOID_P    * INT_REG_CNT \
+                                      + sizeof(double) * FLT_REG_CNT)
+#endif
+
+       executionstate_t es1;
+       executionstate_t es2;
+       executionstate_t es3;
+       unsigned int i;
+       unsigned char reference[MINIMUM_CONTEXT_SIZE];
+
+       /* keep a copy of (a prefix of) the context for reference */
+
+       system_memcpy(&reference, context, MINIMUM_CONTEXT_SIZE);
+
+       /* different poisons */
+
+       system_memset(&es1, 0xc9, sizeof(executionstate_t));
+       system_memset(&es2, 0xb5, sizeof(executionstate_t));
+       system_memset(&es3, 0x6f, sizeof(executionstate_t));
+
+       md_executionstate_read(&es1, context);
+
+       /* verify that item-by-item copying preserves the state */
+
+       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];
+       for (i = 0; i < FLT_REG_CNT; ++i)
+               es2.fltregs[i] = es1.fltregs[i];
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i = 0; i < ADR_REG_CNT; ++i)
+               es2.adrregs[i] = es1.adrregs[i];
+#endif
+
+       /* write it back - this should not change the context */
+       /* We cannot check that completely, unfortunately, as we don't know */
+       /* the size of the (OS-dependent) context. */
+
+       md_executionstate_write(&es2, context);
+
+       /* Read it again, Sam! */
+
+       md_executionstate_read(&es3, context);
+
+       /* Compare. Note: Because of the NAN madness, we cannot compare
+        * doubles using '=='. */
+
+       assert(es3.pc == es1.pc);
+       assert(es3.sp == es1.sp);
+       assert(es3.pv == es1.pv);
+       for (i = 0; i < INT_REG_CNT; ++i)
+               assert(es3.intregs[i] == es1.intregs[i]);
+       for (i = 0; i < FLT_REG_CNT; ++i)
+               assert(memcmp(es3.fltregs+i, es1.fltregs+i, sizeof(double)) == 0);
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i = 0; i < ADR_REG_CNT; ++i)
+               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);
+
+       /* assert that we have not messed up the context */
+
+       assert(memcmp(&reference, context, MINIMUM_CONTEXT_SIZE) == 0);
+}
+#endif
+
+
+/* executionstate_println ******************************************************
+   Print execution state
+  
+   IN:
+       es...............the execution state to print
+  
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void executionstate_println(executionstate_t *es)
+{
+       uint64_t *sp;
+       int       slots;
+       int       extraslots;
+       int       i;
+
+       if (!es) {
+               printf("(executionstate_t *)NULL\n");
+               return;
+       }
+
+       printf("executionstate_t:\n");
+       printf("\tpc = %p", es->pc);
+       printf("  sp = %p", es->sp);
+       printf("  pv = %p", es->pv);
+       printf("  ra = %p\n", es->ra);
+
+#if defined(ENABLE_DISASSEMBLER)
+       for (i=0; i<INT_REG_CNT; ++i) {
+               if (i%4 == 0)
+                       printf("\t");
+               else
+                       printf(" ");
+# if SIZEOF_VOID_P == 8
+               printf("%-3s = %016lx", abi_registers_integer_name[i], es->intregs[i]);
+# else
+               printf("%-3s = %08x", abi_registers_integer_name[i], es->intregs[i]);
+# endif
+               if (i%4 == 3)
+                       printf("\n");
+       }
+
+       for (i=0; i<FLT_REG_CNT; ++i) {
+               if (i%4 == 0)
+                       printf("\t");
+               else
+                       printf(" ");
+               printf("F%02d = %016llx",i,(unsigned long long)es->fltregs[i]);
+               if (i%4 == 3)
+                       printf("\n");
+       }
+
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (i%4 == 0)
+                       printf("\t");
+               else
+                       printf(" ");
+               printf("A%02d = %016llx",i,(unsigned long long)es->adrregs[i]);
+               if (i%4 == 3)
+                       printf("\n");
+       }
+# endif
+#endif
+
+       sp = (uint64_t *) es->sp;
+
+       extraslots = 2;
+
+       if (es->code) {
+               methoddesc *md = es->code->m->parseddesc;
+               slots = es->code->stackframesize;
+               extraslots = 1 + md->memuse;
+       }
+       else
+               slots = 0;
+
+
+       if (slots) {
+               printf("\tstack slots(+%d) at sp:", extraslots);
+               for (i=0; i<slots+extraslots; ++i) {
+                       if (i%4 == 0)
+                               printf("\n\t\t");
+                       printf("M%02d%c", i, (i >= slots) ? '(' : ' ');
+#ifdef HAS_4BYTE_STACKSLOT
+                       printf("%08lx",(unsigned long)*sp++);
+#else
+                       printf("%016llx",(unsigned long long)*sp++);
+#endif
+                       printf("%c", (i >= slots) ? ')' : ' ');
+               }
+               printf("\n");
+       }
+
+       printf("\tcode: %p", (void*)es->code);
+       if (es->code != NULL) {
+               printf(" stackframesize=%d ", es->code->stackframesize);
+               method_print(es->code->m);
+       }
+       printf("\n");
+
+       printf("\n");
+}
+#endif
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vm/jit/executionstate.h b/src/vm/jit/executionstate.h
new file mode 100644 (file)
index 0000000..46211e7
--- /dev/null
@@ -0,0 +1,96 @@
+/* src/vm/jit/executionstate.h - execution-state handling
+
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _EXECUTIONSTATE_H
+#define _EXECUTIONSTATE_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct executionstate_t executionstate_t;
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "arch.h"
+#include "md-abi.h"
+
+#include "vm/jit/code.h"
+
+
+/* executionstate_t ************************************************************
+
+   An execution-state represents the state of a thread containing all
+   registers that are important.  This structure is an internal
+   structure similar to mcontext_t.
+
+*******************************************************************************/
+
+struct executionstate_t {
+       uint8_t   *pc;                                         /* program counter */
+       uint8_t   *sp;                             /* stack pointer within method */
+       uint8_t   *pv;                             /* procedure value. NULL means */
+                                                  /* search the AVL tree         */
+       uint8_t   *ra;                          /* return address / link register */
+
+       uintptr_t  intregs[INT_REG_CNT];                       /* register values */
+       double     fltregs[FLT_REG_CNT];                       /* register values */
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       uintptr_t  adrregs[ADR_REG_CNT];                       /* register values */
+#endif
+
+       codeinfo  *code;                      /* codeinfo corresponding to the pv */
+};
+
+
+/* prototypes *****************************************************************/
+
+#if !defined(NDEBUG)
+void executionstate_sanity_check(void *context);
+void executionstate_println(executionstate_t *es);
+#endif
+
+/* Machine and OS dependent functions (code in ARCH_DIR/OS_DIR/md-os.c) */
+
+void md_executionstate_read(executionstate_t *es, void *ucontext);
+void md_executionstate_write(executionstate_t *es, void *ucontext);
+
+#endif /* _EXECUTIONSTATE_H */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index c1bd25b3f535f407681ccca24492d865043c9ab9..a58cbb937c1a0da8d048e4deb5c9164caf6ebe28 100644 (file)
@@ -42,7 +42,9 @@
 #include "vm/global.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
 #include "vm/jit/stacktrace.h"
 
 #include "vm/jit/i386/codegen.h"
@@ -280,22 +282,21 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
        }
 }
 
-/* md_replace_executionstate_read **********************************************
+/* md_executionstate_read ******************************************************
 
-   Read the given context into an executionstate for Replacement.
+   Read the given context into an executionstate.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_read(executionstate_t *es, void *context)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
-       ucontext_t *_uc;
-       mcontext_t *_mc; 
+       ucontext_t          *_uc;
+       mcontext_t           _mc; 
        i386_thread_state_t *_ss;
-       s4          i; 
+       int                  i;
 
        _uc = (ucontext_t *) context;
-       _mc = &_uc->uc_mcontext;
+       _mc = _uc->uc_mcontext;
        _ss = &_mc->ss;
 
        /* read special registers */
@@ -317,25 +318,23 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
        for (i = 0; i < FLT_REG_CNT; i++)
                es->fltregs[i] = 0xdeadbeefdeadbeefULL;
 }
-#endif
 
 
-/* md_replace_executionstate_write *********************************************
+/* md_executionstate_write *****************************************************
 
-   Write the given executionstate back to the context for Replacement.
+   Write the given executionstate back to the context.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_write(executionstate_t *es, void *context)
+void md_executionstate_write(executionstate_t *es, void *context)
 {
-       ucontext_t *_uc;
-       mcontext_t *_mc;
-       i386_thread_state_t *_ss;
-       s4          i;
+       ucontext_t*          _uc;
+       mcontext_t           _mc;
+       i386_thread_state_t_ss;
+       int                  i;
 
        _uc = (ucontext_t *) context;
-       _mc = &_uc->uc_mcontext;
+       _mc = _uc->uc_mcontext;
        _ss = &_mc->ss;
 
        /* write integer registers */
@@ -352,7 +351,6 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
        _ss->eip = (ptrint) es->pc;
        _ss->esp = (ptrint) es->sp;
 }
-#endif
 
 
 /* md_critical_section_restart *************************************************
index de50d8115332e588a0ebd814d09b5aa5b89b7ad1..92bb757315c97b42ed1451fc7ce72c295b7c0ad8 100644 (file)
@@ -43,6 +43,7 @@
 #include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
 #include "vm/jit/stacktrace.h"
 
 
@@ -300,14 +301,13 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-/* md_replace_executionstate_read **********************************************
+/* md_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)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
@@ -329,17 +329,15 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
        for (i = 0; i < FLT_REG_CNT; i++)
                es->fltregs[i] = 0xdeadbeefdeadbeefULL;
 }
-#endif
 
 
-/* md_replace_executionstate_write *********************************************
+/* md_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)
+void md_executionstate_write(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
@@ -356,7 +354,6 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
        _mc->gregs[REG_EIP] = (ptrint) es->pc;
        _mc->gregs[REG_ESP] = (ptrint) es->sp;
 }
-#endif
 
 
 /* md_critical_section_restart *************************************************
index f6395dcd67a59dbb9033ce0f8279b07f26bd7f9a..cdc937f5a8e329af60f7d9b1d1ff3aeb0bd52cec 100644 (file)
@@ -41,7 +41,9 @@
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
 
 #if defined(ENABLE_PROFILING)
 # include "vm/jit/optimizing/profile.h"
@@ -49,6 +51,8 @@
 
 #include "vm/jit/stacktrace.h"
 
+#include "vmcore/system.h"
+
 
 /* md_signal_handler_sigsegv ***************************************************
 
@@ -296,14 +300,13 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-/* md_replace_executionstate_read **********************************************
+/* md_executionstate_read ******************************************************
 
-   Read the given context into an executionstate for Replacement.
+   Read the given context into an executionstate.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_read(executionstate_t *es, void *context)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
        ucontext_t    *_uc;
        mcontext_t    *_mc;
@@ -313,7 +316,7 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
        _uc = (ucontext_t *) context;
 
 #if defined(__UCLIBC__)
-#error Please port md_replace_executionstate_read to __UCLIBC__
+#error Please port md_executionstate_read to __UCLIBC__
 #else
        _mc    = _uc->uc_mcontext.uc_regs;
        _gregs = _mc->gregs;
@@ -334,19 +337,17 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
         * 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));
+       system_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs));
 }
-#endif
 
 
-/* md_replace_executionstate_write *********************************************
+/* md_executionstate_write *****************************************************
 
-   Write the given executionstate back to the context for Replacement.
+   Write the given executionstate back to the context.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_write(executionstate_t *es, void *context)
+void md_executionstate_write(executionstate_t *es, void *context)
 {
        ucontext_t    *_uc;
        mcontext_t    *_mc;
@@ -356,7 +357,7 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
        _uc = (ucontext_t *) context;
 
 #if defined(__UCLIBC__)
-#error Please port md_replace_executionstate_read to __UCLIBC__
+#error Please port md_executionstate_write to __UCLIBC__
 #else
        _mc    = _uc->uc_mcontext.uc_regs;
        _gregs = _mc->gregs;
@@ -371,7 +372,7 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
         * 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));
+       system_memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs));
 
        /* write special registers */
        _gregs[PT_NIP] = (ptrint) es->pc;
@@ -379,7 +380,6 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
        _gregs[REG_PV] = (ptrint) es->pv;
        _gregs[PT_LNK] = (ptrint) es->ra;
 }
-#endif
 
 
 /* md_critical_section_restart *************************************************
index fe3f9bc365d170c91ad9c13241b817fd6fdeddfb..5895bec0688a9368f4e8491e57c582ef0bf5be16 100644 (file)
@@ -47,6 +47,7 @@
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/disass.h"
+#include "vm/jit/executionstate.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/replace.h"
@@ -113,7 +114,6 @@ typedef u8 stackslot_t;
 #if !defined(NDEBUG)
 static void java_value_print(s4 type, replace_val_t value);
 static void replace_stackframeinfo_println(stackframeinfo_t *sfi);
-static void replace_sanity_check_read_write(void *context);
 #endif
 
 #if !defined(NDEBUG)
@@ -2418,7 +2418,7 @@ sourcestate_t *replace_recover_source_state(rplpoint *rp,
 
        while (rp || sfi) {
 
-               DOLOG( replace_executionstate_println(es); );
+               DOLOG( executionstate_println(es); );
 
                /* if we are not at a replacement point, it is a native frame */
 
@@ -2701,7 +2701,7 @@ static void replace_build_execution_state(sourcestate_t *ss,
 
                        replace_push_activation_record(es, rp, prevframe, ss->frames);
 
-                       DOLOG( replace_executionstate_println(es); );
+                       DOLOG( executionstate_println(es); );
                }
 
                rp = ss->frames->torp;
@@ -2721,7 +2721,7 @@ static void replace_build_execution_state(sourcestate_t *ss,
 
                replace_write_executionstate(rp, es, ss, ss->frames->down == NULL);
 
-               DOLOG( replace_executionstate_println(es); );
+               DOLOG( executionstate_println(es); );
 
                if (rp->type == RPLPOINT_TYPE_CALL) {
                        parent = NULL;
@@ -2903,7 +2903,7 @@ bool replace_me_wrapper(u1 *pc, void *context)
        if ((rp != NULL) && (rp->pc == pc) && (rp->flags & RPLPOINT_FLAG_ACTIVE)) {
 
 #if !defined(NDEBUG)
-               replace_sanity_check_read_write(context);
+               executionstate_sanity_check(context);
 #endif
 
                /* set codeinfo pointer in execution state */
@@ -2912,10 +2912,10 @@ bool replace_me_wrapper(u1 *pc, void *context)
 
                /* read execution state from current context */
 
-               md_replace_executionstate_read(&es, context);
+               md_executionstate_read(&es, context);
 
                DOLOG( printf("REPLACEMENT READ: ");
-                          replace_executionstate_println(&es); );
+                          executionstate_println(&es); );
 
                /* do the actual replacement */
 
@@ -2923,10 +2923,10 @@ bool replace_me_wrapper(u1 *pc, void *context)
 
                /* write execution state to current context */
 
-               md_replace_executionstate_write(&es, context);
+               md_executionstate_write(&es, context);
 
                DOLOG( printf("REPLACEMENT WRITE: ");
-                          replace_executionstate_println(&es); );
+                          executionstate_println(&es); );
 
                /* new code is entered after returning */
 
@@ -3227,111 +3227,6 @@ void replace_show_replacement_points(codeinfo *code)
 #endif
 
 
-/* replace_executionstate_println **********************************************
-   Print execution state
-  
-   IN:
-       es...............the execution state to print
-  
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void replace_executionstate_println(executionstate_t *es)
-{
-       int i;
-       int slots;
-       stackslot_t *sp;
-       int extraslots;
-
-       if (!es) {
-               printf("(executionstate_t *)NULL\n");
-               return;
-       }
-
-       printf("executionstate_t:\n");
-       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)
-                       printf("\t");
-               else
-                       printf(" ");
-#if SIZEOF_VOID_P == 8
-               printf("%-3s = %016llx",abi_registers_integer_name[i],(unsigned long long)es->intregs[i]);
-#else
-               printf("%-3s = %08lx",abi_registers_integer_name[i],(unsigned long)es->intregs[i]);
-#endif
-               if (i%4 == 3)
-                       printf("\n");
-       }
-       for (i=0; i<FLT_REG_CNT; ++i) {
-               if (i%4 == 0)
-                       printf("\t");
-               else
-                       printf(" ");
-               printf("F%02d = %016llx",i,(unsigned long long)es->fltregs[i]);
-               if (i%4 == 3)
-                       printf("\n");
-       }
-# if defined(HAS_ADDRESS_REGISTER_FILE)
-       for (i=0; i<ADR_REG_CNT; ++i) {
-               if (i%4 == 0)
-                       printf("\t");
-               else
-                       printf(" ");
-               printf("A%02d = %016llx",i,(unsigned long long)es->adrregs[i]);
-               if (i%4 == 3)
-                       printf("\n");
-       }
-# endif
-#endif
-
-       sp = (stackslot_t *) es->sp;
-
-       extraslots = 2;
-
-       if (es->code) {
-               methoddesc *md = es->code->m->parseddesc;
-               slots = es->code->stackframesize;
-               extraslots = 1 + md->memuse;
-       }
-       else
-               slots = 0;
-
-
-       if (slots) {
-               printf("\tstack slots(+%d) at sp:", extraslots);
-               for (i=0; i<slots+extraslots; ++i) {
-                       if (i%4 == 0)
-                               printf("\n\t\t");
-                       printf("M%02d%c", i, (i >= slots) ? '(' : ' ');
-#ifdef HAS_4BYTE_STACKSLOT
-                       printf("%08lx",(unsigned long)*sp++);
-#else
-                       printf("%016llx",(unsigned long long)*sp++);
-#endif
-                       printf("%c", (i >= slots) ? ')' : ' ');
-               }
-               printf("\n");
-       }
-
-       printf("\tcode: %p", (void*)es->code);
-       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");
-
-       printf("\n");
-}
-#endif
-
 #if !defined(NDEBUG)
 static void java_value_print(s4 type, replace_val_t value)
 {
@@ -3530,7 +3425,7 @@ void replace_sourcestate_println_short(sourcestate_t *ss)
 
                if (REPLACE_IS_NATIVE_FRAME(frame)) {
                        printf("NATIVE (pc %p size %d) ",
-                                       (void*)frame->nativepc, frame->nativeframesize);
+                                  (void*)frame->nativepc, frame->nativeframesize);
                        replace_stackframeinfo_println(frame->sfi);
                        continue;
                }
@@ -3571,105 +3466,6 @@ static void replace_stackframeinfo_println(stackframeinfo_t *sfi)
 #endif
 
 
-/* replace_sanity_check_read_write *********************************************
-
-   Perform some sanity checks for the md_replace_executionstate_read
-   and md_replace_executionstate_write functions.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-static void replace_sanity_check_read_write(void *context)
-{
-    /* estimate a minimum for the context size */
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-#define MINIMUM_CONTEXT_SIZE  (SIZEOF_VOID_P    * ADR_REG_CNT \
-                                      + sizeof(double) * FLT_REG_CNT \
-                                                          + sizeof(int)    * INT_REG_CNT)
-#else
-#define MINIMUM_CONTEXT_SIZE  (SIZEOF_VOID_P    * INT_REG_CNT \
-                                      + sizeof(double) * FLT_REG_CNT)
-#endif
-
-       executionstate_t es1;
-       executionstate_t es2;
-       executionstate_t es3;
-       unsigned int i;
-       unsigned char reference[MINIMUM_CONTEXT_SIZE];
-
-       /* keep a copy of (a prefix of) the context for reference */
-
-       memcpy(&reference, context, MINIMUM_CONTEXT_SIZE);
-
-       /* different poisons */
-
-       memset(&es1, 0xc9, sizeof(executionstate_t));
-       memset(&es2, 0xb5, sizeof(executionstate_t));
-       memset(&es3, 0x6f, sizeof(executionstate_t));
-
-       md_replace_executionstate_read(&es1, context);
-
-       /* verify that item-by-item copying preserves the state */
-
-       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];
-       for (i = 0; i < FLT_REG_CNT; ++i)
-               es2.fltregs[i] = es1.fltregs[i];
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       for (i = 0; i < ADR_REG_CNT; ++i)
-               es2.adrregs[i] = es1.adrregs[i];
-#endif
-
-       /* write it back - this should not change the context */
-       /* We cannot check that completely, unfortunately, as we don't know */
-       /* the size of the (OS-dependent) context. */
-
-       md_replace_executionstate_write(&es2, context);
-
-       /* Read it again, Sam! */
-
-       md_replace_executionstate_read(&es3, context);
-
-       /* Compare. Note: Because of the NAN madness, we cannot compare
-        * doubles using '=='. */
-
-       assert(es3.pc == es1.pc);
-       assert(es3.sp == es1.sp);
-       assert(es3.pv == es1.pv);
-       for (i = 0; i < INT_REG_CNT; ++i)
-               assert(es3.intregs[i] == es1.intregs[i]);
-       for (i = 0; i < FLT_REG_CNT; ++i)
-               assert(memcmp(es3.fltregs+i, es1.fltregs+i, sizeof(double)) == 0);
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       for (i = 0; i < ADR_REG_CNT; ++i)
-               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);
-
-       /* assert that we have not messed up the context */
-
-       assert(memcmp(&reference, context, MINIMUM_CONTEXT_SIZE) == 0);
-}
-#endif
-
-
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index 12135a971d9a5b8d3be0042743682702b6932744..752cd385f4c8f8a633638c33688272101c781511 100644 (file)
@@ -52,7 +52,6 @@
 
 typedef struct rplalloc rplalloc;
 typedef struct rplpoint rplpoint;
-typedef struct executionstate_t executionstate_t;
 typedef struct sourcestate_t sourcestate_t;
 typedef struct sourceframe_t sourceframe_t;
 typedef union  replace_val_t replace_val_t;
@@ -141,26 +140,7 @@ union replace_val_t {
 };
 
 
-/* An `executionsstate` represents the state of a thread as it reached */
-/* an replacement point or is about to enter one.                      */
-
-struct executionstate_t {
-       u1           *pc;                               /* program counter */
-       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 */
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       ptrint        adrregs[ADR_REG_CNT];             /* register values */
-#endif
-
-       codeinfo     *code;            /* codeinfo corresponding to the pv */
-};
-
-
 struct sourceframe_t {
        sourceframe_t *down;           /* source frame down the call chain */
 
@@ -273,7 +253,6 @@ bool replace_me_wrapper(u1 *pc, void *context);
 #if !defined(NDEBUG)
 void replace_show_replacement_points(codeinfo *code);
 void replace_replacement_point_println(rplpoint *rp, int depth);
-void replace_executionstate_println(executionstate_t *es);
 void replace_sourcestate_println(sourcestate_t *ss);
 void replace_sourcestate_println_short(sourcestate_t *ss);
 void replace_source_frame_println(sourceframe_t *frame);
@@ -285,11 +264,6 @@ void replace_source_frame_println(sourceframe_t *frame);
 void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert);
 #endif
 
-/* machine and OS dependent functions (code in ARCH_DIR/OS_DIR/md-os.c) */
-
-void md_replace_executionstate_read(executionstate_t *es, void *context);
-void md_replace_executionstate_write(executionstate_t *es, void *context);
-
 #endif /* defined(ENABLE_REPLACEMENT) */
 
 #endif /* _REPLACE_H */
index 1a2e7dbf008eac1732af273ddeeccdd158e9731d..aa81679c819f0efe948371c6c05d4665e8040fa3 100644 (file)
@@ -44,6 +44,7 @@
 #include "vm/signallocal.h"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
 #include "vm/jit/stacktrace.h"
 
 
@@ -360,14 +361,13 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-/* md_replace_executionstate_read **********************************************
+/* md_executionstate_read ******************************************************
 
-   Read the given context into an executionstate for Replacement.
+   Read the given context into an executionstate.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_read(executionstate_t *es, void *context)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
@@ -430,17 +430,15 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
        for (i = 0; i < FLT_REG_CNT; i++)
                es->fltregs[i] = 0xdeadbeefdeadbeefL;
 }
-#endif
 
 
-/* md_replace_executionstate_write *********************************************
+/* md_executionstate_write *****************************************************
 
-   Write the given executionstate back to the context for Replacement.
+   Write the given executionstate back to the context.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_write(executionstate_t *es, void *context)
+void md_executionstate_write(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
@@ -498,7 +496,6 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
        _mc->gregs[REG_RIP] = (ptrint) es->pc;
        _mc->gregs[REG_RSP] = (ptrint) es->sp;
 }
-#endif
 
 
 /* md_critical_section_restart *************************************************