1 /* src/vm/jit/alpha/patcher.c - Alpha code patching functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
32 #include "vm/jit/alpha/md.h"
34 #include "mm/memory.h"
36 #include "native/native.h"
38 #include "vm/builtin.h"
39 #include "vm/exceptions.h"
40 #include "vm/initialize.h"
42 #include "vm/jit/asmpart.h"
43 #include "vm/jit/patcher-common.h"
44 #include "vm/jit/methodheader.h"
45 #include "vm/jit/stacktrace.h"
47 #include "vmcore/class.h"
48 #include "vmcore/field.h"
49 #include "vmcore/options.h"
50 #include "vmcore/references.h"
51 #include "vm/resolve.h"
54 #define PATCH_BACK_ORIGINAL_MCODE \
55 *((u4 *) pr->mpc) = (u4) pr->mcode; \
56 md_icacheflush(NULL, 0);
59 /* patcher_patch_code **********************************************************
61 Just patches back the original machine code.
63 *******************************************************************************/
65 void patcher_patch_code(patchref_t *pr)
67 PATCH_BACK_ORIGINAL_MCODE;
71 /* patcher_resolve_classref_to_classinfo ***************************************
75 <patched call postition>
76 a61bff80 ldq a0,-128(pv)
80 <patched call position>
81 a63bff80 ldq a1,-128(pv)
83 a77bff78 ldq pv,-136(pv)
88 <patched call position>
89 a63bfe60 ldq a1,-416(pv)
90 a77bfe58 ldq pv,-424(pv)
93 *******************************************************************************/
95 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
97 constant_classref *cr;
101 /* get stuff from the stack */
103 cr = (constant_classref *) pr->ref;
104 datap = (u1 *) pr->datap;
106 /* get the classinfo */
108 if (!(c = resolve_classref_eager(cr)))
111 PATCH_BACK_ORIGINAL_MCODE;
113 /* patch the classinfo pointer */
115 *((ptrint *) datap) = (ptrint) c;
121 /* patcher_resolve_classref_to_vftbl *******************************************
126 <patched call position>
127 a7940000 ldq at,0(a4)
128 a7bbff28 ldq gp,-216(pv)
130 *******************************************************************************/
132 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
134 constant_classref *cr;
138 /* get stuff from the stack */
140 cr = (constant_classref *) pr->ref;
141 datap = (u1 *) pr->datap;
143 /* get the fieldinfo */
145 if (!(c = resolve_classref_eager(cr)))
148 PATCH_BACK_ORIGINAL_MCODE;
150 /* patch super class' vftbl */
152 *((ptrint *) datap) = (ptrint) c->vftbl;
158 /* patcher_resolve_classref_to_flags *******************************************
160 CHECKCAST/INSTANCEOF:
162 <patched call position>
164 *******************************************************************************/
166 bool patcher_resolve_classref_to_flags(patchref_t *pr)
168 constant_classref *cr;
172 /* get stuff from the stack */
174 cr = (constant_classref *) pr->ref;
175 datap = (u1 *) pr->datap;
177 /* get the fieldinfo */
179 if (!(c = resolve_classref_eager(cr)))
182 PATCH_BACK_ORIGINAL_MCODE;
184 /* patch class flags */
186 *((s4 *) datap) = (s4) c->flags;
192 /* patcher_get_putstatic *******************************************************
196 <patched call position>
197 a73bff98 ldq t11,-104(pv)
198 a2590000 ldl a2,0(t11)
200 *******************************************************************************/
202 bool patcher_get_putstatic(patchref_t *pr)
204 unresolved_field *uf;
208 /* get stuff from the stack */
210 uf = (unresolved_field *) pr->ref;
211 datap = (u1 *) pr->datap;
213 /* get the fieldinfo */
215 if (!(fi = resolve_field_eager(uf)))
218 /* check if the field's class is initialized */
220 if (!(fi->clazz->state & CLASS_INITIALIZED))
221 if (!initialize_class(fi->clazz))
224 PATCH_BACK_ORIGINAL_MCODE;
226 /* patch the field value's address */
228 *((intptr_t *) datap) = (intptr_t) fi->value;
234 /* patcher_get_putfield ********************************************************
238 <patched call position>
239 a2af0020 ldl a5,32(s6)
241 *******************************************************************************/
243 bool patcher_get_putfield(patchref_t *pr)
246 unresolved_field *uf;
250 uf = (unresolved_field *) pr->ref;
252 /* get the fieldinfo */
254 if (!(fi = resolve_field_eager(uf)))
257 PATCH_BACK_ORIGINAL_MCODE;
259 /* if we show disassembly, we have to skip the nop */
264 /* patch the field's offset into the instruction */
266 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
268 md_icacheflush(NULL, 0);
274 /* patcher_invokestatic_special ************************************************
278 <patched call position>
279 a77bffa8 ldq pv,-88(pv)
282 ******************************************************************************/
284 bool patcher_invokestatic_special(patchref_t *pr)
286 unresolved_method *um;
290 /* get stuff from the stack */
292 um = (unresolved_method *) pr->ref;
293 datap = (u1 *) pr->datap;
295 /* get the fieldinfo */
297 if (!(m = resolve_method_eager(um)))
300 PATCH_BACK_ORIGINAL_MCODE;
302 /* patch stubroutine */
304 *((ptrint *) datap) = (ptrint) m->stubroutine;
310 /* patcher_invokevirtual *******************************************************
314 <patched call position>
315 a7900000 ldq at,0(a0)
316 a77c0100 ldq pv,256(at)
319 *******************************************************************************/
321 bool patcher_invokevirtual(patchref_t *pr)
324 unresolved_method *um;
327 /* get stuff from the stack */
330 um = (unresolved_method *) pr->ref;
332 /* get the fieldinfo */
334 if (!(m = resolve_method_eager(um)))
337 PATCH_BACK_ORIGINAL_MCODE;
339 /* if we show disassembly, we have to skip the nop */
344 /* patch vftbl index */
346 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
347 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
349 md_icacheflush(NULL, 0);
355 /* patcher_invokeinterface *****************************************************
359 <patched call position>
360 a7900000 ldq at,0(a0)
361 a79cffa0 ldq at,-96(at)
362 a77c0018 ldq pv,24(at)
365 *******************************************************************************/
367 bool patcher_invokeinterface(patchref_t *pr)
370 unresolved_method *um;
373 /* get stuff from the stack */
376 um = (unresolved_method *) pr->ref;
378 /* get the fieldinfo */
380 if (!(m = resolve_method_eager(um)))
383 PATCH_BACK_ORIGINAL_MCODE;
385 /* if we show disassembly, we have to skip the nop */
390 /* patch interfacetable index */
392 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
393 sizeof(methodptr*) * m->clazz->index) & 0x0000ffff);
395 /* patch method offset */
397 *((s4 *) (ra + 4 + 4)) |=
398 (s4) ((sizeof(methodptr) * (m - m->clazz->methods)) & 0x0000ffff);
400 md_icacheflush(NULL, 0);
406 /* patcher_checkcast_interface *************************************************
410 <patched call position>
411 a78e0000 ldq at,0(s5)
412 a3bc001c ldl gp,28(at)
413 23bdfffd lda gp,-3(gp)
414 efa0002e ble gp,0x00000200002bf6b0
415 a7bcffe8 ldq gp,-24(at)
417 *******************************************************************************/
419 bool patcher_checkcast_interface(patchref_t *pr)
422 constant_classref *cr;
425 /* get stuff from the stack */
428 cr = (constant_classref *) pr->ref;
430 /* get the fieldinfo */
432 if (!(c = resolve_classref_eager(cr)))
435 PATCH_BACK_ORIGINAL_MCODE;
437 /* if we show disassembly, we have to skip the nop */
442 /* patch super class index */
444 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
446 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
447 c->index * sizeof(methodptr*)) & 0x0000ffff);
449 md_icacheflush(NULL, 0);
455 /* patcher_instanceof_interface ************************************************
459 <patched call position>
460 a78e0000 ldq at,0(s5)
461 a3bc001c ldl gp,28(at)
462 23bdfffd lda gp,-3(gp)
463 efa0002e ble gp,0x00000200002bf6b0
464 a7bcffe8 ldq gp,-24(at)
466 *******************************************************************************/
468 bool patcher_instanceof_interface(patchref_t *pr)
471 constant_classref *cr;
474 /* get stuff from the stack */
477 cr = (constant_classref *) pr->ref;
479 /* get the fieldinfo */
481 if (!(c = resolve_classref_eager(cr)))
484 PATCH_BACK_ORIGINAL_MCODE;
486 /* if we show disassembly, we have to skip the nop */
491 /* patch super class index */
493 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
495 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
496 c->index * sizeof(methodptr*)) & 0x0000ffff);
498 md_icacheflush(NULL, 0);
505 * These are local overrides for various environment variables in Emacs.
506 * Please do not remove this and leave it at the end of the file, where
507 * Emacs will automagically detect them.
508 * ---------------------------------------------------------------------
511 * indent-tabs-mode: t
515 * vim:noexpandtab:sw=4:ts=4: