* src/vm/jit/code.c [ENABLE_THREADS] (threads/native/lock.h): Added.
[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_THREADS)
96         lock_init_object_lock(&code->header);
97 #endif
98
99 #if defined(ENABLE_STATISTICS)
100         if (opt_stat)
101                 size_codeinfo += sizeof(codeinfo);
102 #endif
103
104         return code;
105 }
106
107
108 /* code_find_codeinfo_for_pc ***************************************************
109
110    Return the codeinfo for the compilation unit that contains the
111    given PC.
112
113    IN:
114        pc...............machine code position
115
116    RETURN VALUE:
117        the codeinfo * for the given PC
118
119 *******************************************************************************/
120
121 codeinfo *code_find_codeinfo_for_pc(u1 *pc)
122 {
123         u1 *pv;
124
125         pv = codegen_get_pv_from_pc(pc);
126         assert(pv);
127
128         return *(codeinfo **)(pv + CodeinfoPointer);
129 }
130
131
132 /* code_get_sync_slot_count ****************************************************
133
134    Return the number of stack slots used for storing the synchronized object
135    (and the return value around lock_monitor_exit calls) by the given code.
136    
137    IN:
138        code.............the codeinfo of the code in question
139                             (must be != NULL)
140
141    RETURN VALUE:
142        the number of stack slots used for synchronization
143   
144 *******************************************************************************/
145
146 #if defined(ENABLE_REPLACEMENT)
147 int code_get_sync_slot_count(codeinfo *code)
148 {
149 #ifdef ENABLE_THREADS
150         int count;
151         
152         assert(code);
153
154         if (!checksync)
155                 return 0;
156
157         if (!(code->m->flags & ACC_SYNCHRONIZED))
158                 return 0;
159
160         count = 1;
161
162 #ifdef HAS_4BYTE_STACKSLOT
163         /* long and double need 2 4-byte slots */
164         if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
165                 count++;
166 #endif
167
168 #if defined(__POWERPC__)
169         /* powerpc needs an extra slot */
170         count++;
171 #endif
172
173         return count;
174
175 #else /* !ENABLE_THREADS */
176         
177         return 0;
178
179 #endif /* ENABLE_THREADS */
180 }
181 #endif /* defined(ENABLE_REPLACEMENT) */
182
183
184 /* code_get_stack_frame_size ***************************************************
185
186    Return the number of stack slots that the stack frame of the given code
187    comprises.
188
189    IMPORTANT: The return value does *not* include the saved return address 
190               slot, although it is part of non-leaf stack frames on RISC
191                           architectures. The rationale behind this is that the saved
192                           return address is never moved or changed by replacement, and
193                           this way CISC and RISC architectures can be treated the same.
194                           (See also doc/stack_frames.txt.)
195    
196    IN:
197        code.............the codeinfo of the code in question
198                             (must be != NULL)
199
200    RETURN VALUE:
201        the number of stack slots
202   
203 *******************************************************************************/
204
205 #if defined(ENABLE_REPLACEMENT)
206 int code_get_stack_frame_size(codeinfo *code)
207 {
208 #if 0
209         int count;
210         
211         assert(code);
212
213         /* slots allocated by register allocator plus saved registers */
214
215 #ifdef HAS_4BYTE_STACKSLOT
216         count = code->memuse + code->savedintcount + 2*code->savedfltcount;
217 #else
218         count = code->memuse + code->savedintcount + code->savedfltcount;
219 #endif
220
221         /* add slots needed in synchronized methods */
222
223         count += code_get_sync_slot_count(code);
224
225         /* keep stack aligned */
226
227 #if defined(__X86_64__)
228         /* the x86_64 codegen only aligns the stack in non-leaf methods */
229         if (!code->isleafmethod || opt_verbosecall)
230                 count |= 1; /* even when return address is added */
231 #endif
232
233         /* XXX align stack on alpha */
234 #if defined(__MIPS__)
235         if (code->isleafmethod)
236                 count = (count + 1) & ~1;
237         else
238                 count |= 1; /* even when return address is added */
239 #endif
240
241 #if defined(__POWERPC__)
242         /* keep stack 16-byte aligned */
243         count = (count + 3) & ~3;
244 #endif
245
246         return count;
247 #endif
248
249         return code->stackframesize;
250 }
251 #endif /* defined(ENABLE_REPLACEMENT) */
252
253
254 /* code_codeinfo_free **********************************************************
255
256    Free the memory used by a codeinfo.
257    
258    IN:
259        code.............the codeinfo to free
260
261 *******************************************************************************/
262
263 void code_codeinfo_free(codeinfo *code)
264 {
265         if (code == NULL)
266                 return;
267
268         if (code->mcode != NULL)
269                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
270
271 #if defined(ENABLE_REPLACEMENT)
272         replace_free_replacement_points(code);
273 #endif
274
275         FREE(code, codeinfo);
276
277 #if defined(ENABLE_STATISTICS)
278         if (opt_stat)
279                 size_codeinfo -= sizeof(codeinfo);
280 #endif
281 }
282
283
284 /* code_free_code_of_method ****************************************************
285
286    Free all codeinfos of the given method
287    
288    IN:
289        m................the method of which the codeinfos are to be freed
290
291 *******************************************************************************/
292
293 void code_free_code_of_method(methodinfo *m)
294 {
295         codeinfo *nextcode;
296         codeinfo *code;
297
298         if (!m)
299                 return;
300         
301         nextcode = m->code;
302         while (nextcode) {
303                 code = nextcode;
304                 nextcode = code->prev;
305                 code_codeinfo_free(code);
306         }
307
308         m->code = NULL;
309 }
310
311 /*
312  * These are local overrides for various environment variables in Emacs.
313  * Please do not remove this and leave it at the end of the file, where
314  * Emacs will automagically detect them.
315  * ---------------------------------------------------------------------
316  * Local variables:
317  * mode: c
318  * indent-tabs-mode: t
319  * c-basic-offset: 4
320  * tab-width: 4
321  * End:
322  * vim:noexpandtab:sw=4:ts=4:
323  */