8b9360abcf1420abb16808fb3ba10c54658355d0
[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 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31
32 #include "vm/types.h"
33
34 #include "arch.h"
35
36 #include "mm/memory.h"
37
38 #if defined(ENABLE_THREADS)
39 # include "threads/native/lock.h"
40 #endif
41
42 #include "vm/jit/code.h"
43 #include "vm/jit/codegen-common.h"
44 #include "vm/jit/methodheader.h"
45 #include "vm/jit/patcher-common.h"
46
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        patchers
78
79    RETURN VALUE:
80        a new, initialized codeinfo, or
81            NULL if an exception occurred.
82   
83 *******************************************************************************/
84
85 codeinfo *code_codeinfo_new(methodinfo *m)
86 {
87         codeinfo *code;
88
89         code = NEW(codeinfo);
90
91         code->m = m;
92
93         patcher_list_create(code);
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 code_get_codeinfo_for_pv(pv);
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         u1 *pv;
145
146         pv = codegen_get_pv_from_pc_nocheck(pc);
147
148         if (pv == NULL)
149                 return NULL;
150
151         return code_get_codeinfo_for_pv(pv);
152 }
153
154
155 /* code_get_codeinfo_for_pv ****************************************************
156
157    Return the codeinfo for the given PV.
158
159    IN:
160        pv...............PV
161
162    RETURN VALUE:
163        the codeinfo *
164
165 *******************************************************************************/
166
167 codeinfo *code_get_codeinfo_for_pv(u1 *pv)
168 {
169         codeinfo *code;
170
171         assert(pv != NULL);
172
173         code = *((codeinfo **) (pv + CodeinfoPointer));
174
175         return code;
176 }
177
178
179 /* code_get_methodinfo_for_pv **************************************************
180
181    Return the methodinfo for the given PV.
182
183    IN:
184        pv...............PV
185
186    RETURN VALUE:
187        the methodinfo *
188
189 *******************************************************************************/
190
191 methodinfo *code_get_methodinfo_for_pv(u1 *pv)
192 {
193         codeinfo *code;
194
195         code = code_get_codeinfo_for_pv(pv);
196
197         /* This is the case for asm_vm_call_method. */
198
199         if (code == NULL)
200                 return NULL;
201
202         return code->m;
203 }
204
205
206 /* code_get_sync_slot_count ****************************************************
207
208    Return the number of stack slots used for storing the synchronized object
209    (and the return value around lock_monitor_exit calls) by the given code.
210    
211    IN:
212        code.............the codeinfo of the code in question
213                             (must be != NULL)
214
215    RETURN VALUE:
216        the number of stack slots used for synchronization
217   
218 *******************************************************************************/
219
220 #if defined(ENABLE_REPLACEMENT)
221 int code_get_sync_slot_count(codeinfo *code)
222 {
223 #ifdef ENABLE_THREADS
224         int count;
225         
226         assert(code);
227
228         if (!checksync)
229                 return 0;
230
231         if (!(code->m->flags & ACC_SYNCHRONIZED))
232                 return 0;
233
234         count = 1;
235
236 #ifdef HAS_4BYTE_STACKSLOT
237         /* long and double need 2 4-byte slots */
238         if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
239                 count++;
240 #endif
241
242 #if defined(__POWERPC__)
243         /* powerpc needs an extra slot */
244         count++;
245 #endif
246
247         return count;
248
249 #else /* !ENABLE_THREADS */
250         
251         return 0;
252
253 #endif /* ENABLE_THREADS */
254 }
255 #endif /* defined(ENABLE_REPLACEMENT) */
256
257
258 /* code_codeinfo_free **********************************************************
259
260    Free the memory used by a codeinfo.
261    
262    IN:
263        code.............the codeinfo to free
264
265 *******************************************************************************/
266
267 void code_codeinfo_free(codeinfo *code)
268 {
269         if (code == NULL)
270                 return;
271
272         if (code->mcode != NULL)
273                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
274
275         patcher_list_free(code);
276
277 #if defined(ENABLE_REPLACEMENT)
278         replace_free_replacement_points(code);
279 #endif
280
281         FREE(code, codeinfo);
282
283 #if defined(ENABLE_STATISTICS)
284         if (opt_stat)
285                 size_codeinfo -= sizeof(codeinfo);
286 #endif
287 }
288
289
290 /* code_free_code_of_method ****************************************************
291
292    Free all codeinfos of the given method
293    
294    IN:
295        m................the method of which the codeinfos are to be freed
296
297 *******************************************************************************/
298
299 void code_free_code_of_method(methodinfo *m)
300 {
301         codeinfo *nextcode;
302         codeinfo *code;
303
304         if (!m)
305                 return;
306         
307         nextcode = m->code;
308         while (nextcode) {
309                 code = nextcode;
310                 nextcode = code->prev;
311                 code_codeinfo_free(code);
312         }
313
314         m->code = NULL;
315 }
316
317 /*
318  * These are local overrides for various environment variables in Emacs.
319  * Please do not remove this and leave it at the end of the file, where
320  * Emacs will automagically detect them.
321  * ---------------------------------------------------------------------
322  * Local variables:
323  * mode: c
324  * indent-tabs-mode: t
325  * c-basic-offset: 4
326  * tab-width: 4
327  * End:
328  * vim:noexpandtab:sw=4:ts=4:
329  */