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 3464 2005-10-20 10:16:29Z edwin $
36 #include <sys/cachectl.h>
41 #include "mm/memory.h"
42 #include "native/native.h"
43 #include "vm/builtin.h"
45 #include "vm/initialize.h"
46 #include "vm/options.h"
47 #include "vm/resolve.h"
48 #include "vm/references.h"
49 #include "vm/jit/asmpart.h"
50 #include "vm/jit/patcher.h"
53 /* patcher_get_putstatic *******************************************************
57 <patched call position>
58 dfc1ffb8 ld at,-72(s8)
61 *******************************************************************************/
63 bool patcher_get_putstatic(u1 *sp)
67 #if SIZEOF_VOID_P == 8
77 /* get stuff from the stack */
79 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
80 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
81 #if SIZEOF_VOID_P == 8
82 mcode = *((u8 *) (sp + 3 * 8));
84 mcode[0] = *((u4 *) (sp + 3 * 8));
85 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
87 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
88 disp = *((s4 *) (sp + 1 * 8));
89 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
91 /* calculate and set the new return address */
94 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
98 /* get the fieldinfo */
100 if (!(fi = resolve_field_eager(uf))) {
106 /* check if the field's class is initialized */
108 if (!fi->class->initialized) {
109 if (!initialize_class(fi->class)) {
116 /* patch back original code */
118 #if SIZEOF_VOID_P == 8
119 *((u4 *) (ra + 0 * 4)) = mcode;
120 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
122 *((u4 *) (ra + 0 * 4)) = mcode[0];
123 *((u4 *) (ra + 1 * 4)) = mcode[1];
126 /* synchronize instruction cache */
128 cacheflush(ra, 2 * 4, ICACHE);
130 /* patch the field value's address */
132 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
134 /* synchronize data cache */
136 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
138 PATCHER_MARK_PATCHED_MONITOREXIT;
144 /* patcher_get_putfield ********************************************************
148 <patched call position>
149 8ee90020 lw a5,32(s7)
151 *******************************************************************************/
153 bool patcher_get_putfield(u1 *sp)
156 java_objectheader *o;
157 #if SIZEOF_VOID_P == 8
162 unresolved_field *uf;
165 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
166 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
167 #if SIZEOF_VOID_P == 8
168 mcode = *((u8 *) (sp + 3 * 8));
170 mcode[0] = *((u4 *) (sp + 3 * 8));
171 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
173 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
175 /* calculate and set the new return address */
178 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
180 PATCHER_MONITORENTER;
182 /* get the fieldinfo */
184 if (!(fi = resolve_field_eager(uf))) {
190 /* patch back original code */
192 #if SIZEOF_VOID_P == 8
193 *((u4 *) (ra + 0 * 4)) = mcode;
194 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
196 *((u4 *) (ra + 0 * 4)) = mcode[0];
197 *((u4 *) (ra + 1 * 4)) = mcode[1];
200 /* if we show disassembly, we have to skip the nop's */
202 if (opt_showdisassemble)
205 /* patch the field's offset */
207 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
209 /* synchronize instruction cache */
211 if (opt_showdisassemble)
212 cacheflush(ra - 2 * 4, 3 * 4, ICACHE);
214 cacheflush(ra, 2 * 4, ICACHE);
216 PATCHER_MARK_PATCHED_MONITOREXIT;
222 /* patcher_builtin_new *********************************************************
226 dfc4ff98 ld a0,-104(s8)
227 <patched call postition>
228 dfd9ff90 ld t9,-112(s8)
232 NOTICE: Only the displacement for the function address is passed,
233 but the address of the classinfo pointer is one below (above, in
234 addresses speaking). This is for sure.
236 *******************************************************************************/
238 bool patcher_builtin_new(u1 *sp)
241 java_objectheader *o;
242 #if SIZEOF_VOID_P == 8
247 constant_classref *cr;
252 /* get stuff from the stack */
254 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
255 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
256 #if SIZEOF_VOID_P == 8
257 mcode = *((u8 *) (sp + 3 * 8));
259 mcode[0] = *((u4 *) (sp + 3 * 8));
260 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
262 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
263 disp = *((s4 *) (sp + 1 * 8));
264 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
266 /* calculate and set the new return address */
269 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
271 PATCHER_MONITORENTER;
273 /* get the classinfo */
275 if (!(c = resolve_classref_eager_nonabstract(cr))) {
281 /* patch back original code */
283 #if SIZEOF_VOID_P == 8
284 *((u4 *) (ra + 1 * 4)) = mcode;
285 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
287 *((u4 *) (ra + 1 * 4)) = mcode[0];
288 *((u4 *) (ra + 2 * 4)) = mcode[1];
291 /* synchronize instruction cache */
293 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
295 /* patch the classinfo pointer */
297 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c;
299 /* patch new function address */
301 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_new;
303 PATCHER_MARK_PATCHED_MONITOREXIT;
309 /* patcher_builtin_newarray ****************************************************
313 dfc5ffa0 ld a1,-96(s8)
314 <patched call position>
315 dfd9ff98 ld t9,-104(s8)
319 NOTICE: Only the displacement for the function address is passed,
320 but the address of the classinfo pointer is one below (above, in
321 addresses speaking). This is for sure.
323 *******************************************************************************/
325 bool patcher_builtin_newarray(u1 *sp)
328 java_objectheader *o;
329 #if SIZEOF_VOID_P == 8
334 constant_classref *cr;
339 /* get stuff from the stack */
341 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
342 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
343 #if SIZEOF_VOID_P == 8
344 mcode = *((u8 *) (sp + 3 * 8));
346 mcode[0] = *((u4 *) (sp + 3 * 8));
347 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
349 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
350 disp = *((s4 *) (sp + 1 * 8));
351 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
353 /* calculate and set the new return address */
356 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
358 PATCHER_MONITORENTER;
360 /* get the classinfo */
362 if (!(c = resolve_classref_eager(cr))) {
368 /* patch back original code */
370 #if SIZEOF_VOID_P == 8
371 *((u4 *) (ra + 1 * 4)) = mcode;
372 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
374 *((u4 *) (ra + 1 * 4)) = mcode[0];
375 *((u4 *) (ra + 2 * 4)) = mcode[1];
378 /* synchronize instruction cache */
380 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
382 /* patch the class' vftbl pointer */
384 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
386 /* patch new function address */
388 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_newarray;
390 PATCHER_MARK_PATCHED_MONITOREXIT;
396 /* patcher_builtin_multianewarray **********************************************
400 <patched call position>
401 dfc5ff90 ld a1,-112(s8)
403 dfd9ff88 ld t9,-120(s8)
407 *******************************************************************************/
409 bool patcher_builtin_multianewarray(u1 *sp)
412 java_objectheader *o;
413 #if SIZEOF_VOID_P == 8
418 constant_classref *cr;
423 /* get stuff from the stack */
425 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
426 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
427 #if SIZEOF_VOID_P == 8
428 mcode = *((u8 *) (sp + 3 * 8));
430 mcode[0] = *((u4 *) (sp + 3 * 8));
431 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
433 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
434 disp = *((s4 *) (sp + 1 * 8));
435 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
437 /* calculate and set the new return address */
440 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
442 PATCHER_MONITORENTER;
444 /* get the classinfo */
446 if (!(c = resolve_classref_eager(cr))) {
452 /* patch back original code */
454 #if SIZEOF_VOID_P == 8
455 *((u4 *) (ra + 0 * 4)) = mcode;
456 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
458 *((u4 *) (ra + 0 * 4)) = mcode[0];
459 *((u4 *) (ra + 1 * 4)) = mcode[1];
462 /* synchronize instruction cache */
464 cacheflush(ra, 2 * 4, ICACHE);
466 /* patch the class' vftbl pointer */
468 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
470 PATCHER_MARK_PATCHED_MONITOREXIT;
476 /* patcher_builtin_arraycheckcast **********************************************
480 <patched call position>
481 dfc5ffc0 ld a1,-64(s8)
482 dfd9ffb8 ld t9,-72(s8)
486 NOTICE: Only the displacement of the vftbl pointer address is
487 passed, but the address of the function pointer is one above
488 (below, in addresses speaking). This is for sure.
490 *******************************************************************************/
492 bool patcher_builtin_arraycheckcast(u1 *sp)
495 java_objectheader *o;
496 #if SIZEOF_VOID_P == 8
501 constant_classref *cr;
506 /* get stuff from the stack */
508 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
509 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
510 #if SIZEOF_VOID_P == 8
511 mcode = *((u8 *) (sp + 3 * 8));
513 mcode[0] = *((u4 *) (sp + 3 * 8));
514 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
516 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
517 disp = *((s4 *) (sp + 1 * 8));
518 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
520 /* calculate and set the new return address */
523 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
525 PATCHER_MONITORENTER;
527 /* get the classinfo */
529 if (!(c = resolve_classref_eager(cr))) {
535 /* patch back original code */
537 #if SIZEOF_VOID_P == 8
538 *((u4 *) (ra + 0 * 4)) = mcode;
539 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
541 *((u4 *) (ra + 0 * 4)) = mcode[0];
542 *((u4 *) (ra + 1 * 4)) = mcode[1];
545 /* synchronize instruction cache */
547 cacheflush(ra, 2 * 4, ICACHE);
549 /* patch the class' vftbl pointer */
551 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
553 /* patch new function address */
555 *((ptrint *) (pv + (disp - SIZEOF_VOID_P))) =
556 (ptrint) BUILTIN_arraycheckcast;
558 PATCHER_MARK_PATCHED_MONITOREXIT;
564 /* patcher_builtin_arrayinstanceof *********************************************
568 dfc5fe98 ld a1,-360(s8)
569 <patched call position>
570 dfd9fe90 ld t9,-368(s8)
574 NOTICE: Only the displacement for the function address is passed,
575 but the address of the vftbl pointer is one below (above, in
576 addresses speaking). This is for sure.
578 *******************************************************************************/
580 bool patcher_builtin_arrayinstanceof(u1 *sp)
583 java_objectheader *o;
584 #if SIZEOF_VOID_P == 8
589 constant_classref *cr;
594 /* get stuff from the stack */
596 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
597 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
598 #if SIZEOF_VOID_P == 8
599 mcode = *((u8 *) (sp + 3 * 8));
601 mcode[0] = *((u4 *) (sp + 3 * 8));
602 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
604 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
605 disp = *((s4 *) (sp + 1 * 8));
606 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
608 /* calculate and set the new return address */
611 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
613 PATCHER_MONITORENTER;
615 /* get the classinfo */
617 if (!(c = resolve_classref_eager(cr))) {
623 /* patch back original code */
625 #if SIZEOF_VOID_P == 8
626 *((u4 *) (ra + 1 * 4)) = mcode;
627 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
629 *((u4 *) (ra + 1 * 4)) = mcode[0];
630 *((u4 *) (ra + 2 * 4)) = mcode[1];
633 /* synchronize instruction cache */
635 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
637 /* patch the class' vftbl pointer */
639 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
641 /* patch new function address */
643 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_arrayinstanceof;
645 PATCHER_MARK_PATCHED_MONITOREXIT;
651 /* patcher_invokestatic_special ************************************************
655 <patched call position>
656 dfdeffc0 ld s8,-64(s8)
660 ******************************************************************************/
662 bool patcher_invokestatic_special(u1 *sp)
665 java_objectheader *o;
666 #if SIZEOF_VOID_P == 8
671 unresolved_method *um;
676 /* get stuff from the stack */
678 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
679 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
680 #if SIZEOF_VOID_P == 8
681 mcode = *((u8 *) (sp + 3 * 8));
683 mcode[0] = *((u4 *) (sp + 3 * 8));
684 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
686 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
687 disp = *((s4 *) (sp + 1 * 8));
688 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
690 /* calculate and set the new return address */
693 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
695 PATCHER_MONITORENTER;
697 /* get the fieldinfo */
699 if (!(m = resolve_method_eager(um))) {
705 /* patch back original code */
707 #if SIZEOF_VOID_P == 8
708 *((u4 *) (ra + 0 * 4)) = mcode;
709 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
711 *((u4 *) (ra + 0 * 4)) = mcode[0];
712 *((u4 *) (ra + 1 * 4)) = mcode[1];
715 /* synchronize instruction cache */
717 cacheflush(ra, 2 * 4, ICACHE);
719 /* patch stubroutine */
721 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
723 PATCHER_MARK_PATCHED_MONITOREXIT;
729 /* patcher_invokevirtual *******************************************************
733 <patched call position>
735 df3e0040 ld s8,64(t9)
739 *******************************************************************************/
741 bool patcher_invokevirtual(u1 *sp)
744 java_objectheader *o;
745 #if SIZEOF_VOID_P == 8
750 unresolved_method *um;
753 /* get stuff from the stack */
755 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
756 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
757 #if SIZEOF_VOID_P == 8
758 mcode = *((u8 *) (sp + 3 * 8));
760 mcode[0] = *((u4 *) (sp + 3 * 8));
761 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
763 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
765 /* calculate and set the new return address */
768 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
770 PATCHER_MONITORENTER;
772 /* get the fieldinfo */
774 if (!(m = resolve_method_eager(um))) {
780 /* patch back original code */
782 #if SIZEOF_VOID_P == 8
783 *((u4 *) (ra + 0 * 4)) = mcode;
784 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
786 *((u4 *) (ra + 0 * 4)) = mcode[0];
787 *((u4 *) (ra + 1 * 4)) = mcode[1];
790 /* if we show disassembly, we have to skip the nop's */
792 if (opt_showdisassemble)
795 /* patch vftbl index */
797 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
798 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
800 /* synchronize instruction cache */
802 if (opt_showdisassemble)
803 cacheflush(ra - 2 * 4, 4 * 4, ICACHE);
805 cacheflush(ra, 2 * 4, ICACHE);
807 PATCHER_MARK_PATCHED_MONITOREXIT;
813 /* patcher_invokeinterface *****************************************************
817 <patched call position>
819 df39ffa0 ld t9,-96(t9)
820 df3e0018 ld s8,24(t9)
824 *******************************************************************************/
826 bool patcher_invokeinterface(u1 *sp)
829 java_objectheader *o;
830 #if SIZEOF_VOID_P == 8
835 unresolved_method *um;
838 /* get stuff from the stack */
840 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
841 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
842 #if SIZEOF_VOID_P == 8
843 mcode = *((u8 *) (sp + 3 * 8));
845 mcode[0] = *((u4 *) (sp + 3 * 8));
846 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
848 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
850 /* calculate and set the new return address */
853 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
855 PATCHER_MONITORENTER;
857 /* get the fieldinfo */
859 if (!(m = resolve_method_eager(um))) {
865 /* patch back original code */
867 #if SIZEOF_VOID_P == 8
868 *((u4 *) (ra + 0 * 4)) = mcode;
869 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
871 *((u4 *) (ra + 0 * 4)) = mcode[0];
872 *((u4 *) (ra + 1 * 4)) = mcode[1];
875 /* if we show disassembly, we have to skip the nop's */
877 if (opt_showdisassemble)
880 /* patch interfacetable index */
882 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
883 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
885 /* patch method offset */
887 *((s4 *) (ra + 2 * 4)) |=
888 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
890 /* synchronize instruction cache */
892 if (opt_showdisassemble)
893 cacheflush(ra - 2 * 4, 5 * 4, ICACHE);
895 cacheflush(ra, 3 * 4, ICACHE);
897 PATCHER_MARK_PATCHED_MONITOREXIT;
903 /* patcher_checkcast_instanceof_flags ******************************************
907 <patched call position>
908 8fc3ff24 lw v1,-220(s8)
909 30630200 andi v1,v1,512
910 1060000d beq v1,zero,0x000000001051824c
913 *******************************************************************************/
915 bool patcher_checkcast_instanceof_flags(u1 *sp)
918 java_objectheader *o;
919 #if SIZEOF_VOID_P == 8
924 constant_classref *cr;
929 /* get stuff from the stack */
931 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
932 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
933 #if SIZEOF_VOID_P == 8
934 mcode = *((u8 *) (sp + 3 * 8));
936 mcode[0] = *((u4 *) (sp + 3 * 8));
937 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
939 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
940 disp = *((s4 *) (sp + 1 * 8));
941 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
943 /* calculate and set the new return address */
946 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
948 PATCHER_MONITORENTER;
950 /* get the fieldinfo */
952 if (!(c = resolve_classref_eager(cr))) {
958 /* patch back original code */
960 #if SIZEOF_VOID_P == 8
961 *((u4 *) (ra + 0 * 4)) = mcode;
962 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
964 *((u4 *) (ra + 0 * 4)) = mcode[0];
965 *((u4 *) (ra + 1 * 4)) = mcode[1];
968 /* synchronize instruction cache */
970 cacheflush(ra, 2 * 4, ICACHE);
972 /* patch class flags */
974 *((s4 *) (pv + disp)) = (s4) c->flags;
976 PATCHER_MARK_PATCHED_MONITOREXIT;
982 /* patcher_checkcast_instanceof_interface **************************************
986 <patched call position>
988 8c79001c lw t9,28(v1)
989 27390000 addiu t9,t9,0
990 1b200082 blez t9,zero,0x000000001051843c
994 *******************************************************************************/
996 bool patcher_checkcast_instanceof_interface(u1 *sp)
999 java_objectheader *o;
1000 #if SIZEOF_VOID_P == 8
1005 constant_classref *cr;
1008 /* get stuff from the stack */
1010 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1011 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1012 #if SIZEOF_VOID_P == 8
1013 mcode = *((u8 *) (sp + 3 * 8));
1015 mcode[0] = *((u4 *) (sp + 3 * 8));
1016 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1018 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
1020 /* calculate and set the new return address */
1023 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1025 PATCHER_MONITORENTER;
1027 /* get the fieldinfo */
1029 if (!(c = resolve_classref_eager(cr))) {
1030 PATCHER_MONITOREXIT;
1035 /* patch back original code */
1037 #if SIZEOF_VOID_P == 8
1038 *((u4 *) (ra + 0 * 4)) = mcode;
1039 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1041 *((u4 *) (ra + 0 * 4)) = mcode[0];
1042 *((u4 *) (ra + 1 * 4)) = mcode[1];
1045 /* if we show disassembly, we have to skip the nop's */
1047 if (opt_showdisassemble)
1050 /* patch super class index */
1052 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
1054 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
1055 c->index * sizeof(methodptr*)) & 0x0000ffff);
1057 /* synchronize instruction cache */
1059 if (opt_showdisassemble)
1060 cacheflush(ra - 2 * 4, 8 * 4, ICACHE);
1062 cacheflush(ra, 6 * 4, ICACHE);
1064 PATCHER_MARK_PATCHED_MONITOREXIT;
1070 /* patcher_checkcast_instanceof_class ******************************************
1074 <patched call position>
1075 dd030000 ld v1,0(a4)
1076 dfd9ff18 ld t9,-232(s8)
1078 *******************************************************************************/
1080 bool patcher_checkcast_instanceof_class(u1 *sp)
1083 java_objectheader *o;
1084 #if SIZEOF_VOID_P == 8
1089 constant_classref *cr;
1094 /* get stuff from the stack */
1096 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1097 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1098 #if SIZEOF_VOID_P == 8
1099 mcode = *((u8 *) (sp + 3 * 8));
1101 mcode[0] = *((u4 *) (sp + 3 * 8));
1102 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1104 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
1105 disp = *((s4 *) (sp + 1 * 8));
1106 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1108 /* calculate and set the new return address */
1111 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1113 PATCHER_MONITORENTER;
1115 /* get the fieldinfo */
1117 if (!(c = resolve_classref_eager(cr))) {
1118 PATCHER_MONITOREXIT;
1123 /* patch back original code */
1125 #if SIZEOF_VOID_P == 8
1126 *((u4 *) (ra + 0 * 4)) = mcode;
1127 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1129 *((u4 *) (ra + 0 * 4)) = mcode[0];
1130 *((u4 *) (ra + 1 * 4)) = mcode[1];
1133 /* synchronize instruction cache */
1135 cacheflush(ra, 2 * 4, ICACHE);
1137 /* patch super class' vftbl */
1139 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
1141 PATCHER_MARK_PATCHED_MONITOREXIT;
1147 /* patcher_clinit **************************************************************
1149 No special machine code.
1151 *******************************************************************************/
1153 bool patcher_clinit(u1 *sp)
1156 java_objectheader *o;
1157 #if SIZEOF_VOID_P == 8
1164 /* get stuff from the stack */
1166 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1167 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1168 #if SIZEOF_VOID_P == 8
1169 mcode = *((u8 *) (sp + 3 * 8));
1171 mcode[0] = *((u4 *) (sp + 3 * 8));
1172 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1174 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
1176 /* calculate and set the new return address */
1179 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1181 PATCHER_MONITORENTER;
1183 /* check if the class is initialized */
1185 if (!c->initialized) {
1186 if (!initialize_class(c)) {
1187 PATCHER_MONITOREXIT;
1193 /* patch back original code */
1195 #if SIZEOF_VOID_P == 8
1196 *((u4 *) (ra + 0 * 4)) = mcode;
1197 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1199 *((u4 *) (ra + 0 * 4)) = mcode[0];
1200 *((u4 *) (ra + 1 * 4)) = mcode[1];
1203 /* synchronize instruction cache */
1205 cacheflush(ra, 2 * 4, ICACHE);
1207 PATCHER_MARK_PATCHED_MONITOREXIT;
1213 /* patcher_resolve_native ******************************************************
1217 *******************************************************************************/
1219 #if !defined(ENABLE_STATICVM)
1220 bool patcher_resolve_native(u1 *sp)
1223 java_objectheader *o;
1224 #if SIZEOF_VOID_P == 8
1234 /* get stuff from the stack */
1236 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1237 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1238 #if SIZEOF_VOID_P == 8
1239 mcode = *((u8 *) (sp + 3 * 8));
1241 mcode[0] = *((u4 *) (sp + 3 * 8));
1242 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1244 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1245 disp = *((s4 *) (sp + 1 * 8));
1246 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1248 /* calculate and set the new return address */
1251 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1253 PATCHER_MONITORENTER;
1255 /* resolve native function */
1257 if (!(f = native_resolve_function(m))) {
1258 PATCHER_MONITOREXIT;
1263 /* patch back original code */
1265 #if SIZEOF_VOID_P == 8
1266 *((u4 *) (ra + 0 * 4)) = mcode;
1267 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1269 *((u4 *) (ra + 0 * 4)) = mcode[0];
1270 *((u4 *) (ra + 1 * 4)) = mcode[1];
1273 /* synchronize instruction cache */
1275 cacheflush(ra, 2 * 4, ICACHE);
1277 /* patch native function pointer */
1279 *((ptrint *) (pv + disp)) = (ptrint) f;
1281 PATCHER_MARK_PATCHED_MONITOREXIT;
1285 #endif /* !defined(ENABLE_STATICVM) */
1289 * These are local overrides for various environment variables in Emacs.
1290 * Please do not remove this and leave it at the end of the file, where
1291 * Emacs will automagically detect them.
1292 * ---------------------------------------------------------------------
1295 * indent-tabs-mode: t
1299 * vim:noexpandtab:sw=4:ts=4: