1 /* src/vm/jit/executionstate.c - execution-state handling
3 Copyright (C) 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 #include "vm/descriptor.h"
36 #include "vm/jit/abi.h"
37 #include "vm/jit/executionstate.h"
40 /* executionstate_sanity_check *************************************************
42 Perform some sanity checks for the md_executionstate_read and
43 md_executionstate_write functions.
45 *******************************************************************************/
48 void executionstate_sanity_check(void *context)
50 /* estimate a minimum for the context size */
52 #if defined(HAS_ADDRESS_REGISTER_FILE)
53 #define MINIMUM_CONTEXT_SIZE (SIZEOF_VOID_P * ADR_REG_CNT \
54 + sizeof(double) * FLT_REG_CNT \
55 + sizeof(int) * INT_REG_CNT)
57 #define MINIMUM_CONTEXT_SIZE (SIZEOF_VOID_P * INT_REG_CNT \
58 + sizeof(double) * FLT_REG_CNT)
65 unsigned char reference[MINIMUM_CONTEXT_SIZE];
67 /* keep a copy of (a prefix of) the context for reference */
69 os_memcpy(&reference, context, MINIMUM_CONTEXT_SIZE);
71 /* different poisons */
73 os_memset(&es1, 0xc9, sizeof(executionstate_t));
74 os_memset(&es2, 0xb5, sizeof(executionstate_t));
75 os_memset(&es3, 0x6f, sizeof(executionstate_t));
77 md_executionstate_read(&es1, context);
79 /* verify that item-by-item copying preserves the state */
86 for (i = 0; i < INT_REG_CNT; ++i)
87 es2.intregs[i] = es1.intregs[i];
88 for (i = 0; i < FLT_REG_CNT; ++i)
89 es2.fltregs[i] = es1.fltregs[i];
90 #if defined(HAS_ADDRESS_REGISTER_FILE)
91 for (i = 0; i < ADR_REG_CNT; ++i)
92 es2.adrregs[i] = es1.adrregs[i];
95 /* write it back - this should not change the context */
96 /* We cannot check that completely, unfortunately, as we don't know */
97 /* the size of the (OS-dependent) context. */
99 md_executionstate_write(&es2, context);
101 /* Read it again, Sam! */
103 md_executionstate_read(&es3, context);
105 /* Compare. Note: Because of the NAN madness, we cannot compare
106 * doubles using '=='. */
108 assert(es3.pc == es1.pc);
109 assert(es3.sp == es1.sp);
110 assert(es3.pv == es1.pv);
111 for (i = 0; i < INT_REG_CNT; ++i)
112 assert(es3.intregs[i] == es1.intregs[i]);
113 for (i = 0; i < FLT_REG_CNT; ++i)
114 assert(memcmp(es3.fltregs+i, es1.fltregs+i, sizeof(double)) == 0);
115 #if defined(HAS_ADDRESS_REGISTER_FILE)
116 for (i = 0; i < ADR_REG_CNT; ++i)
117 assert(es3.adrregs[i] == es1.adrregs[i]);
120 /* i386 and x86_64 do not have an RA register */
122 #if defined(__I386__) || defined(__X86_64__)
123 assert(es3.ra != es1.ra);
125 assert(es3.ra == es1.ra);
128 /* "code" is not set by the md_* functions */
130 assert(es3.code != es1.code);
132 /* assert that we have not messed up the context */
134 assert(memcmp(&reference, context, MINIMUM_CONTEXT_SIZE) == 0);
139 /* executionstate_println ******************************************************
141 Print execution state
144 es...............the execution state to print
146 *******************************************************************************/
149 void executionstate_println(executionstate_t *es)
157 printf("(executionstate_t *)NULL\n");
161 printf("executionstate_t:\n");
162 printf("\tpc = %p", es->pc);
163 printf(" sp = %p", es->sp);
164 printf(" pv = %p", es->pv);
165 printf(" ra = %p\n", es->ra);
167 #if defined(ENABLE_DISASSEMBLER)
168 for (i=0; i<INT_REG_CNT; ++i) {
173 # if SIZEOF_VOID_P == 8
174 printf("%-3s = %016lx", abi_registers_integer_name[i], es->intregs[i]);
176 printf("%-3s = %08x", abi_registers_integer_name[i], (unsigned) es->intregs[i]);
182 for (i=0; i<FLT_REG_CNT; ++i) {
187 printf("F%02d = %016llx",i,(unsigned long long)es->fltregs[i]);
192 # if defined(HAS_ADDRESS_REGISTER_FILE)
193 for (i=0; i<ADR_REG_CNT; ++i) {
198 printf("A%02d = %016llx",i,(unsigned long long)es->adrregs[i]);
205 sp = (uint64_t *) es->sp;
210 methoddesc *md = es->code->m->parseddesc;
211 slots = es->code->stackframesize;
212 extraslots = 1 + md->memuse;
219 printf("\tstack slots(+%d) at sp:", extraslots);
220 for (i=0; i<slots+extraslots; ++i) {
223 printf("M%02d%c", i, (i >= slots) ? '(' : ' ');
224 #ifdef HAS_4BYTE_STACKSLOT
225 printf("%08lx",(unsigned long)*sp++);
227 printf("%016llx",(unsigned long long)*sp++);
229 printf("%c", (i >= slots) ? ')' : ' ');
234 printf("\tcode: %p", (void*)es->code);
235 if (es->code != NULL) {
236 printf(" stackframesize=%d ", es->code->stackframesize);
237 method_print(es->code->m);
247 * These are local overrides for various environment variables in Emacs.
248 * Please do not remove this and leave it at the end of the file, where
249 * Emacs will automagically detect them.
250 * ---------------------------------------------------------------------
253 * indent-tabs-mode: t
257 * vim:noexpandtab:sw=4:ts=4: