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