1 /* src/vm/jit/s390/patcher.c - s390 code patching functions
3 Copyright (C) 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
31 #include "mm/memory.h"
32 #include "native/native.h"
33 #include "vm/builtin.h"
34 #include "vm/exceptions.h"
35 #include "vm/initialize.h"
36 #include "vm/jit/patcher-common.h"
37 #include "vm/jit/s390/codegen.h"
38 #include "vm/jit/s390/md-abi.h"
39 #include "vm/resolve.h"
41 #include "vmcore/class.h"
42 #include "vmcore/field.h"
43 #include "vmcore/options.h"
44 #include "vmcore/references.h"
46 #define PATCH_BACK_ORIGINAL_MCODE \
47 *((u2 *) pr->mpc) = (u2) pr->mcode;
52 /* patcher_patch_code **********************************************************
54 Just patches back the original machine code.
56 *******************************************************************************/
58 void patcher_patch_code(patchref_t *pr)
60 PATCH_BACK_ORIGINAL_MCODE;
64 /* patcher_get_putstatic *******************************************************
68 *******************************************************************************/
70 bool patcher_get_putstatic(patchref_t *pr)
78 /* get stuff from the stack */
80 uf = (unresolved_field *) pr->ref;
81 datap = (u1 *) pr->datap;
83 /* get the fieldinfo */
85 if (!(fi = resolve_field_eager(uf)))
88 /* check if the field's class is initialized */
90 if (!(fi->clazz->state & CLASS_INITIALIZED))
91 if (!initialize_class(fi->clazz))
94 PATCH_BACK_ORIGINAL_MCODE;
96 /* patch the field value's address */
98 *((intptr_t *) datap) = (intptr_t) fi->value;
104 /* patcher_get_putfield ********************************************************
108 *******************************************************************************/
110 bool patcher_get_putfield(patchref_t *pr)
113 unresolved_field *uf;
119 /* get stuff from the stack */
122 uf = (unresolved_field *) pr->ref;
125 /* get the fieldinfo */
127 if (!(fi = resolve_field_eager(uf)))
130 PATCH_BACK_ORIGINAL_MCODE;
132 /* If NOPs are generated, skip them */
135 ra += PATCHER_NOPS_SKIP;
137 /* If there is an operand load before, skip the load size passed in disp (see ICMD_PUTFIELD) */
141 /* patch correct offset */
143 if (fi->type == TYPE_LNG) {
144 ASSERT_VALID_DISP(fi->offset + 4);
145 /* 2 RX operations, for 2 words; each already contains a 0 or 4 offset. */
146 N_RX_SET_DISP(ra, fi->offset + N_RX_GET_DISP(ra));
148 N_RX_SET_DISP(ra, fi->offset + N_RX_GET_DISP(ra));
150 ASSERT_VALID_DISP(fi->offset);
152 N_RX_SET_DISP(ra, fi->offset);
158 /* patcher_invokestatic_special ************************************************
162 *******************************************************************************/
164 bool patcher_invokestatic_special(patchref_t *pr)
166 unresolved_method *um;
172 /* get stuff from the stack */
174 um = (unresolved_method *) pr->ref;
175 datap = (u1 *) pr->datap;
177 /* get the fieldinfo */
179 if (!(m = resolve_method_eager(um)))
182 PATCH_BACK_ORIGINAL_MCODE;
184 /* patch stubroutine */
186 *((ptrint *) datap) = (ptrint) m->stubroutine;
191 /* patcher_invokevirtual *******************************************************
195 *******************************************************************************/
197 bool patcher_invokevirtual(patchref_t *pr)
200 unresolved_method *um;
206 /* get stuff from the stack */
209 um = (unresolved_method *) pr->ref;
211 /* get the fieldinfo */
213 if (!(m = resolve_method_eager(um)))
216 /* patch back original code */
218 PATCH_BACK_ORIGINAL_MCODE;
220 /* If NOPs are generated, skip them */
223 ra += PATCHER_NOPS_SKIP;
225 /* patch vftbl index */
228 off = (s4) (OFFSET(vftbl_t, table[0]) +
229 sizeof(methodptr) * m->vftblindex);
231 ASSERT_VALID_DISP(off);
233 N_RX_SET_DISP(ra + SZ_RX, off);
239 /* patcher_invokeinterface *****************************************************
243 *******************************************************************************/
245 bool patcher_invokeinterface(patchref_t *pr)
248 unresolved_method *um;
254 /* get stuff from the stack */
257 um = (unresolved_method *) pr->ref;
259 /* get the fieldinfo */
261 if (!(m = resolve_method_eager(um)))
264 /* patch back original code */
266 PATCH_BACK_ORIGINAL_MCODE;
268 /* If NOPs are generated, skip them */
271 ra += PATCHER_NOPS_SKIP;
273 /* get interfacetable index */
275 idx = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
276 sizeof(methodptr) * m->clazz->index);
278 ASSERT_VALID_IMM(idx);
280 /* get method offset */
283 (s4) (sizeof(methodptr) * (m - m->clazz->methods));
285 ASSERT_VALID_DISP(off);
289 N_RI_SET_IMM(ra + SZ_L, idx);
290 N_RX_SET_DISP(ra + SZ_L + SZ_LHI + SZ_L, off);
296 /* patcher_resolve_classref_to_flags *******************************************
298 CHECKCAST/INSTANCEOF:
300 <patched call position>
302 *******************************************************************************/
304 bool patcher_resolve_classref_to_flags(patchref_t *pr)
306 constant_classref *cr;
312 /* get stuff from the stack */
314 cr = (constant_classref *) pr->ref;
315 datap = (u1 *) pr->datap;
317 /* get the fieldinfo */
319 if (!(c = resolve_classref_eager(cr)))
322 PATCH_BACK_ORIGINAL_MCODE;
324 /* patch class flags */
326 *((s4 *) datap) = (s4) c->flags;
331 /* patcher_resolve_classref_to_classinfo ***************************************
337 *******************************************************************************/
339 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
341 constant_classref *cr;
347 /* get stuff from the stack */
349 cr = (constant_classref *) pr->ref;
350 datap = (u1 *) pr->datap;
352 /* get the classinfo */
354 if (!(c = resolve_classref_eager(cr)))
357 PATCH_BACK_ORIGINAL_MCODE;
359 /* patch the classinfo pointer */
361 *((ptrint *) datap) = (ptrint) c;
366 /* patcher_resolve_classref_to_vftbl *******************************************
371 *******************************************************************************/
373 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
375 constant_classref *cr;
381 /* get stuff from the stack */
383 cr = (constant_classref *) pr->ref;
384 datap = (u1 *) pr->datap;
386 /* get the fieldinfo */
388 if (!(c = resolve_classref_eager(cr)))
391 PATCH_BACK_ORIGINAL_MCODE;
393 /* patch super class' vftbl */
395 *((ptrint *) datap) = (ptrint) c->vftbl;
400 /* patcher_checkcast_instanceof_interface **************************************
404 *******************************************************************************/
406 bool patcher_checkcast_instanceof_interface(patchref_t *pr)
410 constant_classref *cr;
415 /* get stuff from the stack */
418 cr = (constant_classref *) pr->ref;
420 /* get the fieldinfo */
422 if (!(c = resolve_classref_eager(cr)))
425 /* patch back original code */
427 PATCH_BACK_ORIGINAL_MCODE;
429 /* If NOPs are generated, skip them */
432 ra += PATCHER_NOPS_SKIP;
434 /* patch super class index */
436 /* From here, split your editor and open codegen.c */
438 switch (N_RX_GET_REG(ra)) {
440 /* First M_ALD is into ITMP1 */
441 /* INSTANCEOF code */
443 N_RI_SET_IMM(ra + SZ_L + SZ_L, - c->index);
445 ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC,
446 (int16_t)(OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*))
451 /* First M_ALD is into ITMP2 */
454 N_RI_SET_IMM(ra + SZ_L + SZ_L, - c->index);
456 ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC + SZ_ILL,
457 (int16_t)(OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*))
471 * These are local overrides for various environment variables in Emacs.
472 * Please do not remove this and leave it at the end of the file, where
473 * Emacs will automagically detect them.
474 * ---------------------------------------------------------------------
477 * indent-tabs-mode: t
481 * vim:noexpandtab:sw=4:ts=4: