82c6ff64a6a9b35e896ff76896ce63b7c4529ae3
[cacao.git] / src / vm / jit / code.c
1 /* src/vm/jit/code.c - codeinfo struct for representing compiled code
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
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.
14
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.
19
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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id$
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33
34 #include "vm/types.h"
35
36 #include "arch.h"
37
38 #include "mm/memory.h"
39
40 #if defined(ENABLE_THREADS)
41 # include "threads/native/lock.h"
42 #endif
43
44 #include "vm/jit/code.h"
45 #include "vm/jit/codegen-common.h"
46 #include "vm/jit/methodheader.h"
47
48 #include "vmcore/options.h"
49
50
51 /* code_init *******************************************************************
52
53    Initialize the code-subsystem.
54
55 *******************************************************************************/
56
57 bool code_init(void)
58 {
59         /* check for offset of code->m == 0 (see comment in code.h) */
60
61         assert(OFFSET(codeinfo, m) == 0);
62
63         /* everything's ok */
64
65         return true;
66 }
67
68
69 /* code_codeinfo_new ***********************************************************
70
71    Create a new codeinfo for the given method.
72    
73    IN:
74        m................method to create a new codeinfo for
75
76    The following fields are set in codeinfo:
77        m
78            isleafmethod
79    all other fields are zeroed
80
81    RETURN VALUE:
82        a new, initialized codeinfo, or
83            NULL if an exception occurred.
84   
85 *******************************************************************************/
86
87 codeinfo *code_codeinfo_new(methodinfo *m)
88 {
89         codeinfo *code;
90
91         code = NEW(codeinfo);
92
93         code->m = m;
94
95 #if defined(ENABLE_STATISTICS)
96         if (opt_stat)
97                 size_codeinfo += sizeof(codeinfo);
98 #endif
99
100         return code;
101 }
102
103
104 /* code_find_codeinfo_for_pc ***************************************************
105
106    Return the codeinfo for the compilation unit that contains the
107    given PC.
108
109    IN:
110        pc...............machine code position
111
112    RETURN VALUE:
113        the codeinfo * for the given PC
114
115 *******************************************************************************/
116
117 codeinfo *code_find_codeinfo_for_pc(u1 *pc)
118 {
119         u1 *pv;
120
121         pv = codegen_get_pv_from_pc(pc);
122         assert(pv);
123
124         return *(codeinfo **)(pv + CodeinfoPointer);
125 }
126
127
128 /* code_find_codeinfo_for_pc ***************************************************
129
130    Return the codeinfo for the compilation unit that contains the
131    given PC. This method does not check the return value and is used
132    by the GC.
133
134    IN:
135        pc...............machine code position
136
137    RETURN VALUE:
138        the codeinfo * for the given PC, or NULL
139
140 *******************************************************************************/
141
142 codeinfo *code_find_codeinfo_for_pc_nocheck(u1 *pc)
143 {
144         codeinfo *code;
145         u1 *pv;
146
147         pv = codegen_get_pv_from_pc_nocheck(pc);
148
149         if (pv == NULL)
150                 return NULL;
151
152         code = *(codeinfo **)(pv + CodeinfoPointer);
153
154         return code;
155 }
156
157
158 /* code_get_methodinfo_for_pv **************************************************
159
160    Return the methodinfo for the given PV.
161
162    IN:
163        pv...............PV
164
165    RETURN VALUE:
166        the methodinfo *
167
168 *******************************************************************************/
169
170 methodinfo *code_get_methodinfo_for_pv(u1 *pv)
171 {
172         codeinfo *code;
173
174         code = *((codeinfo **) (pv + CodeinfoPointer));
175
176         return code->m;
177 }
178
179
180 /* code_get_sync_slot_count ****************************************************
181
182    Return the number of stack slots used for storing the synchronized object
183    (and the return value around lock_monitor_exit calls) by the given code.
184    
185    IN:
186        code.............the codeinfo of the code in question
187                             (must be != NULL)
188
189    RETURN VALUE:
190        the number of stack slots used for synchronization
191   
192 *******************************************************************************/
193
194 #if defined(ENABLE_REPLACEMENT)
195 int code_get_sync_slot_count(codeinfo *code)
196 {
197 #ifdef ENABLE_THREADS
198         int count;
199         
200         assert(code);
201
202         if (!checksync)
203                 return 0;
204
205         if (!(code->m->flags & ACC_SYNCHRONIZED))
206                 return 0;
207
208         count = 1;
209
210 #ifdef HAS_4BYTE_STACKSLOT
211         /* long and double need 2 4-byte slots */
212         if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
213                 count++;
214 #endif
215
216 #if defined(__POWERPC__)
217         /* powerpc needs an extra slot */
218         count++;
219 #endif
220
221         return count;
222
223 #else /* !ENABLE_THREADS */
224         
225         return 0;
226
227 #endif /* ENABLE_THREADS */
228 }
229 #endif /* defined(ENABLE_REPLACEMENT) */
230
231
232 /* code_get_stack_frame_size ***************************************************
233
234    Return the number of stack slots that the stack frame of the given code
235    comprises.
236
237    IMPORTANT: The return value does *not* include the saved return address 
238               slot, although it is part of non-leaf stack frames on RISC
239                           architectures. The rationale behind this is that the saved
240                           return address is never moved or changed by replacement, and
241                           this way CISC and RISC architectures can be treated the same.
242                           (See also doc/stack_frames.txt.)
243    
244    IN:
245        code.............the codeinfo of the code in question
246                             (must be != NULL)
247
248    RETURN VALUE:
249        the number of stack slots
250   
251 *******************************************************************************/
252
253 #if defined(ENABLE_REPLACEMENT)
254 int code_get_stack_frame_size(codeinfo *code)
255 {
256 #if 0
257         int count;
258         
259         assert(code);
260
261         /* slots allocated by register allocator plus saved registers */
262
263 #ifdef HAS_4BYTE_STACKSLOT
264         count = code->memuse + code->savedintcount + 2*code->savedfltcount;
265 #else
266         count = code->memuse + code->savedintcount + code->savedfltcount;
267 #endif
268
269         /* add slots needed in synchronized methods */
270
271         count += code_get_sync_slot_count(code);
272
273         /* keep stack aligned */
274
275 #if defined(__X86_64__)
276         /* the x86_64 codegen only aligns the stack in non-leaf methods */
277         if (!code->isleafmethod || opt_verbosecall)
278                 count |= 1; /* even when return address is added */
279 #endif
280
281         /* XXX align stack on alpha */
282 #if defined(__MIPS__)
283         if (code->isleafmethod)
284                 count = (count + 1) & ~1;
285         else
286                 count |= 1; /* even when return address is added */
287 #endif
288
289 #if defined(__POWERPC__)
290         /* keep stack 16-byte aligned */
291         count = (count + 3) & ~3;
292 #endif
293
294         return count;
295 #endif
296
297         return code->stackframesize;
298 }
299 #endif /* defined(ENABLE_REPLACEMENT) */
300
301
302 /* code_codeinfo_free **********************************************************
303
304    Free the memory used by a codeinfo.
305    
306    IN:
307        code.............the codeinfo to free
308
309 *******************************************************************************/
310
311 void code_codeinfo_free(codeinfo *code)
312 {
313         if (code == NULL)
314                 return;
315
316         if (code->mcode != NULL)
317                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
318
319 #if defined(ENABLE_REPLACEMENT)
320         replace_free_replacement_points(code);
321 #endif
322
323         FREE(code, codeinfo);
324
325 #if defined(ENABLE_STATISTICS)
326         if (opt_stat)
327                 size_codeinfo -= sizeof(codeinfo);
328 #endif
329 }
330
331
332 /* code_free_code_of_method ****************************************************
333
334    Free all codeinfos of the given method
335    
336    IN:
337        m................the method of which the codeinfos are to be freed
338
339 *******************************************************************************/
340
341 void code_free_code_of_method(methodinfo *m)
342 {
343         codeinfo *nextcode;
344         codeinfo *code;
345
346         if (!m)
347                 return;
348         
349         nextcode = m->code;
350         while (nextcode) {
351                 code = nextcode;
352                 nextcode = code->prev;
353                 code_codeinfo_free(code);
354         }
355
356         m->code = NULL;
357 }
358
359 /*
360  * These are local overrides for various environment variables in Emacs.
361  * Please do not remove this and leave it at the end of the file, where
362  * Emacs will automagically detect them.
363  * ---------------------------------------------------------------------
364  * Local variables:
365  * mode: c
366  * indent-tabs-mode: t
367  * c-basic-offset: 4
368  * tab-width: 4
369  * End:
370  * vim:noexpandtab:sw=4:ts=4:
371  */