* Removed all Id tags.
[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 *(codeinfo **)(pv + CodeinfoPointer);
125 }
126
127
128 /* code_get_methodinfo_for_pv **************************************************
129
130    Return the methodinfo for the given PV.
131
132    IN:
133        pv...............PV
134
135    RETURN VALUE:
136        the methodinfo *
137
138 *******************************************************************************/
139
140 methodinfo *code_get_methodinfo_for_pv(u1 *pv)
141 {
142         codeinfo *code;
143
144         code = *((codeinfo **) (pv + CodeinfoPointer));
145
146         return code->m;
147 }
148
149
150 /* code_get_sync_slot_count ****************************************************
151
152    Return the number of stack slots used for storing the synchronized object
153    (and the return value around lock_monitor_exit calls) by the given code.
154    
155    IN:
156        code.............the codeinfo of the code in question
157                             (must be != NULL)
158
159    RETURN VALUE:
160        the number of stack slots used for synchronization
161   
162 *******************************************************************************/
163
164 #if defined(ENABLE_REPLACEMENT)
165 int code_get_sync_slot_count(codeinfo *code)
166 {
167 #ifdef ENABLE_THREADS
168         int count;
169         
170         assert(code);
171
172         if (!checksync)
173                 return 0;
174
175         if (!(code->m->flags & ACC_SYNCHRONIZED))
176                 return 0;
177
178         count = 1;
179
180 #ifdef HAS_4BYTE_STACKSLOT
181         /* long and double need 2 4-byte slots */
182         if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
183                 count++;
184 #endif
185
186 #if defined(__POWERPC__)
187         /* powerpc needs an extra slot */
188         count++;
189 #endif
190
191         return count;
192
193 #else /* !ENABLE_THREADS */
194         
195         return 0;
196
197 #endif /* ENABLE_THREADS */
198 }
199 #endif /* defined(ENABLE_REPLACEMENT) */
200
201
202 /* code_codeinfo_free **********************************************************
203
204    Free the memory used by a codeinfo.
205    
206    IN:
207        code.............the codeinfo to free
208
209 *******************************************************************************/
210
211 void code_codeinfo_free(codeinfo *code)
212 {
213         if (code == NULL)
214                 return;
215
216         if (code->mcode != NULL)
217                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
218
219         patcher_list_free(code);
220
221 #if defined(ENABLE_REPLACEMENT)
222         replace_free_replacement_points(code);
223 #endif
224
225         FREE(code, codeinfo);
226
227 #if defined(ENABLE_STATISTICS)
228         if (opt_stat)
229                 size_codeinfo -= sizeof(codeinfo);
230 #endif
231 }
232
233
234 /* code_free_code_of_method ****************************************************
235
236    Free all codeinfos of the given method
237    
238    IN:
239        m................the method of which the codeinfos are to be freed
240
241 *******************************************************************************/
242
243 void code_free_code_of_method(methodinfo *m)
244 {
245         codeinfo *nextcode;
246         codeinfo *code;
247
248         if (!m)
249                 return;
250         
251         nextcode = m->code;
252         while (nextcode) {
253                 code = nextcode;
254                 nextcode = code->prev;
255                 code_codeinfo_free(code);
256         }
257
258         m->code = NULL;
259 }
260
261 /*
262  * These are local overrides for various environment variables in Emacs.
263  * Please do not remove this and leave it at the end of the file, where
264  * Emacs will automagically detect them.
265  * ---------------------------------------------------------------------
266  * Local variables:
267  * mode: c
268  * indent-tabs-mode: t
269  * c-basic-offset: 4
270  * tab-width: 4
271  * End:
272  * vim:noexpandtab:sw=4:ts=4:
273  */