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.hpp"
38 #include "vm/jit/builtin.hpp"
39 #include "vm/class.hpp"
40 #include "vm/field.hpp"
41 #include "vm/initialize.hpp"
42 #include "vm/options.h"
43 #include "vm/references.h"
44 #include "vm/resolve.hpp"
46 #include "vm/jit/asmpart.h"
47 #include "vm/jit/patcher-common.hpp"
48 #include "vm/jit/methodheader.h"
51 /* patcher_patch_code **********************************************************
53 Just patches back the original machine code.
55 *******************************************************************************/
57 void patcher_patch_code(patchref_t* pr)
59 // Patch back original code.
60 *((uint32_t*) pr->mpc) = pr->mcode;
62 // Synchronize instruction cache.
63 md_icacheflush(NULL, 0);
67 /* patcher_resolve_classref_to_classinfo ***************************************
71 <patched call postition>
72 a61bff80 ldq a0,-128(pv)
76 <patched call position>
77 a63bff80 ldq a1,-128(pv)
79 a77bff78 ldq pv,-136(pv)
84 <patched call position>
85 a63bfe60 ldq a1,-416(pv)
86 a77bfe58 ldq pv,-424(pv)
89 *******************************************************************************/
91 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
93 constant_classref *cr;
97 /* get stuff from the stack */
99 cr = (constant_classref *) pr->ref;
100 datap = (u1 *) pr->datap;
102 /* get the classinfo */
104 if (!(c = resolve_classref_eager(cr)))
107 /* patch the classinfo pointer */
109 *((ptrint *) datap) = (ptrint) c;
111 // Patch back the original code.
112 patcher_patch_code(pr);
118 /* patcher_resolve_classref_to_vftbl *******************************************
123 <patched call position>
124 a7940000 ldq at,0(a4)
125 a7bbff28 ldq gp,-216(pv)
127 *******************************************************************************/
129 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
131 constant_classref *cr;
135 /* get stuff from the stack */
137 cr = (constant_classref *) pr->ref;
138 datap = (u1 *) pr->datap;
140 /* get the fieldinfo */
142 if (!(c = resolve_classref_eager(cr)))
145 /* patch super class' vftbl */
147 *((ptrint *) datap) = (ptrint) c->vftbl;
149 // Patch back the original code.
150 patcher_patch_code(pr);
156 /* patcher_resolve_classref_to_flags *******************************************
158 CHECKCAST/INSTANCEOF:
160 <patched call position>
162 *******************************************************************************/
164 bool patcher_resolve_classref_to_flags(patchref_t *pr)
166 constant_classref *cr;
170 /* get stuff from the stack */
172 cr = (constant_classref *) pr->ref;
173 datap = (u1 *) pr->datap;
175 /* get the fieldinfo */
177 if (!(c = resolve_classref_eager(cr)))
180 /* patch class flags */
182 *((s4 *) datap) = (s4) c->flags;
184 // Patch back the original code.
185 patcher_patch_code(pr);
191 /* patcher_get_putstatic *******************************************************
195 <patched call position>
196 a73bff98 ldq t11,-104(pv)
197 a2590000 ldl a2,0(t11)
199 *******************************************************************************/
201 bool patcher_get_putstatic(patchref_t *pr)
203 unresolved_field *uf;
207 /* get stuff from the stack */
209 uf = (unresolved_field *) pr->ref;
210 datap = (u1 *) pr->datap;
212 /* get the fieldinfo */
214 if (!(fi = resolve_field_eager(uf)))
217 /* check if the field's class is initialized */
219 if (!(fi->clazz->state & CLASS_INITIALIZED))
220 if (!initialize_class(fi->clazz))
223 /* patch the field value's address */
225 *((intptr_t *) datap) = (intptr_t) fi->value;
227 // Patch back the original code.
228 patcher_patch_code(pr);
234 /* patcher_get_putfield ********************************************************
238 <patched call position>
239 a2af0020 ldl a5,32(s6)
241 *******************************************************************************/
243 bool patcher_get_putfield(patchref_t *pr)
245 unresolved_field *uf;
248 uf = (unresolved_field *) pr->ref;
250 /* get the fieldinfo */
252 if (!(fi = resolve_field_eager(uf)))
255 /* patch the field's offset into the instruction */
257 pr->mcode |= (s2) (fi->offset & 0x0000ffff);
259 // Patch back the original code.
260 patcher_patch_code(pr);
266 /* patcher_invokestatic_special ************************************************
270 <patched call position>
271 a77bffa8 ldq pv,-88(pv)
274 ******************************************************************************/
276 bool patcher_invokestatic_special(patchref_t *pr)
278 unresolved_method *um;
282 /* get stuff from the stack */
284 um = (unresolved_method *) pr->ref;
285 datap = (u1 *) pr->datap;
287 /* get the fieldinfo */
289 if (!(m = resolve_method_eager(um)))
292 /* patch stubroutine */
294 *((ptrint *) datap) = (ptrint) m->stubroutine;
296 // Patch back the original code.
297 patcher_patch_code(pr);
303 /* patcher_invokevirtual *******************************************************
307 <patched call position>
308 a7900000 ldq at,0(a0)
309 a77c0100 ldq pv,256(at)
312 *******************************************************************************/
314 bool patcher_invokevirtual(patchref_t *pr)
317 unresolved_method *um;
320 /* get stuff from the stack */
323 um = (unresolved_method *) pr->ref;
325 /* get the fieldinfo */
327 if (!(m = resolve_method_eager(um)))
330 /* patch vftbl index */
332 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
333 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
335 md_icacheflush(NULL, 0);
337 // Patch back the original code.
338 patcher_patch_code(pr);
344 /* patcher_invokeinterface *****************************************************
348 <patched call position>
349 a7900000 ldq at,0(a0)
350 a79cffa0 ldq at,-96(at)
351 a77c0018 ldq pv,24(at)
354 *******************************************************************************/
356 bool patcher_invokeinterface(patchref_t *pr)
359 unresolved_method *um;
362 /* get stuff from the stack */
365 um = (unresolved_method *) pr->ref;
367 /* get the fieldinfo */
369 if (!(m = resolve_method_eager(um)))
372 /* patch interfacetable index */
374 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
375 sizeof(methodptr*) * m->clazz->index) & 0x0000ffff);
377 /* patch method offset */
379 *((s4 *) (ra + 4 + 4)) |=
380 (s4) ((sizeof(methodptr) * (m - m->clazz->methods)) & 0x0000ffff);
382 md_icacheflush(NULL, 0);
384 // Patch back the original code.
385 patcher_patch_code(pr);
391 /* patcher_checkcast_interface *************************************************
395 <patched call position>
396 a78e0000 ldq at,0(s5)
397 a3bc001c ldl gp,28(at)
398 23bdfffd lda gp,-3(gp)
399 efa0002e ble gp,0x00000200002bf6b0
400 a7bcffe8 ldq gp,-24(at)
402 *******************************************************************************/
404 bool patcher_checkcast_interface(patchref_t *pr)
407 constant_classref *cr;
410 /* get stuff from the stack */
413 cr = (constant_classref *) pr->ref;
415 /* get the fieldinfo */
417 if (!(c = resolve_classref_eager(cr)))
420 /* patch super class index */
422 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
424 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
425 c->index * sizeof(methodptr*)) & 0x0000ffff);
427 md_icacheflush(NULL, 0);
429 // Patch back the original code.
430 patcher_patch_code(pr);
436 /* patcher_instanceof_interface ************************************************
440 <patched call position>
441 a78e0000 ldq at,0(s5)
442 a3bc001c ldl gp,28(at)
443 23bdfffd lda gp,-3(gp)
444 efa0002e ble gp,0x00000200002bf6b0
445 a7bcffe8 ldq gp,-24(at)
447 *******************************************************************************/
449 bool patcher_instanceof_interface(patchref_t *pr)
452 constant_classref *cr;
455 /* get stuff from the stack */
458 cr = (constant_classref *) pr->ref;
460 /* get the fieldinfo */
462 if (!(c = resolve_classref_eager(cr)))
465 /* patch super class index */
467 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
469 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
470 c->index * sizeof(methodptr*)) & 0x0000ffff);
472 md_icacheflush(NULL, 0);
474 // Patch back the original code.
475 patcher_patch_code(pr);
482 * These are local overrides for various environment variables in Emacs.
483 * Please do not remove this and leave it at the end of the file, where
484 * Emacs will automagically detect them.
485 * ---------------------------------------------------------------------
488 * indent-tabs-mode: t
492 * vim:noexpandtab:sw=4:ts=4: