* src/threads/posix/threads.c: Renamed from here...
[cacao.git] / src / vm / jit / intrp / engine.c
1 /* src/vm/jit/intrp/engine.c - #included by engine1.c and engine2.c
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
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.
12
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.
17
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
21    02110-1301, USA.
22
23 */
24
25
26 /* #define VM_DEBUG */
27
28 #include "config.h"
29
30 #include <assert.h>
31
32 #include "vm/types.h"
33
34 #include "arch.h"
35
36 #include "vm/jit/intrp/intrp.h"
37
38 #include "md-abi.h"                           /* required for TRACE_ARGS_NUM */
39
40 #include "mm/memory.h"
41
42 #include "threads/thread.h"
43
44 #include "vm/builtin.h"
45 #include "vm/exceptions.h"
46
47 #include "vm/jit/methodheader.h"
48 #include "vm/jit/patcher.h"
49 #include "vm/jit/stacktrace.h"
50
51 #include "vmcore/loader.h"
52 #include "vmcore/options.h"
53
54
55 #if defined(ENABLE_THREADS)
56 # ifndef USE_FAKE_ATOMIC_INSTRUCTIONS
57 #  include "machine-instr.h"
58 # else
59 #  include "threads/posix/generic-primitives.h"
60 # endif
61 #endif
62
63 #if !defined(STORE_ORDER_BARRIER) && !defined(ENABLE_THREADS)
64 #define STORE_ORDER_BARRIER() /* nothing */
65 #endif
66
67
68 /* threading macros */
69 #define GCC_PR15242_WORKAROUND
70 #ifdef GCC_PR15242_WORKAROUND
71 #  define NEXT_P1_5
72 #  define DO_GOTO goto before_goto
73 #else
74 #  define NEXT_P1_5
75 #  define DO_GOTO goto *ip[-1]
76 #endif
77
78 #  define NEXT_P0
79 #  define IP            (ip)
80 #  define SET_IP(p)     do {ip=(p); NEXT_P0;} while (0)
81 #  define NEXT_INST     (*IP)
82 #  define INC_IP(const_inc)     do { ip+=(const_inc);} while (0)
83 #  define DEF_CA
84 #  define NEXT_P1       (ip++)
85 #  define NEXT_P2   do {NEXT_P1_5; DO_GOTO;} while(0)
86
87 #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
88 #define IPTOS NEXT_INST
89
90 #if defined(__POWERPC__) || defined(__POWERPC64__) || defined(__SPARC__)
91 # define USE_spTOS
92 #endif
93
94 #if defined(USE_spTOS)
95 #define IF_spTOS(x) x
96 #else
97 #define IF_spTOS(x)
98 #define spTOS (sp[0])
99 #endif
100
101 #if defined(__I386__)
102 /* works with gcc-2.95.4 20011002 (Debian prerelease) without static supers */
103 #define SPREG /* __asm__("%esi") */
104 #define TOSREG /* __asm__("%ecx") */
105 #elif defined(__X86_64__)
106 /* works with gcc-4.0.2 (Debian 4.0.2-2) */
107 #define SPREG /* __asm__("%r15") */
108 #define TOSREG
109 #else
110 #define SPREG
111 #define TOSREG
112 #endif
113
114
115 /* conversion on fetch */
116
117 #ifdef VM_PROFILING
118 #define SUPER_END  vm_count_block(IP)
119 #else
120 #define SUPER_END
121 #define vm_uncount_block(_ip)   /* nothing */
122 #endif
123
124
125 #define THROW0       goto throw
126 #if 1
127 #define THROW(_ball) do { \
128                        __asm__(""); /* work around gcc PR 25285 */ \
129                        goto *throw_##_ball; \
130                      } while (0)
131 #else
132 #define THROW(_ball) do { \
133                        goto throw_##_ball##1; \
134                      } while (0)
135 #endif
136
137 #define THROWCODE(_ball) \
138     throw_##_ball##1: \
139         global_sp = sp; \
140         *exceptionptr = (stacktrace_inline_##_ball(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP)); \
141         CLEAR_global_sp; \
142         THROW0;
143
144 #define CHECK_NULL_PTR(ptr) \
145     { \
146         if ((ptr) == NULL) { \
147             THROW(nullpointerexception); \
148             } \
149         }
150
151 #define THROW_CLASSCASTEXCEPTION(o) \
152     { \
153                 classcastexception_object = o; \
154         THROW(classcastexception); \
155         }
156
157 #define CHECK_OUT_OF_BOUNDS(_array, _idx)              \
158         {                                            \
159           if (length_array(_array) <= (u4) (_idx)) { \
160                 arrayindexoutofbounds_index = (_idx); \
161                                 THROW(arrayindexoutofboundsexception); \
162           } \
163         }
164
165 #define CHECK_ZERO_DIVISOR(_divisor) \
166   { if (_divisor == 0) \
167       THROW(arithmeticexception); \
168   } 
169
170 #if 0
171 /* !! alignment bug */
172 #define access_local_long(_offset) \
173         ( *(s8 *)(((u1 *)fp) + (_offset)) )
174 #endif
175
176 #define length_array(array)                          \
177         ( ((java_arrayheader*)(array))->size )
178
179 #define access_array_int(array, index)               \
180         ((((java_intarray*)(array))->data)[index])
181
182 #define access_array_long(array, index)               \
183         ((((java_longarray*)(array))->data)[index])
184
185 #define access_array_char(array, index)               \
186         ((((java_chararray*)(array))->data)[index])
187
188 #define access_array_short(array, index)               \
189         ((((java_shortarray*)(array))->data)[index])
190
191 #define access_array_byte(array, index)               \
192         ((((java_bytearray*)(array))->data)[index])
193
194 #define access_array_addr(array, index)               \
195         ((((java_objectarray*)(array))->data)[index])
196
197 #define access_array_float(array, index)               \
198         ((((java_floatarray*)(array))->data)[index])
199
200 /* (see createcompilerstub in codegen.c) */
201 #define FRAMESIZE(stub) (((Cell *)stub)[1])
202
203 #if 0
204 #define CLEARSTACK(_start, _end) \
205          do {Cell *__start=(_start); MSET(__start,0,u1,(_end)-__start); } while (0)
206 #else
207 #define CLEARSTACK(_start, _end)
208 #endif
209
210
211 #ifdef VM_DEBUG
212 #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 #else
214 #define NAME(_x)
215 #endif
216
217 #define LABEL2(name) J_##name: __asm__("");
218 #define LABEL3(name) K_##name: __asm__("");
219
220
221 java_objectheader *
222 engine(Inst *ip0, Cell * sp0, Cell * fp)
223 {
224   Inst *ip;
225   register Cell *sp SPREG = sp0;
226   /* Inst ca1; XXX unused? */ /* code address; this is the next dispatched instruction */
227   IF_spTOS(register Cell spTOS TOSREG;)
228   static Inst   labels[] = {
229 #define INST_ADDR(_inst) (&&I_##_inst)
230 #include <java-labels.i>
231 #undef INST_ADDR
232           NULL,
233 #define INST_ADDR(_inst) (&&J_##_inst)
234 #include <java-labels.i>
235 #undef INST_ADDR
236 #define INST_ADDR(_inst) (&&K_##_inst)
237 #include <java-labels.i>
238 #undef INST_ADDR
239     (Label)&&after_last,
240     (Label)&&before_goto,
241     (Label)&&after_goto,
242 #define INST_ADDR(_inst) (&&H_##_inst)
243 #include <java-labels.i>
244 #undef INST_ADDR
245   };
246   /* local variables for the various throw codes; this helps make
247          potentially throwing instructions relocatable (instead of a
248          non-relocatable direct jump, they perform an indirect jump) */
249   Label throw_arithmeticexception            = &&throw_arithmeticexception1;
250   Label throw_arrayindexoutofboundsexception = &&throw_arrayindexoutofboundsexception1;
251   Label throw_classcastexception                         = &&throw_classcastexception1;  
252   Label throw_nullpointerexception                   = &&throw_nullpointerexception1;
253   Label throw_arraystoreexception            = &&throw_arraystoreexception1;
254   java_objectheader *classcastexception_object = NULL;
255   s4 arrayindexoutofbounds_index = 0; /* pass the index to the throw code */
256
257   if (vm_debug)
258       fprintf(vm_out,"entering engine(%p,%p,%p)\n",ip0,sp,fp);
259   if (ip0 == NULL) {
260     return (java_objectheader *)labels;
261   }
262
263   if (0) {
264   before_goto:
265           goto *ip[-1];
266   after_goto:
267           /* ensure that gcc does not constant-propagate the contents of
268                  these variables and thus undo our relocatability work */
269           throw_arithmeticexception = 0;
270           throw_arrayindexoutofboundsexception = 0;
271           throw_classcastexception = 0;
272           throw_nullpointerexception = 0;
273           throw_arraystoreexception = 0;
274
275       /* the actual codes jumped to through the ...exception variables */
276           THROWCODE(arithmeticexception);
277           THROWCODE(nullpointerexception);
278           THROWCODE(arraystoreexception);
279
280   throw_classcastexception1:
281           global_sp = sp;
282           *exceptionptr = stacktrace_inline_classcastexception(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP, classcastexception_object);
283           CLEAR_global_sp;
284           THROW0;
285
286   throw_arrayindexoutofboundsexception1:
287           global_sp = sp;
288           *exceptionptr = stacktrace_inline_arrayindexoutofboundsexception(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP, arrayindexoutofbounds_index);
289           CLEAR_global_sp;
290           THROW0;
291   }
292
293   /* I don't have a clue where these things come from,
294      but I've put them in macros.h for the moment */
295   IF_spTOS(spTOS = sp[0]);
296
297   SET_IP(ip0);
298   NEXT;
299
300 #define INST_ADDR(_inst) (&&I_##_inst)
301 #include <java-vm.i>
302 #undef NAME
303  after_last: return NULL;
304 }
305
306
307 /*
308  * These are local overrides for various environment variables in Emacs.
309  * Please do not remove this and leave it at the end of the file, where
310  * Emacs will automagically detect them.
311  * ---------------------------------------------------------------------
312  * Local variables:
313  * mode: c
314  * indent-tabs-mode: t
315  * c-basic-offset: 4
316  * tab-width: 4
317  * End:
318  * vim:noexpandtab:sw=4:ts=4:
319  */