1 /* src/vm/jit/intrp/engine.c - #included by engine1.c and engine2.c
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
32 $Id: engine.c 3895 2005-12-07 16:03:37Z anton $
37 /* #define VM_DEBUG */
41 #include "vm/jit/intrp/intrp.h"
43 #include "md-abi.h" /* required for TRACE_ARGS_NUM */
45 #include "cacao/cacao.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/jit/codegen.inc.h"
51 #include "vm/jit/methodheader.h"
52 #include "vm/jit/patcher.h"
57 # include "ffcall/avcall/avcall.h"
59 # include "libffi/include/ffi.h"
62 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
63 # ifndef USE_MD_THREAD_STUFF
64 # include "machine-instr.h"
66 # include "threads/native/generic-primitives.h"
70 #if !defined(STORE_ORDER_BARRIER) && !defined(USE_THREADS)
71 #define STORE_ORDER_BARRIER() /* nothing */
75 /* threading macros */
76 #define GCC_PR15242_WORKAROUND
77 #ifdef GCC_PR15242_WORKAROUND
78 #define DO_GOTO goto before_goto
80 #define DO_GOTO goto *ca
85 # define SET_IP(p) do {ip=(p); NEXT_P0;} while (0)
86 # define NEXT_INST (*IP)
87 # define INC_IP(const_inc) do { ip+=(const_inc);} while (0)
89 # define NEXT_P1 (ip++)
90 # define NEXT_P1_5 do {ca=ip[-1];} while(0)
91 # define NEXT_P2 do {NEXT_P1_5; DO_GOTO;} while(0)
93 #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
94 #define IPTOS NEXT_INST
96 #if defined(USE_spTOS)
100 #define spTOS (sp[0])
103 /* conversion on fetch */
106 #define SUPER_END vm_count_block(IP)
109 #define vm_uncount_block(_ip) /* nothing */
113 #define THROW0 goto throw
114 #define THROW(_ball) do { \
115 __asm__(""); /* work around gcc PR 25285 */ \
116 goto *throw_##_ball; \
119 #define THROWCODE(_ball) \
122 *exceptionptr = (stacktrace_inline_##_ball(NULL, (u1 *) fp, (functionptr) IP, (functionptr) IP)); \
126 #define CHECK_NULL_PTR(ptr) \
128 if ((ptr) == NULL) { \
129 THROW(nullpointerexception); \
133 #define CHECK_OUT_OF_BOUNDS(_array, _idx) \
135 if (length_array(_array) <= (u4) (_idx)) { \
136 arrayindexoutofbounds_index = (_idx); \
137 THROW(arrayindexoutofboundsexception); \
141 #define CHECK_ZERO_DIVISOR(_divisor) \
142 { if (_divisor == 0) \
143 THROW(arithmeticexception); \
147 /* !! alignment bug */
148 #define access_local_long(_offset) \
149 ( *(s8 *)(((u1 *)fp) + (_offset)) )
152 #define length_array(array) \
153 ( ((java_arrayheader*)(array))->size )
155 #define access_array_int(array, index) \
156 ((((java_intarray*)(array))->data)[index])
158 #define access_array_long(array, index) \
159 ((((java_longarray*)(array))->data)[index])
161 #define access_array_char(array, index) \
162 ((((java_chararray*)(array))->data)[index])
164 #define access_array_short(array, index) \
165 ((((java_shortarray*)(array))->data)[index])
167 #define access_array_byte(array, index) \
168 ((((java_bytearray*)(array))->data)[index])
170 #define access_array_addr(array, index) \
171 ((((java_objectarray*)(array))->data)[index])
173 #define MAXLOCALS(stub) (((Cell *)stub)[1])
176 #define CLEARSTACK(_start, _end) \
177 do {Cell *__start=(_start); MSET(__start,0,u1,(_end)-__start); } while (0)
179 #define CLEARSTACK(_start, _end)
184 #define NAME(_x) if (vm_debug) {fprintf(vm_out, "%lx: %-20s, ", (long)(ip-1), _x); fprintf(vm_out,"fp=%p, sp=%p", fp, sp);}
189 #define LABEL2(name) J_##name: __asm__("");
190 #define LABEL3(name) K_##name: __asm__("");
194 engine(Inst *ip0, Cell * sp, Cell * fp)
197 Inst ca; /* code address; this is the next dispatched instruction */
198 IF_spTOS(Cell spTOS);
199 static Inst labels[] = {
200 #define INST_ADDR(_inst) (&&I_##_inst)
201 #include "java-labels.i"
204 #define INST_ADDR(_inst) (&&J_##_inst)
205 #include "java-labels.i"
207 #define INST_ADDR(_inst) (&&K_##_inst)
208 #include "java-labels.i"
211 (Label)&&before_goto,
213 #define INST_ADDR(_inst) (&&H_##_inst)
214 #include "java-labels.i"
217 /* local variables for the various throw codes; this helps make
218 potentially throwing instructions relocatable (instead of a
219 non-relocatable direct jump, they perform an indirect jump) */
220 Label throw_arithmeticexception = &&throw_arithmeticexception1;
221 Label throw_arrayindexoutofboundsexception = &&throw_arrayindexoutofboundsexception1;
222 Label throw_classcastexception = &&throw_classcastexception1;
223 Label throw_nullpointerexception = &&throw_nullpointerexception1;
224 Label throw_arraystoreexception = &&throw_arraystoreexception1;
225 s4 arrayindexoutofbounds_index; /* pass the index to the throw code */
228 fprintf(vm_out,"entering engine(%p,%p,%p)\n",ip0,sp,fp);
230 return (java_objectheader *)labels;
237 /* ensure that gcc does not constant-propagate the contents of
238 these variables and thus undo our relocatability work */
239 throw_arithmeticexception = 0;
240 throw_arrayindexoutofboundsexception = 0;
241 throw_classcastexception = 0;
242 throw_nullpointerexception = 0;
243 throw_arraystoreexception = 0;
245 /* the actual codes jumped to through the ...exception variables */
246 THROWCODE(arithmeticexception);
247 THROWCODE(classcastexception);
248 THROWCODE(nullpointerexception);
249 THROWCODE(arraystoreexception);
251 throw_arrayindexoutofboundsexception1:
253 *exceptionptr = stacktrace_inline_arrayindexoutofboundsexception(NULL, (u1 *) fp, (functionptr) IP, (functionptr) IP, arrayindexoutofbounds_index);
258 /* I don't have a clue where these things come from,
259 but I've put them in macros.h for the moment */
260 IF_spTOS(spTOS = sp[0]);
265 #define INST_ADDR(_inst) (&&I_##_inst)
268 after_last: return NULL;
273 * These are local overrides for various environment variables in Emacs.
274 * Please do not remove this and leave it at the end of the file, where
275 * Emacs will automagically detect them.
276 * ---------------------------------------------------------------------
279 * indent-tabs-mode: t