emit-common.h \
exceptiontable.c \
exceptiontable.h \
+ executionstate.c \
+ executionstate.h \
icmdtable.inc \
jit.c \
jit.h \
#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 ***************************************************
#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;
* 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;
* 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;
_mc->sc_regs[REG_PV] = (ptrint) es->pv;
_mc->sc_regs[REG_RA] = (ptrint) es->ra;
}
-#endif
/* md_critical_section_restart *************************************************
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
#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"
}
}
-/* 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 */
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 */
_ss->eip = (ptrint) es->pc;
_ss->esp = (ptrint) es->sp;
}
-#endif
/* md_critical_section_restart *************************************************
#include "vm/stringlocal.h"
#include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
#include "vm/jit/stacktrace.h"
#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;
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;
_mc->gregs[REG_EIP] = (ptrint) es->pc;
_mc->gregs[REG_ESP] = (ptrint) es->sp;
}
-#endif
/* md_critical_section_restart *************************************************
#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"
#include "vm/jit/stacktrace.h"
+#include "vmcore/system.h"
+
/* md_signal_handler_sigsegv ***************************************************
#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;
_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;
* 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;
_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;
* 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;
_gregs[REG_PV] = (ptrint) es->pv;
_gregs[PT_LNK] = (ptrint) es->ra;
}
-#endif
/* md_critical_section_restart *************************************************
#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"
#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)
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 */
replace_push_activation_record(es, rp, prevframe, ss->frames);
- DOLOG( replace_executionstate_println(es); );
+ DOLOG( executionstate_println(es); );
}
rp = ss->frames->torp;
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;
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 */
/* 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 */
/* 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 */
#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)
{
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;
}
#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
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;
};
-/* 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 */
#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);
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 */
#include "vm/signallocal.h"
#include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
#include "vm/jit/stacktrace.h"
#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;
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;
_mc->gregs[REG_RIP] = (ptrint) es->pc;
_mc->gregs[REG_RSP] = (ptrint) es->sp;
}
-#endif
/* md_critical_section_restart *************************************************