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