1 /* src/vm/jit/alpha/patcher.c - Alpha code patching functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
31 $Id: patcher.c 2527 2005-05-25 08:07:57Z twisti $
36 #include "vm/jit/alpha/types.h"
37 #include "vm/builtin.h"
39 #include "vm/initialize.h"
40 #include "vm/options.h"
41 #include "vm/references.h"
42 #include "vm/jit/asmpart.h"
43 #include "vm/jit/helper.h"
44 #include "vm/jit/patcher.h"
47 /* patcher_get_putstatic *******************************************************
51 <patched call position>
52 a73bff98 ldq t11,-104(pv)
53 a2590000 ldl a2,0(t11)
55 *******************************************************************************/
57 bool patcher_get_putstatic(u1 *sp)
67 /* get stuff from the stack */
69 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
70 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
71 mcode = *((u4 *) (sp + 1 * 8));
72 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
73 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
75 /* calculate and set the new return address */
78 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
82 /* get the fieldinfo */
84 if (!(fi = helper_resolve_fieldinfo(uf)))
87 /* check if the field's class is initialized */
89 if (!fi->class->initialized)
90 if (!initialize_class(fi->class))
93 /* patch back original code */
97 /* if we show disassembly, we have to skip the nop */
102 /* get the offset from machine instruction */
104 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
106 /* patch the field value's address */
108 *((ptrint *) (pv + offset)) = (ptrint) &(fi->value);
110 /* synchronize instruction cache */
112 asm_sync_instruction_cache();
120 /* patcher_get_putfield ********************************************************
124 <patched call position>
125 a2af0020 ldl a5,32(s6)
127 *******************************************************************************/
129 bool patcher_get_putfield(u1 *sp)
132 java_objectheader *o;
134 unresolved_field *uf;
138 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
139 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
140 mcode = *((u4 *) (sp + 1 * 8));
141 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
142 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
144 /* calculate and set the new return address */
147 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
149 PATCHER_MONITORENTER;
151 /* get the fieldinfo */
153 if (!(fi = helper_resolve_fieldinfo(uf)))
156 /* patch back original code */
158 *((u4 *) ra) = mcode;
160 /* if we show disassembly, we have to skip the nop */
165 /* patch the field's offset */
167 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
169 /* synchronize instruction cache */
171 asm_sync_instruction_cache();
179 /* patcher_builtin_new *********************************************************
183 a61bff80 ldq a0,-128(pv)
184 <patched call postition>
185 a77bff78 ldq pv,-136(pv)
188 *******************************************************************************/
190 bool patcher_builtin_new(u1 *sp)
193 java_objectheader *o;
195 constant_classref *cr;
200 /* get stuff from the stack */
202 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
203 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
204 mcode = *((u4 *) (sp + 1 * 8));
205 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
206 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
208 /* calculate and set the new return address */
211 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
213 PATCHER_MONITORENTER;
215 /* get the classinfo */
217 if (!(c = helper_resolve_classinfo(cr)))
220 /* patch back original code */
222 *((u4 *) (ra + 4)) = mcode;
224 /* get the offset from machine instruction */
226 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
228 /* patch the classinfo pointer */
230 *((ptrint *) (pv + offset)) = (ptrint) c;
232 /* if we show disassembly, we have to skip the nop */
237 /* get the offset from machine instruction */
239 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
241 /* patch new function address */
243 *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_new;
245 /* synchronize instruction cache */
247 asm_sync_instruction_cache();
255 /* patcher_builtin_newarray ****************************************************
259 a63bff88 ldq a1,-120(pv)
260 <patched call position>
261 a77bff80 ldq pv,-128(pv)
264 *******************************************************************************/
266 bool patcher_builtin_newarray(u1 *sp)
269 java_objectheader *o;
271 constant_classref *cr;
276 /* get stuff from the stack */
278 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
279 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
280 mcode = *((u4 *) (sp + 1 * 8));
281 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
282 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
284 /* calculate and set the new return address */
287 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
289 PATCHER_MONITORENTER;
291 /* get the classinfo */
293 if (!(c = helper_resolve_classinfo(cr)))
296 /* patch back original code */
298 *((u4 *) (ra + 4)) = mcode;
300 /* get the offset from machine instruction */
302 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
304 /* patch the class' vftbl pointer */
306 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
308 /* if we show disassembly, we have to skip the nop */
313 /* get the offset from machine instruction */
315 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
317 /* patch new function address */
319 *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_newarray;
321 /* synchronize instruction cache */
323 asm_sync_instruction_cache();
331 /* patcher_builtin_multianewarray **********************************************
335 <patched call position>
336 221f0002 lda a0,2(zero)
337 a63bff80 ldq a1,-128(pv)
339 a77bff78 ldq pv,-136(pv)
342 *******************************************************************************/
344 bool patcher_builtin_multianewarray(u1 *sp)
347 java_objectheader *o;
349 constant_classref *cr;
354 /* get stuff from the stack */
356 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
357 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
358 mcode = *((u4 *) (sp + 1 * 8));
359 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
360 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
362 /* calculate and set the new return address */
365 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
367 PATCHER_MONITORENTER;
369 /* get the classinfo */
371 if (!(c = helper_resolve_classinfo(cr)))
374 /* patch back original code */
376 *((u4 *) ra) = mcode;
378 /* if we show disassembly, we have to skip the nop */
383 /* get the offset from machine instruction */
385 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
387 /* patch the class' vftbl pointer */
389 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
391 /* synchronize instruction cache */
393 asm_sync_instruction_cache();
401 /* patcher_builtin_arraycheckcast **********************************************
405 a63bfe60 ldq a1,-416(pv)
406 <patched call position>
407 a77bfe58 ldq pv,-424(pv)
410 *******************************************************************************/
412 bool patcher_builtin_arraycheckcast(u1 *sp)
415 java_objectheader *o;
417 constant_classref *cr;
422 /* get stuff from the stack */
424 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
425 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
426 mcode = *((u4 *) (sp + 1 * 8));
427 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
428 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
430 /* calculate and set the new return address */
433 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
435 PATCHER_MONITORENTER;
437 /* get the classinfo */
439 if (!(c = helper_resolve_classinfo(cr)))
442 /* patch back original code */
444 *((u4 *) (ra + 4)) = mcode;
446 /* get the offset from machine instruction */
448 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
450 /* patch the class' vftbl pointer */
452 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
454 /* if we show disassembly, we have to skip the nop */
459 /* get the offset from machine instruction */
461 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
463 /* patch new function address */
465 *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_arraycheckcast;
467 /* synchronize instruction cache */
469 asm_sync_instruction_cache();
477 /* patcher_builtin_arrayinstanceof *********************************************
481 a63bfeb0 ldq a1,-336(pv)
482 <patched call position>
483 a77bfea8 ldq pv,-344(pv)
486 *******************************************************************************/
488 bool patcher_builtin_arrayinstanceof(u1 *sp)
491 java_objectheader *o;
493 constant_classref *cr;
498 /* get stuff from the stack */
500 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
501 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
502 mcode = *((u4 *) (sp + 1 * 8));
503 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
504 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
506 /* calculate and set the new return address */
509 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
511 PATCHER_MONITORENTER;
513 /* get the classinfo */
515 if (!(c = helper_resolve_classinfo(cr)))
518 /* patch back original code */
520 *((u4 *) (ra + 4)) = mcode;
522 /* get the offset from machine instruction */
524 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
526 /* patch the class' vftbl pointer */
528 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
530 /* if we show disassembly, we have to skip the nop */
535 /* get the offset from machine instruction */
537 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
539 /* patch new function address */
541 *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_arrayinstanceof;
543 /* synchronize instruction cache */
545 asm_sync_instruction_cache();
553 /* patcher_invokestatic_special ************************************************
557 <patched call position>
558 a77bffa8 ldq pv,-88(pv)
561 ******************************************************************************/
563 bool patcher_invokestatic_special(u1 *sp)
566 java_objectheader *o;
568 unresolved_method *um;
573 /* get stuff from the stack */
575 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
576 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
577 mcode = *((u4 *) (sp + 1 * 8));
578 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
579 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
581 /* calculate and set the new return address */
584 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
586 PATCHER_MONITORENTER;
588 /* get the fieldinfo */
590 if (!(m = helper_resolve_methodinfo(um)))
593 /* patch back original code */
595 *((u4 *) ra) = mcode;
597 /* if we show disassembly, we have to skip the nop */
602 /* get the offset from machine instruction */
604 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
606 /* patch stubroutine */
608 *((ptrint *) (pv + offset)) = (ptrint) m->stubroutine;
610 /* synchronize instruction cache */
612 asm_sync_instruction_cache();
620 /* patcher_invokevirtual *******************************************************
624 <patched call position>
625 a7900000 ldq at,0(a0)
626 a77c0100 ldq pv,256(at)
629 *******************************************************************************/
631 bool patcher_invokevirtual(u1 *sp)
634 java_objectheader *o;
636 unresolved_method *um;
639 /* get stuff from the stack */
641 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
642 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
643 mcode = *((u4 *) (sp + 1 * 8));
644 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
646 /* calculate and set the new return address */
649 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
651 PATCHER_MONITORENTER;
653 /* get the fieldinfo */
655 if (!(m = helper_resolve_methodinfo(um)))
658 /* patch back original code */
660 *((u4 *) ra) = mcode;
662 /* if we show disassembly, we have to skip the nop */
667 /* patch vftbl index */
669 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
670 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
672 /* synchronize instruction cache */
674 asm_sync_instruction_cache();
682 /* patcher_invokeinterface *****************************************************
686 <patched call position>
687 a7900000 ldq at,0(a0)
688 a79cffa0 ldq at,-96(at)
689 a77c0018 ldq pv,24(at)
692 *******************************************************************************/
694 bool patcher_invokeinterface(u1 *sp)
697 java_objectheader *o;
699 unresolved_method *um;
702 /* get stuff from the stack */
704 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
705 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
706 mcode = *((u4 *) (sp + 1 * 8));
707 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
709 /* calculate and set the new return address */
712 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
714 PATCHER_MONITORENTER;
716 /* get the fieldinfo */
718 if (!(m = helper_resolve_methodinfo(um)))
721 /* patch back original code */
723 *((u4 *) ra) = mcode;
725 /* if we show disassembly, we have to skip the nop */
730 /* patch interfacetable index */
732 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
733 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
735 /* patch method offset */
737 *((s4 *) (ra + 4 + 4)) |=
738 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
740 /* synchronize instruction cache */
742 asm_sync_instruction_cache();
750 /* patcher_checkcast_instanceof_flags ******************************************
754 <patched call position>
756 *******************************************************************************/
758 bool patcher_checkcast_instanceof_flags(u1 *sp)
761 java_objectheader *o;
763 constant_classref *cr;
768 /* get stuff from the stack */
770 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
771 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
772 mcode = *((u4 *) (sp + 1 * 8));
773 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
774 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
776 /* calculate and set the new return address */
779 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
781 PATCHER_MONITORENTER;
783 /* get the fieldinfo */
785 if (!(c = helper_resolve_classinfo(cr)))
788 /* patch back original code */
790 *((u4 *) ra) = mcode;
792 /* if we show disassembly, we have to skip the nop */
797 /* get the offset from machine instruction */
799 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
801 /* patch class flags */
803 *((s4 *) (pv + offset)) = (s4) c->flags;
805 /* synchronize instruction cache */
807 asm_sync_instruction_cache();
815 /* patcher_checkcast_instanceof_interface **************************************
819 <patched call position>
820 a78e0000 ldq at,0(s5)
821 a3bc001c ldl gp,28(at)
822 23bdfffd lda gp,-3(gp)
823 efa0002e ble gp,0x00000200002bf6b0
824 a7bcffe8 ldq gp,-24(at)
826 *******************************************************************************/
828 bool patcher_checkcast_instanceof_interface(u1 *sp)
831 java_objectheader *o;
833 constant_classref *cr;
836 /* get stuff from the stack */
838 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
839 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
840 mcode = *((u4 *) (sp + 1 * 8));
841 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
843 /* calculate and set the new return address */
846 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
848 PATCHER_MONITORENTER;
850 /* get the fieldinfo */
852 if (!(c = helper_resolve_classinfo(cr)))
855 /* patch back original code */
857 *((u4 *) ra) = mcode;
859 /* if we show disassembly, we have to skip the nop */
864 /* patch super class index */
866 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
868 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
869 c->index * sizeof(methodptr*)) & 0x0000ffff);
871 /* synchronize instruction cache */
873 asm_sync_instruction_cache();
881 /* patcher_checkcast_instanceof_class ******************************************
885 <patched call position>
886 a7940000 ldq at,0(a4)
887 a7bbff28 ldq gp,-216(pv)
889 *******************************************************************************/
891 bool patcher_checkcast_instanceof_class(u1 *sp)
894 java_objectheader *o;
896 constant_classref *cr;
901 /* get stuff from the stack */
903 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
904 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
905 mcode = *((u4 *) (sp + 1 * 8));
906 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
907 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
909 /* calculate and set the new return address */
912 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
914 PATCHER_MONITORENTER;
916 /* get the fieldinfo */
918 if (!(c = helper_resolve_classinfo(cr)))
921 /* patch back original code */
923 *((u4 *) ra) = mcode;
925 /* if we show disassembly, we have to skip the nop */
930 /* get the offset from machine instruction */
932 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
934 /* patch super class' vftbl */
936 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
938 /* synchronize instruction cache */
940 asm_sync_instruction_cache();
948 /* patcher_clinit **************************************************************
952 *******************************************************************************/
954 bool patcher_clinit(u1 *sp)
957 java_objectheader *o;
961 /* get stuff from the stack */
963 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
964 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
965 mcode = *((u4 *) (sp + 1 * 8));
966 c = (classinfo *) *((ptrint *) (sp + 0 * 8));
968 /* calculate and set the new return address */
971 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
973 PATCHER_MONITORENTER;
975 /* check if the class is initialized */
978 if (!initialize_class(c))
981 /* patch back original code */
983 *((u4 *) ra) = mcode;
985 /* synchronize instruction cache */
987 asm_sync_instruction_cache();
996 * These are local overrides for various environment variables in Emacs.
997 * Please do not remove this and leave it at the end of the file, where
998 * Emacs will automagically detect them.
999 * ---------------------------------------------------------------------
1002 * indent-tabs-mode: t
1006 * vim:noexpandtab:sw=4:ts=4: