1 /* src/vm/jit/mips/patcher.c - MIPS 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 2444 2005-05-11 12:51:53Z twisti $
37 #include "vm/jit/mips/types.h"
39 #include "vm/builtin.h"
41 #include "vm/initialize.h"
42 #include "vm/options.h"
43 #include "vm/references.h"
44 #include "vm/jit/asmpart.h"
45 #include "vm/jit/helper.h"
48 /* patcher_get_putstatic *******************************************************
52 <patched call position>
53 dfc1ffb8 ld at,-72(s8)
56 *******************************************************************************/
58 bool patcher_get_putstatic(u1 *sp)
68 /* get stuff from the stack */
70 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
71 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
72 mcode = *((u8 *) (sp + 1 * 8));
73 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
74 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
76 /* calculate and set the new return address */
79 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
81 #if defined(USE_THREADS)
82 /* enter a monitor on the patching position */
84 builtin_monitorenter(o);
86 /* check if the position has already been patched */
89 builtin_monitorexit(o);
95 /* get the fieldinfo */
97 if (!(fi = helper_resolve_fieldinfo(uf)))
100 /* check if the field's class is initialized */
102 if (!fi->class->initialized)
103 if (!initialize_class(fi->class))
106 /* patch back original code */
108 *((u4 *) (ra + 0 * 4)) = mcode;
109 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
111 /* if we show disassembly, we have to skip the nop's */
116 /* get the offset from machine instruction */
118 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
120 /* patch the field value's address */
122 *((ptrint *) (pv + offset)) = (ptrint) &(fi->value);
124 /* synchronize instruction cache */
126 docacheflush(ra, 2 * 4);
128 #if defined(USE_THREADS)
129 /* this position has been patched */
131 o->vftbl = (vftbl_t *) 1;
133 /* leave the monitor on the patching position */
135 builtin_monitorexit(o);
142 /* patcher_get_putfield ********************************************************
146 <patched call position>
147 8ee90020 lw a5,32(s7)
149 *******************************************************************************/
151 bool patcher_get_putfield(u1 *sp)
154 java_objectheader *o;
156 unresolved_field *uf;
159 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
160 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
161 mcode = *((u8 *) (sp + 1 * 8));
162 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
164 /* calculate and set the new return address */
167 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
169 #if defined(USE_THREADS)
170 /* enter a monitor on the patching position */
172 builtin_monitorenter(o);
174 /* check if the position has already been patched */
177 builtin_monitorexit(o);
183 /* get the fieldinfo */
185 if (!(fi = helper_resolve_fieldinfo(uf)))
188 /* patch back original code */
190 *((u4 *) (ra + 0 * 4)) = mcode;
191 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
193 /* if we show disassembly, we have to skip the nop's */
198 /* patch the field's offset */
200 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
202 /* synchronize instruction cache */
204 docacheflush(ra, 2 * 4);
206 #if defined(USE_THREADS)
207 /* this position has been patched */
209 o->vftbl = (vftbl_t *) 1;
211 /* leave the monitor on the patching position */
213 builtin_monitorexit(o);
220 /* patcher_builtin_new *********************************************************
224 dfc4ff98 ld a0,-104(s8)
225 <patched call postition>
226 dfd9ff90 ld t9,-112(s8)
230 *******************************************************************************/
232 bool patcher_builtin_new(u1 *sp)
235 java_objectheader *o;
237 constant_classref *cr;
242 /* get stuff from the stack */
244 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
245 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
246 mcode = *((u8 *) (sp + 1 * 8));
247 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
248 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
250 /* calculate and set the new return address */
252 ra = ra - (4 + 2 * 4);
253 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
255 #if defined(USE_THREADS)
256 /* enter a monitor on the patching position */
258 builtin_monitorenter(o);
260 /* check if the position has already been patched */
263 builtin_monitorexit(o);
269 /* get the classinfo */
271 if (!(c = helper_resolve_classinfo(cr)))
274 /* patch back original code */
276 *((u4 *) (ra + 1 * 4)) = mcode;
277 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
279 /* get the offset from machine instruction */
281 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
283 /* patch the classinfo pointer */
285 *((ptrint *) (pv + offset)) = (ptrint) c;
287 /* if we show disassembly, we have to skip the nop's */
292 /* get the offset from machine instruction */
294 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
296 /* patch new function address */
298 *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_new;
300 /* synchronize instruction cache */
302 docacheflush(ra + 4, 2 * 4);
304 #if defined(USE_THREADS)
305 /* this position has been patched */
307 o->vftbl = (vftbl_t *) 1;
309 /* leave the monitor on the patching position */
311 builtin_monitorexit(o);
318 /* patcher_builtin_newarray ****************************************************
322 dfc5ffa0 ld a1,-96(s8)
323 <patched call position>
324 dfd9ff98 ld t9,-104(s8)
328 *******************************************************************************/
330 bool patcher_builtin_newarray(u1 *sp)
333 java_objectheader *o;
335 constant_classref *cr;
340 /* get stuff from the stack */
342 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
343 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
344 mcode = *((u8 *) (sp + 1 * 8));
345 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
346 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
348 /* calculate and set the new return address */
350 ra = ra - (4 + 2 * 4);
351 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
353 #if defined(USE_THREADS)
354 /* enter a monitor on the patching position */
356 builtin_monitorenter(o);
358 /* check if the position has already been patched */
361 builtin_monitorexit(o);
367 /* get the classinfo */
369 if (!(c = helper_resolve_classinfo(cr)))
372 /* patch back original code */
374 *((u4 *) (ra + 1 * 4)) = mcode;
375 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
377 /* get the offset from machine instruction */
379 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
381 /* patch the class' vftbl pointer */
383 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
385 /* if we show disassembly, we have to skip the nop */
390 /* get the offset from machine instruction */
392 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
394 /* patch new function address */
396 *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_newarray;
398 /* synchronize instruction cache */
400 docacheflush(ra + 4, 2 * 4);
402 #if defined(USE_THREADS)
403 /* this position has been patched */
405 o->vftbl = (vftbl_t *) 1;
407 /* leave the monitor on the patching position */
409 builtin_monitorexit(o);
416 /* patcher_builtin_multianewarray **********************************************
420 <patched call position>
421 24040002 addiu a0,zero,2
422 dfc5ff90 ld a1,-112(s8)
424 dfd9ff88 ld t9,-120(s8)
428 *******************************************************************************/
430 bool patcher_builtin_multianewarray(u1 *sp)
433 java_objectheader *o;
435 constant_classref *cr;
440 /* get stuff from the stack */
442 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
443 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
444 mcode = *((u8 *) (sp + 1 * 8));
445 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
446 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
448 /* calculate and set the new return address */
451 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
453 #if defined(USE_THREADS)
454 /* enter a monitor on the patching position */
456 builtin_monitorenter(o);
458 /* check if the position has already been patched */
461 builtin_monitorexit(o);
467 /* get the classinfo */
469 if (!(c = helper_resolve_classinfo(cr)))
472 /* patch back original code */
474 *((u4 *) (ra + 0 * 4)) = mcode;
475 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
477 /* if we show disassembly, we have to skip the nop's */
482 /* get the offset from machine instruction */
484 offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
486 /* patch the class' vftbl pointer */
488 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
490 /* synchronize instruction cache */
492 docacheflush(ra, 2 * 4);
494 #if defined(USE_THREADS)
495 /* this position has been patched */
497 o->vftbl = (vftbl_t *) 1;
499 /* leave the monitor on the patching position */
501 builtin_monitorexit(o);
508 /* patcher_builtin_arraycheckcast **********************************************
512 dfc5ffc0 ld a1,-64(s8)
513 <patched call position>
514 dfd9ffb8 ld t9,-72(s8)
518 *******************************************************************************/
520 bool patcher_builtin_arraycheckcast(u1 *sp)
523 java_objectheader *o;
525 constant_classref *cr;
530 /* get stuff from the stack */
532 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
533 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
534 mcode = *((u8 *) (sp + 1 * 8));
535 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
536 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
538 /* calculate and set the new return address */
541 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
543 #if defined(USE_THREADS)
544 /* enter a monitor on the patching position */
546 builtin_monitorenter(o);
548 /* check if the position has already been patched */
551 builtin_monitorexit(o);
557 /* get the classinfo */
559 if (!(c = helper_resolve_classinfo(cr)))
562 /* patch back original code */
564 *((u4 *) (ra + 1 * 4)) = mcode;
565 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
567 /* get the offset from machine instruction */
569 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
571 /* patch the class' vftbl pointer */
573 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
575 /* if we show disassembly, we have to skip the nop */
580 /* get the offset from machine instruction */
582 offset = (s2) (*((u4 *) (ra + 1 * 4)) & 0x0000ffff);
584 /* patch new function address */
586 *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_arraycheckcast;
588 /* synchronize instruction cache */
590 docacheflush(ra + 4, 2 * 4);
592 #if defined(USE_THREADS)
593 /* this position has been patched */
595 o->vftbl = (vftbl_t *) 1;
597 /* leave the monitor on the patching position */
599 builtin_monitorexit(o);
606 /* patcher_builtin_arrayinstanceof *********************************************
610 dfc5fe98 ld a1,-360(s8)
611 <patched call position>
612 dfd9fe90 ld t9,-368(s8)
616 *******************************************************************************/
618 bool patcher_builtin_arrayinstanceof(u1 *sp)
621 java_objectheader *o;
623 constant_classref *cr;
628 /* get stuff from the stack */
630 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
631 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
632 mcode = *((u8 *) (sp + 1 * 8));
633 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
634 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
636 /* calculate and set the new return address */
639 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
641 #if defined(USE_THREADS)
642 /* enter a monitor on the patching position */
644 builtin_monitorenter(o);
646 /* check if the position has already been patched */
649 builtin_monitorexit(o);
655 /* get the classinfo */
657 if (!(c = helper_resolve_classinfo(cr)))
660 /* patch back original code */
662 *((u4 *) (ra + 1 * 4)) = mcode;
663 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
665 /* get the offset from machine instruction */
667 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
669 /* patch the class' vftbl pointer */
671 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
673 /* if we show disassembly, we have to skip the nop's */
678 /* get the offset from machine instruction */
680 offset = (s2) (*((u4 *) (ra + 1 * 4)) & 0x0000ffff);
682 /* patch new function address */
684 *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_arrayinstanceof;
686 /* synchronize instruction cache */
688 docacheflush(ra + 4, 2 * 4);
690 #if defined(USE_THREADS)
691 /* this position has been patched */
693 o->vftbl = (vftbl_t *) 1;
695 /* leave the monitor on the patching position */
697 builtin_monitorexit(o);
704 /* patcher_invokestatic_special ************************************************
708 <patched call position>
709 dfdeffc0 ld s8,-64(s8)
713 ******************************************************************************/
715 bool patcher_invokestatic_special(u1 *sp)
718 java_objectheader *o;
720 unresolved_method *um;
725 /* get stuff from the stack */
727 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
728 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
729 mcode = *((u8 *) (sp + 1 * 8));
730 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
731 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
733 /* calculate and set the new return address */
736 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
738 #if defined(USE_THREADS)
739 /* enter a monitor on the patching position */
741 builtin_monitorenter(o);
743 /* check if the position has already been patched */
746 builtin_monitorexit(o);
752 /* get the fieldinfo */
754 if (!(m = helper_resolve_methodinfo(um)))
757 /* patch back original code */
759 *((u4 *) (ra + 0 * 4)) = mcode;
760 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
762 /* if we show disassembly, we have to skip the nop's */
767 /* get the offset from machine instruction */
769 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
771 /* patch stubroutine */
773 *((ptrint *) (pv + offset)) = (ptrint) m->stubroutine;
775 /* synchronize instruction cache */
777 docacheflush(ra, 2 * 4);
779 #if defined(USE_THREADS)
780 /* this position has been patched */
782 o->vftbl = (vftbl_t *) 1;
784 /* leave the monitor on the patching position */
786 builtin_monitorexit(o);
793 /* patcher_invokevirtual *******************************************************
797 <patched call position>
799 df3e0040 ld s8,64(t9)
803 *******************************************************************************/
805 bool patcher_invokevirtual(u1 *sp)
808 java_objectheader *o;
810 unresolved_method *um;
813 /* get stuff from the stack */
815 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
816 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
817 mcode = *((u8 *) (sp + 1 * 8));
818 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
820 /* calculate and set the new return address */
823 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
825 #if defined(USE_THREADS)
826 /* enter a monitor on the patching position */
828 builtin_monitorenter(o);
830 /* check if the position has already been patched */
833 builtin_monitorexit(o);
839 /* get the fieldinfo */
841 if (!(m = helper_resolve_methodinfo(um)))
844 /* patch back original code */
846 *((u4 *) (ra + 0 * 4)) = mcode;
847 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
849 /* if we show disassembly, we have to skip the nop's */
854 /* patch vftbl index */
856 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
857 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
859 /* synchronize instruction cache */
861 docacheflush(ra, 2 * 4);
863 #if defined(USE_THREADS)
864 /* this position has been patched */
866 o->vftbl = (vftbl_t *) 1;
868 /* leave the monitor on the patching position */
870 builtin_monitorexit(o);
877 /* patcher_invokeinterface *****************************************************
881 <patched call position>
883 df39ffa0 ld t9,-96(t9)
884 df3e0018 ld s8,24(t9)
888 *******************************************************************************/
890 bool patcher_invokeinterface(u1 *sp)
893 java_objectheader *o;
895 unresolved_method *um;
898 /* get stuff from the stack */
900 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
901 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
902 mcode = *((u8 *) (sp + 1 * 8));
903 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
905 /* calculate and set the new return address */
908 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
910 #if defined(USE_THREADS)
911 /* enter a monitor on the patching position */
913 builtin_monitorenter(o);
915 /* check if the position has already been patched */
918 builtin_monitorexit(o);
924 /* get the fieldinfo */
926 if (!(m = helper_resolve_methodinfo(um)))
929 /* patch back original code */
931 *((u4 *) (ra + 0 * 4)) = mcode;
932 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
934 /* if we show disassembly, we have to skip the nop's */
939 /* patch interfacetable index */
941 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
942 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
944 /* patch method offset */
946 *((s4 *) (ra + 2 * 4)) |=
947 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
949 /* synchronize instruction cache */
951 docacheflush(ra, 2 * 4);
953 #if defined(USE_THREADS)
954 /* this position has been patched */
956 o->vftbl = (vftbl_t *) 1;
958 /* leave the monitor on the patching position */
960 builtin_monitorexit(o);
967 /* patcher_checkcast_instanceof_flags ******************************************
971 <patched call position>
972 8fc3ff24 lw v1,-220(s8)
973 30630200 andi v1,v1,512
974 1060000d beq v1,zero,0x000000001051824c
977 *******************************************************************************/
979 bool patcher_checkcast_instanceof_flags(u1 *sp)
982 java_objectheader *o;
984 constant_classref *cr;
989 /* get stuff from the stack */
991 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
992 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
993 mcode = *((u8 *) (sp + 1 * 8));
994 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
995 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
997 /* calculate and set the new return address */
1000 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1002 #if defined(USE_THREADS)
1003 /* enter a monitor on the patching position */
1005 builtin_monitorenter(o);
1007 /* check if the position has already been patched */
1010 builtin_monitorexit(o);
1016 /* get the fieldinfo */
1018 if (!(c = helper_resolve_classinfo(cr)))
1021 /* patch back original code */
1023 *((u4 *) (ra + 0 * 4)) = mcode;
1024 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1026 /* if we show disassembly, we have to skip the nop's */
1028 if (showdisassemble)
1031 /* get the offset from machine instruction */
1033 offset = (s2) (*((u4 *) ra) & 0x0000ffff);
1035 /* patch class flags */
1037 *((s4 *) (pv + offset)) = (s4) c->flags;
1039 /* synchronize instruction cache */
1041 docacheflush(ra, 2 * 4);
1043 #if defined(USE_THREADS)
1044 /* this position has been patched */
1046 o->vftbl = (vftbl_t *) 1;
1048 /* leave the monitor on the patching position */
1050 builtin_monitorexit(o);
1057 /* patcher_checkcast_instanceof_interface **************************************
1061 <patched call position>
1062 dd030000 ld v1,0(a4)
1063 8c79001c lw t9,28(v1)
1064 27390000 addiu t9,t9,0
1065 1b200082 blez t9,zero,0x000000001051843c
1067 dc790000 ld t9,0(v1)
1069 *******************************************************************************/
1071 bool patcher_checkcast_instanceof_interface(u1 *sp)
1074 java_objectheader *o;
1076 constant_classref *cr;
1079 /* get stuff from the stack */
1081 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1082 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1083 mcode = *((u8 *) (sp + 1 * 8));
1084 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1086 /* calculate and set the new return address */
1089 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1091 #if defined(USE_THREADS)
1092 /* enter a monitor on the patching position */
1094 builtin_monitorenter(o);
1096 /* check if the position has already been patched */
1099 builtin_monitorexit(o);
1105 /* get the fieldinfo */
1107 if (!(c = helper_resolve_classinfo(cr)))
1110 /* patch back original code */
1112 *((u4 *) (ra + 0 * 4)) = mcode;
1113 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1115 /* if we show disassembly, we have to skip the nop's */
1117 if (showdisassemble)
1120 /* patch super class index */
1122 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
1124 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
1125 c->index * sizeof(methodptr*)) & 0x0000ffff);
1127 /* synchronize instruction cache */
1129 docacheflush(ra, 6 * 4);
1131 #if defined(USE_THREADS)
1132 /* this position has been patched */
1134 o->vftbl = (vftbl_t *) 1;
1136 /* leave the monitor on the patching position */
1138 builtin_monitorexit(o);
1145 /* patcher_checkcast_instanceof_class ******************************************
1149 <patched call position>
1150 dd030000 ld v1,0(a4)
1151 dfd9ff18 ld t9,-232(s8)
1153 *******************************************************************************/
1155 bool patcher_checkcast_instanceof_class(u1 *sp)
1158 java_objectheader *o;
1160 constant_classref *cr;
1165 /* get stuff from the stack */
1167 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1168 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1169 mcode = *((u8 *) (sp + 1 * 8));
1170 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1171 pv = (u1 *) *((ptrint *) (sp - 2 * 8));
1173 /* calculate and set the new return address */
1176 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1178 #if defined(USE_THREADS)
1179 /* enter a monitor on the patching position */
1181 builtin_monitorenter(o);
1183 /* check if the position has already been patched */
1186 builtin_monitorexit(o);
1192 /* get the fieldinfo */
1194 if (!(c = helper_resolve_classinfo(cr)))
1197 /* patch back original code */
1199 *((u4 *) (ra + 0 * 4)) = mcode;
1200 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1202 /* if we show disassembly, we have to skip the nop's */
1204 if (showdisassemble)
1207 /* get the offset from machine instruction */
1209 offset = (s2) (*((u4 *) (ra + 1 * 4)) & 0x0000ffff);
1211 /* patch super class' vftbl */
1213 *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
1215 /* synchronize instruction cache */
1217 docacheflush(ra, 2 * 4);
1219 #if defined(USE_THREADS)
1220 /* this position has been patched */
1222 o->vftbl = (vftbl_t *) 1;
1224 /* leave the monitor on the patching position */
1226 builtin_monitorexit(o);
1233 /* patcher_clinit **************************************************************
1237 *******************************************************************************/
1239 bool patcher_clinit(u1 *sp)
1242 java_objectheader *o;
1246 /* get stuff from the stack */
1248 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1249 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1250 mcode = *((u8 *) (sp + 1 * 8));
1251 c = (classinfo *) *((ptrint *) (sp + 0 * 8));
1253 /* calculate and set the new return address */
1256 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1258 #if defined(USE_THREADS)
1259 /* enter a monitor on the patching position */
1261 builtin_monitorenter(o);
1263 /* check if the position has already been patched */
1266 builtin_monitorexit(o);
1272 /* check if the class is initialized */
1274 if (!c->initialized)
1275 if (!initialize_class(c))
1278 /* patch back original code */
1280 *((u4 *) (ra + 0)) = mcode;
1281 *((u4 *) (ra + 4)) = mcode >> 32;
1283 /* synchronize instruction cache */
1285 docacheflush(ra, 2 * 4);
1287 #if defined(USE_THREADS)
1288 /* this position has been patched */
1290 o->vftbl = (vftbl_t *) 1;
1292 /* leave the monitor on the patching position */
1294 builtin_monitorexit(o);
1302 * These are local overrides for various environment variables in Emacs.
1303 * Please do not remove this and leave it at the end of the file, where
1304 * Emacs will automagically detect them.
1305 * ---------------------------------------------------------------------
1308 * indent-tabs-mode: t
1312 * vim:noexpandtab:sw=4:ts=4: