Merged new changes from default (manually: src/vm/jit/i386/codegen.c).
[cacao.git] / src / vm / jit / code.cpp
1 /* src/vm/jit/code.cpp - 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/options.h"
36 #include "vm/vm.hpp"
37
38 #include "vm/jit/code.hpp"
39 #include "vm/jit/codegen-common.hpp"
40 #include "vm/jit/jitcache.hpp"
41 #include "vm/jit/patcher-common.hpp"
42 #include "vm/jit/methodtree.h"
43
44
45 /* code_init *******************************************************************
46
47    Initialize the code-subsystem.
48
49 *******************************************************************************/
50
51 void code_init(void)
52 {
53         /* Check if offset of codeinfo.m == 0 (see comment in code.h). */
54
55         if (OFFSET(codeinfo, m) != 0)
56                 vm_abort("code_init: offset of codeinfo.m != 0: %d != 0", OFFSET(codeinfo, m));
57 }
58
59
60 /* code_codeinfo_new ***********************************************************
61
62    Create a new codeinfo for the given method.
63    
64    IN:
65        m................method to create a new codeinfo for
66
67    The following fields are set in codeinfo:
68        m
69        patchers
70            cachedrefs
71
72    RETURN VALUE:
73        a new, initialized codeinfo, or
74            NULL if an exception occurred.
75   
76 *******************************************************************************/
77
78 codeinfo *code_codeinfo_new(methodinfo *m)
79 {
80         codeinfo *code;
81
82         code = NEW(codeinfo);
83
84         code->m = m;
85
86         patcher_list_create(code);
87
88 #if defined (ENABLE_JITCACHE)
89         jitcache_list_create(code);
90 #endif
91
92 #if defined (ENABLE_STATISTICS)
93         if (opt_stat)
94                 size_codeinfo += sizeof(codeinfo);
95 #endif
96
97         return code;
98 }
99
100
101 /* code_find_codeinfo_for_pc ***************************************************
102
103    Return the codeinfo for the compilation unit that contains the
104    given PC.
105
106    ARGUMENTS:
107        pc...............machine code position
108
109    RETURN VALUE:
110        the codeinfo * for the given PC
111
112 *******************************************************************************/
113
114 codeinfo *code_find_codeinfo_for_pc(void *pc)
115 {
116         void *pv;
117
118         pv = methodtree_find(pc);
119
120         return code_get_codeinfo_for_pv(pv);
121 }
122
123
124 /* code_find_codeinfo_for_pc ***************************************************
125
126    Return the codeinfo for the compilation unit that contains the
127    given PC. This method does not check the return value and is used
128    by the GC.
129
130    IN:
131        pc...............machine code position
132
133    RETURN VALUE:
134        the codeinfo * for the given PC, or NULL
135
136 *******************************************************************************/
137
138 codeinfo *code_find_codeinfo_for_pc_nocheck(void *pc)
139 {
140         void *pv;
141
142         pv = methodtree_find_nocheck(pc);
143
144         if (pv == NULL)
145                 return NULL;
146
147         return code_get_codeinfo_for_pv(pv);
148 }
149
150
151 /* code_get_methodinfo_for_pv **************************************************
152
153    Return the methodinfo for the given PV.
154
155    IN:
156        pv...............PV
157
158    RETURN VALUE:
159        the methodinfo *
160
161 *******************************************************************************/
162
163 methodinfo *code_get_methodinfo_for_pv(void *pv)
164 {
165         codeinfo *code;
166
167         code = code_get_codeinfo_for_pv(pv);
168
169         /* This is the case for asm_vm_call_method. */
170
171         if (code == NULL)
172                 return NULL;
173
174         return code->m;
175 }
176
177
178 /* code_get_sync_slot_count ****************************************************
179
180    Return the number of stack slots used for storing the synchronized object
181    (and the return value around lock_monitor_exit calls) by the given code.
182    
183    IN:
184        code.............the codeinfo of the code in question
185                             (must be != NULL)
186
187    RETURN VALUE:
188        the number of stack slots used for synchronization
189   
190 *******************************************************************************/
191
192 #if defined(ENABLE_REPLACEMENT)
193 int code_get_sync_slot_count(codeinfo *code)
194 {
195 #ifdef ENABLE_THREADS
196         int count;
197         
198         assert(code);
199
200         if (!checksync)
201                 return 0;
202
203         if (!code_is_synchronized(code))
204                 return 0;
205
206         count = 1;
207
208 #if defined(__POWERPC__)
209         /* powerpc needs an extra slot */
210         count++;
211 #endif
212
213         return count;
214
215 #else /* !ENABLE_THREADS */
216         
217         return 0;
218
219 #endif /* ENABLE_THREADS */
220 }
221 #endif /* defined(ENABLE_REPLACEMENT) */
222
223
224 /* code_codeinfo_free **********************************************************
225
226    Free the memory used by a codeinfo.
227    
228    IN:
229        code.............the codeinfo to free
230
231 *******************************************************************************/
232
233 void code_codeinfo_free(codeinfo *code)
234 {
235         if (code == NULL)
236                 return;
237
238         if (code->mcode != NULL)
239                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
240
241         patcher_list_free(code);
242
243 #if defined(ENABLE_JITCACHE)
244         jitcache_list_free(code);
245 #endif
246
247 #if defined(ENABLE_REPLACEMENT)
248         replace_free_replacement_points(code);
249 #endif
250
251         FREE(code, codeinfo);
252
253 #if defined(ENABLE_STATISTICS)
254         if (opt_stat)
255                 size_codeinfo -= sizeof(codeinfo);
256 #endif
257 }
258
259
260 /* code_free_code_of_method ****************************************************
261
262    Free all codeinfos of the given method
263    
264    IN:
265        m................the method of which the codeinfos are to be freed
266
267 *******************************************************************************/
268
269 void code_free_code_of_method(methodinfo *m)
270 {
271         codeinfo *nextcode;
272         codeinfo *code;
273
274         if (!m)
275                 return;
276         
277         nextcode = m->code;
278         while (nextcode) {
279                 code = nextcode;
280                 nextcode = code->prev;
281                 code_codeinfo_free(code);
282         }
283
284         m->code = NULL;
285 }
286
287 /*
288  * These are local overrides for various environment variables in Emacs.
289  * Please do not remove this and leave it at the end of the file, where
290  * Emacs will automagically detect them.
291  * ---------------------------------------------------------------------
292  * Local variables:
293  * mode: c++
294  * indent-tabs-mode: t
295  * c-basic-offset: 4
296  * tab-width: 4
297  * End:
298  * vim:noexpandtab:sw=4:ts=4:
299  */