1 /* src/vm/jit/intrp/engine.c - #included by engine1.c and engine2.c
3 Copyright (C) 1996-2005, 2006, 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
26 /* #define VM_DEBUG */
36 #include "vm/jit/intrp/intrp.h"
38 #include "md-abi.h" /* required for TRACE_ARGS_NUM */
40 #include "mm/memory.h"
42 #include "threads/thread.h"
44 #include "vm/builtin.h"
45 #include "vm/exceptions.h"
47 #include "vm/jit/methodheader.h"
48 #include "vm/jit/patcher.h"
49 #include "vm/jit/stacktrace.hpp"
51 #include "vmcore/loader.h"
52 #include "vmcore/options.h"
55 #if defined(ENABLE_THREADS)
56 # include "threads/atomic.hpp"
59 #if !defined(STORE_ORDER_BARRIER) && !defined(ENABLE_THREADS)
60 #define STORE_ORDER_BARRIER() /* nothing */
64 /* threading macros */
65 #define GCC_PR15242_WORKAROUND
66 #ifdef GCC_PR15242_WORKAROUND
68 # define DO_GOTO goto before_goto
71 # define DO_GOTO goto *ip[-1]
76 # define SET_IP(p) do {ip=(p); NEXT_P0;} while (0)
77 # define NEXT_INST (*IP)
78 # define INC_IP(const_inc) do { ip+=(const_inc);} while (0)
80 # define NEXT_P1 (ip++)
81 # define NEXT_P2 do {NEXT_P1_5; DO_GOTO;} while(0)
83 #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
84 #define IPTOS NEXT_INST
86 #if defined(__POWERPC__) || defined(__POWERPC64__) || defined(__SPARC__)
90 #if defined(USE_spTOS)
98 /* works with gcc-2.95.4 20011002 (Debian prerelease) without static supers */
99 #define SPREG /* __asm__("%esi") */
100 #define TOSREG /* __asm__("%ecx") */
101 #elif defined(__X86_64__)
102 /* works with gcc-4.0.2 (Debian 4.0.2-2) */
103 #define SPREG /* __asm__("%r15") */
111 /* conversion on fetch */
114 #define SUPER_END vm_count_block(IP)
117 #define vm_uncount_block(_ip) /* nothing */
121 #define THROW0 goto throw
123 #define THROW(_ball) do { \
124 __asm__(""); /* work around gcc PR 25285 */ \
125 goto *throw_##_ball; \
128 #define THROW(_ball) do { \
129 goto throw_##_ball##1; \
133 #define THROWCODE(_ball) \
136 *exceptionptr = (stacktrace_inline_##_ball(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP)); \
140 #define CHECK_NULL_PTR(ptr) \
142 if ((ptr) == NULL) { \
143 THROW(nullpointerexception); \
147 #define THROW_CLASSCASTEXCEPTION(o) \
149 classcastexception_object = o; \
150 THROW(classcastexception); \
153 #define CHECK_OUT_OF_BOUNDS(_array, _idx) \
155 if (length_array(_array) <= (u4) (_idx)) { \
156 arrayindexoutofbounds_index = (_idx); \
157 THROW(arrayindexoutofboundsexception); \
161 #define CHECK_ZERO_DIVISOR(_divisor) \
162 { if (_divisor == 0) \
163 THROW(arithmeticexception); \
167 /* !! alignment bug */
168 #define access_local_long(_offset) \
169 ( *(s8 *)(((u1 *)fp) + (_offset)) )
172 #define length_array(array) \
173 ( ((java_arrayheader*)(array))->size )
175 #define access_array_int(array, index) \
176 ((((java_intarray*)(array))->data)[index])
178 #define access_array_long(array, index) \
179 ((((java_longarray*)(array))->data)[index])
181 #define access_array_char(array, index) \
182 ((((java_chararray*)(array))->data)[index])
184 #define access_array_short(array, index) \
185 ((((java_shortarray*)(array))->data)[index])
187 #define access_array_byte(array, index) \
188 ((((java_bytearray*)(array))->data)[index])
190 #define access_array_addr(array, index) \
191 ((((java_objectarray*)(array))->data)[index])
193 #define access_array_float(array, index) \
194 ((((java_floatarray*)(array))->data)[index])
196 /* (see createcompilerstub in codegen.c) */
197 #define FRAMESIZE(stub) (((Cell *)stub)[1])
200 #define CLEARSTACK(_start, _end) \
201 do {Cell *__start=(_start); MSET(__start,0,u1,(_end)-__start); } while (0)
203 #define CLEARSTACK(_start, _end)
208 #define NAME(_x) if (vm_debug) {fprintf(vm_out, "%lx: %-20s, ", (long)(ip-1), _x); fprintf(vm_out,"fp=%p, sp=%p", fp, sp);}
213 #define LABEL2(name) J_##name: __asm__("");
214 #define LABEL3(name) K_##name: __asm__("");
218 engine(Inst *ip0, Cell * sp0, Cell * fp)
221 register Cell *sp SPREG = sp0;
222 /* Inst ca1; XXX unused? */ /* code address; this is the next dispatched instruction */
223 IF_spTOS(register Cell spTOS TOSREG;)
224 static Inst labels[] = {
225 #define INST_ADDR(_inst) (&&I_##_inst)
226 #include <java-labels.i>
229 #define INST_ADDR(_inst) (&&J_##_inst)
230 #include <java-labels.i>
232 #define INST_ADDR(_inst) (&&K_##_inst)
233 #include <java-labels.i>
236 (Label)&&before_goto,
238 #define INST_ADDR(_inst) (&&H_##_inst)
239 #include <java-labels.i>
242 /* local variables for the various throw codes; this helps make
243 potentially throwing instructions relocatable (instead of a
244 non-relocatable direct jump, they perform an indirect jump) */
245 Label throw_arithmeticexception = &&throw_arithmeticexception1;
246 Label throw_arrayindexoutofboundsexception = &&throw_arrayindexoutofboundsexception1;
247 Label throw_classcastexception = &&throw_classcastexception1;
248 Label throw_nullpointerexception = &&throw_nullpointerexception1;
249 Label throw_arraystoreexception = &&throw_arraystoreexception1;
250 java_objectheader *classcastexception_object = NULL;
251 s4 arrayindexoutofbounds_index = 0; /* pass the index to the throw code */
254 fprintf(vm_out,"entering engine(%p,%p,%p)\n",ip0,sp,fp);
256 return (java_objectheader *)labels;
263 /* ensure that gcc does not constant-propagate the contents of
264 these variables and thus undo our relocatability work */
265 throw_arithmeticexception = 0;
266 throw_arrayindexoutofboundsexception = 0;
267 throw_classcastexception = 0;
268 throw_nullpointerexception = 0;
269 throw_arraystoreexception = 0;
271 /* the actual codes jumped to through the ...exception variables */
272 THROWCODE(arithmeticexception);
273 THROWCODE(nullpointerexception);
274 THROWCODE(arraystoreexception);
276 throw_classcastexception1:
278 *exceptionptr = stacktrace_inline_classcastexception(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP, classcastexception_object);
282 throw_arrayindexoutofboundsexception1:
284 *exceptionptr = stacktrace_inline_arrayindexoutofboundsexception(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP, arrayindexoutofbounds_index);
289 /* I don't have a clue where these things come from,
290 but I've put them in macros.h for the moment */
291 IF_spTOS(spTOS = sp[0]);
296 #define INST_ADDR(_inst) (&&I_##_inst)
299 after_last: return NULL;
304 * These are local overrides for various environment variables in Emacs.
305 * Please do not remove this and leave it at the end of the file, where
306 * Emacs will automagically detect them.
307 * ---------------------------------------------------------------------
310 * indent-tabs-mode: t
314 * vim:noexpandtab:sw=4:ts=4: