* This is a rather huge commit, which changes the build order of
[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    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 "mm/memory.h"
44 #include "vm/jit/code.h"
45 #include "vm/jit/codegen-common.h"
46 #include "vm/jit/methodheader.h"
47 #include "vmcore/options.h"
48
49
50 /* code_init *******************************************************************
51
52    Initialize the code-subsystem.
53
54 *******************************************************************************/
55
56 bool code_init(void)
57 {
58         /* check for offset of code->m == 0 (see comment in code.h) */
59
60         assert(OFFSET(codeinfo, m) == 0);
61
62         /* everything's ok */
63
64         return true;
65 }
66
67
68 /* code_codeinfo_new ***********************************************************
69
70    Create a new codeinfo for the given method.
71    
72    IN:
73        m................method to create a new codeinfo for
74
75    The following fields are set in codeinfo:
76        m
77            isleafmethod
78    all other fields are zeroed
79
80    RETURN VALUE:
81        a new, initialized codeinfo, or
82            NULL if an exception occurred.
83   
84 *******************************************************************************/
85
86 codeinfo *code_codeinfo_new(methodinfo *m)
87 {
88         codeinfo *code;
89
90         code = NEW(codeinfo);
91
92         code->m = m;
93
94 #if defined(ENABLE_STATISTICS)
95         if (opt_stat)
96                 size_codeinfo += sizeof(codeinfo);
97 #endif
98
99         return code;
100 }
101
102
103 /* code_find_codeinfo_for_pc ***************************************************
104
105    Return the codeinfo for the compilation unit that contains the
106    given PC.
107
108    IN:
109        pc...............machine code position
110
111    RETURN VALUE:
112        the codeinfo * for the given PC
113
114 *******************************************************************************/
115
116 codeinfo *code_find_codeinfo_for_pc(u1 *pc)
117 {
118         u1 *pv;
119
120         pv = codegen_get_pv_from_pc(pc);
121         assert(pv);
122
123         return *(codeinfo **)(pv + CodeinfoPointer);
124 }
125
126
127 /* code_get_sync_slot_count ****************************************************
128
129    Return the number of stack slots used for storing the synchronized object
130    (and the return value around lock_monitor_exit calls) by the given code.
131    
132    IN:
133        code.............the codeinfo of the code in question
134                             (must be != NULL)
135
136    RETURN VALUE:
137        the number of stack slots used for synchronization
138   
139 *******************************************************************************/
140
141 #if defined(ENABLE_REPLACEMENT)
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 #endif /* defined(ENABLE_REPLACEMENT) */
177
178
179 /* code_get_stack_frame_size ***************************************************
180
181    Return the number of stack slots that the stack frame of the given code
182    comprises.
183
184    IMPORTANT: The return value does *not* include the saved return address 
185               slot, although it is part of non-leaf stack frames on RISC
186                           architectures. The rationale behind this is that the saved
187                           return address is never moved or changed by replacement, and
188                           this way CISC and RISC architectures can be treated the same.
189                           (See also doc/stack_frames.txt.)
190    
191    IN:
192        code.............the codeinfo of the code in question
193                             (must be != NULL)
194
195    RETURN VALUE:
196        the number of stack slots
197   
198 *******************************************************************************/
199
200 #if defined(ENABLE_REPLACEMENT)
201 int code_get_stack_frame_size(codeinfo *code)
202 {
203 #if 0
204         int count;
205         
206         assert(code);
207
208         /* slots allocated by register allocator plus saved registers */
209
210 #ifdef HAS_4BYTE_STACKSLOT
211         count = code->memuse + code->savedintcount + 2*code->savedfltcount;
212 #else
213         count = code->memuse + code->savedintcount + code->savedfltcount;
214 #endif
215
216         /* add slots needed in synchronized methods */
217
218         count += code_get_sync_slot_count(code);
219
220         /* keep stack aligned */
221
222 #if defined(__X86_64__)
223         /* the x86_64 codegen only aligns the stack in non-leaf methods */
224         if (!code->isleafmethod || opt_verbosecall)
225                 count |= 1; /* even when return address is added */
226 #endif
227
228         /* XXX align stack on alpha */
229 #if defined(__MIPS__)
230         if (code->isleafmethod)
231                 count = (count + 1) & ~1;
232         else
233                 count |= 1; /* even when return address is added */
234 #endif
235
236 #if defined(__POWERPC__)
237         /* keep stack 16-byte aligned */
238         count = (count + 3) & ~3;
239 #endif
240
241         return count;
242 #endif
243
244         return code->stackframesize;
245 }
246 #endif /* defined(ENABLE_REPLACEMENT) */
247
248
249 /* code_codeinfo_free **********************************************************
250
251    Free the memory used by a codeinfo.
252    
253    IN:
254        code.............the codeinfo to free
255
256 *******************************************************************************/
257
258 void code_codeinfo_free(codeinfo *code)
259 {
260         if (code == NULL)
261                 return;
262
263         if (code->mcode != NULL)
264                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
265
266 #if defined(ENABLE_REPLACEMENT)
267         replace_free_replacement_points(code);
268 #endif
269
270         FREE(code, codeinfo);
271
272 #if defined(ENABLE_STATISTICS)
273         if (opt_stat)
274                 size_codeinfo -= sizeof(codeinfo);
275 #endif
276 }
277
278
279 /* code_free_code_of_method ****************************************************
280
281    Free all codeinfos of the given method
282    
283    IN:
284        m................the method of which the codeinfos are to be freed
285
286 *******************************************************************************/
287
288 void code_free_code_of_method(methodinfo *m)
289 {
290         codeinfo *nextcode;
291         codeinfo *code;
292
293         if (!m)
294                 return;
295         
296         nextcode = m->code;
297         while (nextcode) {
298                 code = nextcode;
299                 nextcode = code->prev;
300                 code_codeinfo_free(code);
301         }
302
303         m->code = NULL;
304 }
305
306 /*
307  * These are local overrides for various environment variables in Emacs.
308  * Please do not remove this and leave it at the end of the file, where
309  * Emacs will automagically detect them.
310  * ---------------------------------------------------------------------
311  * Local variables:
312  * mode: c
313  * indent-tabs-mode: t
314  * c-basic-offset: 4
315  * tab-width: 4
316  * End:
317  * vim:noexpandtab:sw=4:ts=4:
318  */