CACAO
patcher.c
Go to the documentation of this file.
1 /* src/vm/jit/intrp/patcher.c - Interpreter code patching functions
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 
26 #include "config.h"
27 #include "vm/types.hpp"
28 
29 #include "mm/memory.hpp"
30 
31 #include "native/native.hpp"
32 
33 #include "vm/jit/builtin.hpp"
34 #include "vm/class.hpp"
35 #include "vm/field.hpp"
36 #include "vm/initialize.hpp"
37 #include "vm/options.hpp"
38 #include "vm/references.hpp"
39 #include "vm/resolve.hpp"
40 
41 #include "vm/jit/asmpart.hpp"
42 #include "vm/jit/patcher.hpp"
43 
44 
45 /* patcher_get_putstatic *******************************************************
46 
47  Machine code:
48 
49 *******************************************************************************/
50 
52 {
53  ptrint *ip;
54  unresolved_field *uf;
55  fieldinfo *fi;
56 
57  ip = (ptrint *) sp;
58  uf = (unresolved_field *) ip[2];
59 
60  /* get the fieldinfo */
61 
62  if (!(fi = resolve_field_eager(uf)))
63  return false;
64 
65  /* check if the field's class is initialized */
66 
67  if (!(fi->clazz->state & CLASS_INITIALIZED))
68  if (!initialize_class(fi->clazz))
69  return false;
70 
71  /* patch the field's address */
72 
73  ip[1] = (ptrint) &(fi->value);
74 
75  return true;
76 }
77 
78 
79 /* patcher_get_putstatic_clinit ************************************************
80 
81  This patcher is used if we already have the resolved fieldinfo but the
82  class of the field has not been initialized, yet.
83 
84  Machine code:
85 
86 *******************************************************************************/
87 
89 {
90  ptrint *ip;
91  fieldinfo *fi;
92 
93  /* get the fieldinfo */
94 
95  ip = (ptrint *) sp;
96  fi = (fieldinfo *) ip[2];
97 
98  /* check if the field's class is initialized */
99 
100  if (!(fi->clazz->state & CLASS_INITIALIZED))
101  if (!initialize_class(fi->clazz))
102  return false;
103 
104  /* patch the field's address */
105 
106  ip[1] = (ptrint) &(fi->value);
107 
108  return true;
109 }
110 
111 
112 /* patcher_get_putfield ********************************************************
113 
114  Machine code:
115 
116 *******************************************************************************/
117 
119 {
120  ptrint *ip;
121  unresolved_field *uf;
122  fieldinfo *fi;
123 
124  ip = (ptrint *) sp;
125  uf = (unresolved_field *) ip[2];
126 
127  /* get the fieldinfo */
128 
129  if (!(fi = resolve_field_eager(uf)))
130  return false;
131 
132  /* patch the field's offset */
133 
134  ip[1] = fi->offset;
135 
136  return true;
137 }
138 
139 
140 /* patcher_aconst **************************************************************
141 
142  Machine code:
143 
144 *******************************************************************************/
145 
147 {
148  ptrint *ip;
149  constant_classref *cr;
150  classinfo *c;
151 
152  ip = (ptrint *) sp;
153  cr = (constant_classref *) ip[2];
154 
155  /* get the classinfo */
156 
157  if (!(c = resolve_classref_eager(cr)))
158  return false;
159 
160  /* patch the classinfo pointer */
161 
162  ip[1] = (ptrint) c;
163 
164  return true;
165 }
166 
167 
168 /* patcher_builtin_multianewarray **********************************************
169 
170  Machine code:
171 
172 *******************************************************************************/
173 
175 {
176  ptrint *ip;
177  constant_classref *cr;
178  classinfo *c;
179 
180  ip = (ptrint *) sp;
181  cr = (constant_classref *) ip[3];
182 
183  /* get the classinfo */
184 
185  if (!(c = resolve_classref_eager(cr)))
186  return false;
187 
188  /* patch the classinfo pointer */
189 
190  ip[1] = (ptrint) c;
191 
192  return true;
193 }
194 
195 
196 /* patcher_builtin_arraycheckcast **********************************************
197 
198  Machine code:
199 
200 *******************************************************************************/
201 
203 {
204  ptrint *ip;
205  constant_classref *cr;
206  classinfo *c;
207 
208  ip = (ptrint *) sp;
209  cr = (constant_classref *) ip[2];
210 
211  /* get the classinfo */
212 
213  if (!(c = resolve_classref_eager(cr)))
214  return false;
215 
216  /* patch the classinfo pointer */
217 
218  ip[1] = (ptrint) c;
219 
220  return true;
221 }
222 
223 
224 /* patcher_invokestatic_special ************************************************
225 
226  Machine code:
227 
228 ******************************************************************************/
229 
231 {
232  ptrint *ip;
233  unresolved_method *um;
234  methodinfo *m;
235 
236  ip = (ptrint *) sp;
237  um = (unresolved_method *) ip[3];
238 
239  /* get the fieldinfo */
240 
241  if (!(m = resolve_method_eager(um)))
242  return false;
243 
244  /* patch methodinfo and stubroutine */
245 
246  ip[3] = (ptrint) m;
247  ip[1] = (ptrint) m->stubroutine;
248 
249  return true;
250 }
251 
252 
253 /* patcher_invokevirtual *******************************************************
254 
255  Machine code:
256 
257 *******************************************************************************/
258 
260 {
261  ptrint *ip;
262  unresolved_method *um;
263  methodinfo *m;
264 
265  ip = (ptrint *) sp;
266  um = (unresolved_method *) ip[3];
267 
268  /* get the fieldinfo */
269 
270  if (!(m = resolve_method_eager(um)))
271  return false;
272 
273  /* patch methodinfo and vftbl index */
274 
275  ip[3] = (ptrint) m;
276  ip[1] = (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex);
277 
278  return true;
279 }
280 
281 
282 /* patcher_invokeinterface *****************************************************
283 
284  Machine code:
285 
286 *******************************************************************************/
287 
289 {
290  ptrint *ip;
291  unresolved_method *um;
292  methodinfo *m;
293 
294  ip = (ptrint *) sp;
295  um = (unresolved_method *) ip[4];
296 
297  /* get the methodinfo */
298 
299  if (!(m = resolve_method_eager(um)))
300  return false;
301 
302  /* patch interfacetable index */
303 
304  ip[1] = (OFFSET(vftbl_t, interfacetable[0]) -
305  sizeof(methodptr*) * m->clazz->index);
306 
307  /* patch methodinfo and method offset */
308 
309  ip[4] = (ptrint) m;
310  ip[2] = (sizeof(methodptr) * (m - m->clazz->methods));
311 
312  return true;
313 }
314 
315 
316 /* patcher_checkcast_instanceof ************************************************
317 
318  Machine code:
319 
320 *******************************************************************************/
321 
323 {
324  ptrint *ip;
325  constant_classref *cr;
326  classinfo *c;
327 
328  ip = (ptrint *) sp;
329  cr = (constant_classref *) ip[2];
330 
331  /* get the classinfo */
332 
333  if (!(c = resolve_classref_eager(cr)))
334  return false;
335 
336  /* patch super class pointer */
337 
338  ip[1] = (ptrint) c;
339 
340  return true;
341 }
342 
343 
344 /* patcher_resolve_native ******************************************************
345 
346  XXX
347 
348 *******************************************************************************/
349 
351 {
352  ptrint *ip;
353  methodinfo *m;
354  functionptr f;
355 
356  ip = (ptrint *) sp;
357  m = (methodinfo *) ip[1];
358 
359  /* resolve native function */
360 
361  if (!(f = native_resolve_function(m)))
362  return false;
363 
364  /* patch native function pointer */
365 
366  ip[2] = (ptrint) f;
367 
368  return true;
369 }
370 
371 
372 /*
373  * These are local overrides for various environment variables in Emacs.
374  * Please do not remove this and leave it at the end of the file, where
375  * Emacs will automagically detect them.
376  * ---------------------------------------------------------------------
377  * Local variables:
378  * mode: c
379  * indent-tabs-mode: t
380  * c-basic-offset: 4
381  * tab-width: 4
382  * End:
383  * vim:noexpandtab:sw=4:ts=4:
384  */
bool intrp_patcher_aconst(u1 *sp)
Definition: patcher.c:146
bool intrp_patcher_get_putfield(u1 *sp)
Definition: patcher.c:118
methodinfo * methods
Definition: class.hpp:113
s4 state
Definition: class.hpp:115
bool intrp_patcher_builtin_multianewarray(u1 *sp)
Definition: patcher.c:174
bool intrp_patcher_resolve_native(u1 *sp)
Definition: patcher.c:350
uint8_t u1
Definition: types.hpp:40
u1 * methodptr
Definition: global.hpp:40
void(* functionptr)(void)
Definition: global.hpp:39
bool intrp_patcher_checkcast_instanceof(u1 *sp)
Definition: patcher.c:322
u1 * stubroutine
Definition: method.hpp:102
s4 vftblindex
Definition: method.hpp:81
bool intrp_patcher_get_putstatic_clinit(u1 *sp)
Definition: patcher.c:88
int32_t offset
Definition: field.hpp:66
classinfo * clazz
Definition: method.hpp:80
imm_union * value
Definition: field.hpp:67
classinfo * clazz
Definition: field.hpp:55
s4 index
Definition: class.hpp:116
bool initialize_class(classinfo *c)
Definition: initialize.cpp:110
fieldinfo * resolve_field_eager(unresolved_field *ref)
Definition: resolve.cpp:1497
#define sp
Definition: md-asm.hpp:81
methodinfo * resolve_method_eager(unresolved_method *ref)
Definition: resolve.cpp:2236
bool intrp_patcher_invokestatic_special(u1 *sp)
Definition: patcher.c:230
bool intrp_patcher_invokevirtual(u1 *sp)
Definition: patcher.c:259
classinfo * resolve_classref_eager(constant_classref *ref)
Definition: resolve.cpp:961
bool intrp_patcher_builtin_arraycheckcast(u1 *sp)
Definition: patcher.c:202
bool intrp_patcher_get_putstatic(u1 *sp)
Definition: patcher.c:51
uintptr_t ptrint
Definition: types.hpp:54
bool intrp_patcher_invokeinterface(u1 *sp)
Definition: patcher.c:288
#define OFFSET(s, el)
Definition: memory.hpp:90
#define ip
Definition: md-asm.hpp:59