- created jitcache-arm-x86 branch
[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, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30
31 #include "arch.h"
32
33 #include "mm/memory.h"
34
35 #include "vm/vm.h"
36
37 #include "vm/jit/code.h"
38 #include "vm/jit/codegen-common.h"
39 #include "vm/jit/jitcache.h"
40 #include "vm/jit/methodtree.h"
41 #include "vm/jit/patcher-common.h"
42
43 #include "vmcore/options.h"
44
45
46 /* code_init *******************************************************************
47
48    Initialize the code-subsystem.
49
50 *******************************************************************************/
51
52 void code_init(void)
53 {
54         /* Check if offset of codeinfo.m == 0 (see comment in code.h). */
55
56         if (OFFSET(codeinfo, m) != 0)
57                 vm_abort("code_init: offset of codeinfo.m != 0: %d != 0", OFFSET(codeinfo, m));
58 }
59
60
61 /* code_codeinfo_new ***********************************************************
62
63    Create a new codeinfo for the given method.
64    
65    IN:
66        m................method to create a new codeinfo for
67
68    The following fields are set in codeinfo:
69        m
70        patchers
71            cachedrefs
72
73    RETURN VALUE:
74        a new, initialized codeinfo, or
75            NULL if an exception occurred.
76   
77 *******************************************************************************/
78
79 codeinfo *code_codeinfo_new(methodinfo *m)
80 {
81         codeinfo *code;
82
83         code = NEW(codeinfo);
84
85         code->m = m;
86
87         patcher_list_create(code);
88
89 #if defined (ENABLE_JITCACHE)
90         jitcache_list_create(code);
91 #endif
92
93 #if defined (ENABLE_STATISTICS)
94         if (opt_stat)
95                 size_codeinfo += sizeof(codeinfo);
96 #endif
97
98         return code;
99 }
100
101
102 /* code_find_codeinfo_for_pc ***************************************************
103
104    Return the codeinfo for the compilation unit that contains the
105    given PC.
106
107    ARGUMENTS:
108        pc...............machine code position
109
110    RETURN VALUE:
111        the codeinfo * for the given PC
112
113 *******************************************************************************/
114
115 codeinfo *code_find_codeinfo_for_pc(void *pc)
116 {
117         void *pv;
118
119         pv = methodtree_find(pc);
120
121         return code_get_codeinfo_for_pv(pv);
122 }
123
124
125 /* code_find_codeinfo_for_pc ***************************************************
126
127    Return the codeinfo for the compilation unit that contains the
128    given PC. This method does not check the return value and is used
129    by the GC.
130
131    IN:
132        pc...............machine code position
133
134    RETURN VALUE:
135        the codeinfo * for the given PC, or NULL
136
137 *******************************************************************************/
138
139 codeinfo *code_find_codeinfo_for_pc_nocheck(void *pc)
140 {
141         void *pv;
142
143         pv = methodtree_find_nocheck(pc);
144
145         if (pv == NULL)
146                 return NULL;
147
148         return code_get_codeinfo_for_pv(pv);
149 }
150
151
152 /* code_get_methodinfo_for_pv **************************************************
153
154    Return the methodinfo for the given PV.
155
156    IN:
157        pv...............PV
158
159    RETURN VALUE:
160        the methodinfo *
161
162 *******************************************************************************/
163
164 methodinfo *code_get_methodinfo_for_pv(void *pv)
165 {
166         codeinfo *code;
167
168         code = code_get_codeinfo_for_pv(pv);
169
170         /* This is the case for asm_vm_call_method. */
171
172         if (code == NULL)
173                 return NULL;
174
175         return code->m;
176 }
177
178
179 /* code_get_sync_slot_count ****************************************************
180
181    Return the number of stack slots used for storing the synchronized object
182    (and the return value around lock_monitor_exit calls) by the given code.
183    
184    IN:
185        code.............the codeinfo of the code in question
186                             (must be != NULL)
187
188    RETURN VALUE:
189        the number of stack slots used for synchronization
190   
191 *******************************************************************************/
192
193 #if defined(ENABLE_REPLACEMENT)
194 int code_get_sync_slot_count(codeinfo *code)
195 {
196 #ifdef ENABLE_THREADS
197         int count;
198         
199         assert(code);
200
201         if (!checksync)
202                 return 0;
203
204         if (!code_is_synchronized(code))
205                 return 0;
206
207         count = 1;
208
209 #ifdef HAS_4BYTE_STACKSLOT
210         /* long and double need 2 4-byte slots */
211         if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
212                 count++;
213 #endif
214
215 #if defined(__POWERPC__)
216         /* powerpc needs an extra slot */
217         count++;
218 #endif
219
220         return count;
221
222 #else /* !ENABLE_THREADS */
223         
224         return 0;
225
226 #endif /* ENABLE_THREADS */
227 }
228 #endif /* defined(ENABLE_REPLACEMENT) */
229
230
231 /* code_codeinfo_free **********************************************************
232
233    Free the memory used by a codeinfo.
234    
235    IN:
236        code.............the codeinfo to free
237
238 *******************************************************************************/
239
240 void code_codeinfo_free(codeinfo *code)
241 {
242         if (code == NULL)
243                 return;
244
245         if (code->mcode != NULL)
246                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
247
248         patcher_list_free(code);
249
250 #if defined(ENABLE_JITCACHE)
251         jitcache_list_free(code);
252 #endif
253
254 #if defined(ENABLE_REPLACEMENT)
255         replace_free_replacement_points(code);
256 #endif
257
258         FREE(code, codeinfo);
259
260 #if defined(ENABLE_STATISTICS)
261         if (opt_stat)
262                 size_codeinfo -= sizeof(codeinfo);
263 #endif
264 }
265
266
267 /* code_free_code_of_method ****************************************************
268
269    Free all codeinfos of the given method
270    
271    IN:
272        m................the method of which the codeinfos are to be freed
273
274 *******************************************************************************/
275
276 void code_free_code_of_method(methodinfo *m)
277 {
278         codeinfo *nextcode;
279         codeinfo *code;
280
281         if (!m)
282                 return;
283         
284         nextcode = m->code;
285         while (nextcode) {
286                 code = nextcode;
287                 nextcode = code->prev;
288                 code_codeinfo_free(code);
289         }
290
291         m->code = NULL;
292 }
293
294 /*
295  * These are local overrides for various environment variables in Emacs.
296  * Please do not remove this and leave it at the end of the file, where
297  * Emacs will automagically detect them.
298  * ---------------------------------------------------------------------
299  * Local variables:
300  * mode: c
301  * indent-tabs-mode: t
302  * c-basic-offset: 4
303  * tab-width: 4
304  * End:
305  * vim:noexpandtab:sw=4:ts=4:
306  */