* configure.ac: Added option --enable-replacement.
[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 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    Contact: cacao@cacaojvm.org
26
27    Authors: Edwin Steiner
28             Christian Thalinger
29
30    $Id$
31
32 */
33
34
35 #include "config.h"
36
37 #include <assert.h>
38
39 #include "vm/types.h"
40
41 #include "arch.h"
42
43 #include "vm/jit/code.h"
44 #include "vm/jit/codegen-common.h"
45 #include "vm/jit/methodheader.h"
46 #include "mm/memory.h"
47 #include "vm/options.h"
48 #include "vm/jit/code.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_get_sync_slot_count ****************************************************
129
130    Return the number of stack slots used for storing the synchronized object
131    (and the return value around lock_monitor_exit calls) by the given code.
132    
133    IN:
134        code.............the codeinfo of the code in question
135                             (must be != NULL)
136
137    RETURN VALUE:
138        the number of stack slots used for synchronization
139   
140 *******************************************************************************/
141
142 #if defined(ENABLE_REPLACEMENT)
143 int code_get_sync_slot_count(codeinfo *code)
144 {
145 #ifdef ENABLE_THREADS
146         int count;
147         
148         assert(code);
149
150         if (!checksync)
151                 return 0;
152
153         if (!(code->m->flags & ACC_SYNCHRONIZED))
154                 return 0;
155
156         count = 1;
157
158 #ifdef HAS_4BYTE_STACKSLOT
159         /* long and double need 2 4-byte slots */
160         if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
161                 count++;
162 #endif
163
164 #if defined(__POWERPC__)
165         /* powerpc needs an extra slot */
166         count++;
167 #endif
168
169         return count;
170
171 #else /* !ENABLE_THREADS */
172         
173         return 0;
174
175 #endif /* ENABLE_THREADS */
176 }
177 #endif /* defined(ENABLE_REPLACEMENT) */
178
179
180 /* code_get_stack_frame_size ***************************************************
181
182    Return the number of stack slots that the stack frame of the given code
183    comprises.
184
185    IMPORTANT: The return value does *not* include the saved return address 
186               slot, although it is part of non-leaf stack frames on RISC
187                           architectures. The rationale behind this is that the saved
188                           return address is never moved or changed by replacement, and
189                           this way CISC and RISC architectures can be treated the same.
190                           (See also doc/stack_frames.txt.)
191    
192    IN:
193        code.............the codeinfo of the code in question
194                             (must be != NULL)
195
196    RETURN VALUE:
197        the number of stack slots
198   
199 *******************************************************************************/
200
201 #if defined(ENABLE_REPLACEMENT)
202 int code_get_stack_frame_size(codeinfo *code)
203 {
204 #if 0
205         int count;
206         
207         assert(code);
208
209         /* slots allocated by register allocator plus saved registers */
210
211 #ifdef HAS_4BYTE_STACKSLOT
212         count = code->memuse + code->savedintcount + 2*code->savedfltcount;
213 #else
214         count = code->memuse + code->savedintcount + code->savedfltcount;
215 #endif
216
217         /* add slots needed in synchronized methods */
218
219         count += code_get_sync_slot_count(code);
220
221         /* keep stack aligned */
222
223 #if defined(__X86_64__)
224         /* the x86_64 codegen only aligns the stack in non-leaf methods */
225         if (!code->isleafmethod || opt_verbosecall)
226                 count |= 1; /* even when return address is added */
227 #endif
228
229         /* XXX align stack on alpha */
230 #if defined(__MIPS__)
231         if (code->isleafmethod)
232                 count = (count + 1) & ~1;
233         else
234                 count |= 1; /* even when return address is added */
235 #endif
236
237 #if defined(__POWERPC__)
238         /* keep stack 16-byte aligned */
239         count = (count + 3) & ~3;
240 #endif
241
242         return count;
243 #endif
244
245         return code->stackframesize;
246 }
247 #endif /* defined(ENABLE_REPLACEMENT) */
248
249
250 /* code_codeinfo_free **********************************************************
251
252    Free the memory used by a codeinfo.
253    
254    IN:
255        code.............the codeinfo to free
256
257 *******************************************************************************/
258
259 void code_codeinfo_free(codeinfo *code)
260 {
261         if (code == NULL)
262                 return;
263
264         if (code->mcode != NULL)
265                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
266
267 #if defined(ENABLE_REPLACEMENT)
268         replace_free_replacement_points(code);
269 #endif
270
271         FREE(code, codeinfo);
272
273 #if defined(ENABLE_STATISTICS)
274         if (opt_stat)
275                 size_codeinfo -= sizeof(codeinfo);
276 #endif
277 }
278
279
280 /* code_free_code_of_method ****************************************************
281
282    Free all codeinfos of the given method
283    
284    IN:
285        m................the method of which the codeinfos are to be freed
286
287 *******************************************************************************/
288
289 void code_free_code_of_method(methodinfo *m)
290 {
291         codeinfo *nextcode;
292         codeinfo *code;
293
294         if (!m)
295                 return;
296         
297         nextcode = m->code;
298         while (nextcode) {
299                 code = nextcode;
300                 nextcode = code->prev;
301                 code_codeinfo_free(code);
302         }
303
304         m->code = NULL;
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  */