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