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 3520 2005-10-28 17:50:55Z twisti $
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));
93 /* get the fieldinfo */
95 if (!(fi = resolve_field_eager(uf))) {
101 /* check if the field's class is initialized */
103 if (!fi->class->initialized) {
104 if (!initialize_class(fi->class)) {
111 /* patch back original code */
113 #if SIZEOF_VOID_P == 8
114 *((u4 *) (ra + 0 * 4)) = mcode;
115 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
117 *((u4 *) (ra + 0 * 4)) = mcode[0];
118 *((u4 *) (ra + 1 * 4)) = mcode[1];
121 /* synchronize instruction cache */
123 cacheflush(ra, 2 * 4, ICACHE);
125 /* patch the field value's address */
127 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
129 /* synchronize data cache */
131 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
133 PATCHER_MARK_PATCHED_MONITOREXIT;
139 /* patcher_get_putfield ********************************************************
143 <patched call position>
144 8ee90020 lw a5,32(s7)
146 *******************************************************************************/
148 bool patcher_get_putfield(u1 *sp)
151 java_objectheader *o;
152 #if SIZEOF_VOID_P == 8
157 unresolved_field *uf;
160 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
161 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
162 #if SIZEOF_VOID_P == 8
163 mcode = *((u8 *) (sp + 3 * 8));
165 mcode[0] = *((u4 *) (sp + 3 * 8));
166 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
168 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
170 PATCHER_MONITORENTER;
172 /* get the fieldinfo */
174 if (!(fi = resolve_field_eager(uf))) {
180 /* patch back original code */
182 #if SIZEOF_VOID_P == 8
183 *((u4 *) (ra + 0 * 4)) = mcode;
184 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
186 *((u4 *) (ra + 0 * 4)) = mcode[0];
187 *((u4 *) (ra + 1 * 4)) = mcode[1];
190 /* if we show disassembly, we have to skip the nop's */
192 if (opt_showdisassemble)
195 /* patch the field's offset */
197 #if SIZEOF_VOID_P == 4
198 if (fi->type == TYPE_LNG) {
199 # if WORDS_BIGENDIAN == 1
200 /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
201 *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
202 *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
204 /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
205 *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
206 *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
210 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
212 /* synchronize instruction cache */
214 if (opt_showdisassemble) {
215 #if SIZEOF_VOID_P == 4
216 if (fi->type == TYPE_LNG) {
217 cacheflush(ra - 2 * 4, 4 * 4, ICACHE);
220 cacheflush(ra - 2 * 4, 3 * 4, ICACHE);
222 cacheflush(ra, 2 * 4, ICACHE);
225 PATCHER_MARK_PATCHED_MONITOREXIT;
231 /* patcher_builtin_new *********************************************************
235 dfc4ff98 ld a0,-104(s8)
236 <patched call postition>
237 dfd9ff90 ld t9,-112(s8)
241 NOTICE: Only the displacement for the function address is passed,
242 but the address of the classinfo pointer is one below (above, in
243 addresses speaking). This is for sure.
245 *******************************************************************************/
247 bool patcher_builtin_new(u1 *sp)
250 java_objectheader *o;
251 #if SIZEOF_VOID_P == 8
256 constant_classref *cr;
261 /* get stuff from the stack */
263 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
264 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
265 #if SIZEOF_VOID_P == 8
266 mcode = *((u8 *) (sp + 3 * 8));
268 mcode[0] = *((u4 *) (sp + 3 * 8));
269 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
271 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
272 disp = *((s4 *) (sp + 1 * 8));
273 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
275 /* calculate and set the new return address */
278 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
280 PATCHER_MONITORENTER;
282 /* get the classinfo */
284 if (!(c = resolve_classref_eager_nonabstract(cr))) {
290 /* patch back original code */
292 #if SIZEOF_VOID_P == 8
293 *((u4 *) (ra + 1 * 4)) = mcode;
294 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
296 *((u4 *) (ra + 1 * 4)) = mcode[0];
297 *((u4 *) (ra + 2 * 4)) = mcode[1];
300 /* synchronize instruction cache */
302 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
304 /* patch the classinfo pointer */
306 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c;
308 /* patch new function address */
310 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_new;
312 /* synchronize data cache */
314 cacheflush(pv + disp, SIZEOF_VOID_P * 2, DCACHE);
316 PATCHER_MARK_PATCHED_MONITOREXIT;
322 /* patcher_builtin_newarray ****************************************************
326 dfc5ffa0 ld a1,-96(s8)
327 <patched call position>
328 dfd9ff98 ld t9,-104(s8)
332 NOTICE: Only the displacement for the function address is passed,
333 but the address of the classinfo pointer is one below (above, in
334 addresses speaking). This is for sure.
336 *******************************************************************************/
338 bool patcher_builtin_newarray(u1 *sp)
341 java_objectheader *o;
342 #if SIZEOF_VOID_P == 8
347 constant_classref *cr;
352 /* get stuff from the stack */
354 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
355 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
356 #if SIZEOF_VOID_P == 8
357 mcode = *((u8 *) (sp + 3 * 8));
359 mcode[0] = *((u4 *) (sp + 3 * 8));
360 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
362 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
363 disp = *((s4 *) (sp + 1 * 8));
364 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
366 /* calculate and set the new return address */
369 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
371 PATCHER_MONITORENTER;
373 /* get the classinfo */
375 if (!(c = resolve_classref_eager(cr))) {
381 /* patch back original code */
383 #if SIZEOF_VOID_P == 8
384 *((u4 *) (ra + 1 * 4)) = mcode;
385 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
387 *((u4 *) (ra + 1 * 4)) = mcode[0];
388 *((u4 *) (ra + 2 * 4)) = mcode[1];
391 /* synchronize instruction cache */
393 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
395 /* patch the class' vftbl pointer */
397 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
399 /* patch new function address */
401 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_newarray;
403 /* synchronize data cache */
405 cacheflush(pv + disp, SIZEOF_VOID_P * 2, DCACHE);
407 PATCHER_MARK_PATCHED_MONITOREXIT;
413 /* patcher_builtin_multianewarray **********************************************
417 <patched call position>
418 dfc5ff90 ld a1,-112(s8)
420 dfd9ff88 ld t9,-120(s8)
424 *******************************************************************************/
426 bool patcher_builtin_multianewarray(u1 *sp)
429 java_objectheader *o;
430 #if SIZEOF_VOID_P == 8
435 constant_classref *cr;
440 /* get stuff from the stack */
442 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
443 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
444 #if SIZEOF_VOID_P == 8
445 mcode = *((u8 *) (sp + 3 * 8));
447 mcode[0] = *((u4 *) (sp + 3 * 8));
448 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
450 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
451 disp = *((s4 *) (sp + 1 * 8));
452 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
454 PATCHER_MONITORENTER;
456 /* get the classinfo */
458 if (!(c = resolve_classref_eager(cr))) {
464 /* patch back original code */
466 #if SIZEOF_VOID_P == 8
467 *((u4 *) (ra + 0 * 4)) = mcode;
468 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
470 *((u4 *) (ra + 0 * 4)) = mcode[0];
471 *((u4 *) (ra + 1 * 4)) = mcode[1];
474 /* synchronize instruction cache */
476 cacheflush(ra, 2 * 4, ICACHE);
478 /* patch the class' vftbl pointer */
480 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
482 /* synchronize data cache */
484 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
486 PATCHER_MARK_PATCHED_MONITOREXIT;
492 /* patcher_builtin_arraycheckcast **********************************************
496 <patched call position>
497 dfc5ffc0 ld a1,-64(s8)
498 dfd9ffb8 ld t9,-72(s8)
502 NOTICE: Only the displacement of the vftbl pointer address is
503 passed, but the address of the function pointer is one above
504 (below, in addresses speaking). This is for sure.
506 *******************************************************************************/
508 bool patcher_builtin_arraycheckcast(u1 *sp)
511 java_objectheader *o;
512 #if SIZEOF_VOID_P == 8
517 constant_classref *cr;
522 /* get stuff from the stack */
524 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
525 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
526 #if SIZEOF_VOID_P == 8
527 mcode = *((u8 *) (sp + 3 * 8));
529 mcode[0] = *((u4 *) (sp + 3 * 8));
530 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
532 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
533 disp = *((s4 *) (sp + 1 * 8));
534 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
536 PATCHER_MONITORENTER;
538 /* get the classinfo */
540 if (!(c = resolve_classref_eager(cr))) {
546 /* patch back original code */
548 #if SIZEOF_VOID_P == 8
549 *((u4 *) (ra + 0 * 4)) = mcode;
550 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
552 *((u4 *) (ra + 0 * 4)) = mcode[0];
553 *((u4 *) (ra + 1 * 4)) = mcode[1];
556 /* synchronize instruction cache */
558 cacheflush(ra, 2 * 4, ICACHE);
560 /* patch the class' vftbl pointer */
562 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
564 /* patch new function address */
566 *((ptrint *) (pv + (disp - SIZEOF_VOID_P))) =
567 (ptrint) BUILTIN_arraycheckcast;
569 /* synchronize data cache */
571 cacheflush(pv + disp - SIZEOF_VOID_P, SIZEOF_VOID_P * 2, DCACHE);
573 PATCHER_MARK_PATCHED_MONITOREXIT;
579 /* patcher_builtin_arrayinstanceof *********************************************
583 dfc5fe98 ld a1,-360(s8)
584 <patched call position>
585 dfd9fe90 ld t9,-368(s8)
589 NOTICE: Only the displacement for the function address is passed,
590 but the address of the vftbl pointer is one below (above, in
591 addresses speaking). This is for sure.
593 *******************************************************************************/
595 bool patcher_builtin_arrayinstanceof(u1 *sp)
598 java_objectheader *o;
599 #if SIZEOF_VOID_P == 8
604 constant_classref *cr;
609 /* get stuff from the stack */
611 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
612 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
613 #if SIZEOF_VOID_P == 8
614 mcode = *((u8 *) (sp + 3 * 8));
616 mcode[0] = *((u4 *) (sp + 3 * 8));
617 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
619 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
620 disp = *((s4 *) (sp + 1 * 8));
621 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
623 /* calculate and set the new return address */
626 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
628 PATCHER_MONITORENTER;
630 /* get the classinfo */
632 if (!(c = resolve_classref_eager(cr))) {
638 /* patch back original code */
640 #if SIZEOF_VOID_P == 8
641 *((u4 *) (ra + 1 * 4)) = mcode;
642 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
644 *((u4 *) (ra + 1 * 4)) = mcode[0];
645 *((u4 *) (ra + 2 * 4)) = mcode[1];
648 /* synchronize instruction cache */
650 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
652 /* patch the class' vftbl pointer */
654 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
656 /* patch new function address */
658 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_arrayinstanceof;
660 /* synchronize data cache */
662 cacheflush(pv + disp, SIZEOF_VOID_P * 2, DCACHE);
664 PATCHER_MARK_PATCHED_MONITOREXIT;
670 /* patcher_invokestatic_special ************************************************
674 <patched call position>
675 dfdeffc0 ld s8,-64(s8)
679 ******************************************************************************/
681 bool patcher_invokestatic_special(u1 *sp)
684 java_objectheader *o;
685 #if SIZEOF_VOID_P == 8
690 unresolved_method *um;
695 /* get stuff from the stack */
697 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
698 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
699 #if SIZEOF_VOID_P == 8
700 mcode = *((u8 *) (sp + 3 * 8));
702 mcode[0] = *((u4 *) (sp + 3 * 8));
703 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
705 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
706 disp = *((s4 *) (sp + 1 * 8));
707 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
709 PATCHER_MONITORENTER;
711 /* get the fieldinfo */
713 if (!(m = resolve_method_eager(um))) {
719 /* patch back original code */
721 #if SIZEOF_VOID_P == 8
722 *((u4 *) (ra + 0 * 4)) = mcode;
723 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
725 *((u4 *) (ra + 0 * 4)) = mcode[0];
726 *((u4 *) (ra + 1 * 4)) = mcode[1];
729 /* synchronize instruction cache */
731 cacheflush(ra, 2 * 4, ICACHE);
733 /* patch stubroutine */
735 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
737 /* synchronize data cache */
739 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
741 PATCHER_MARK_PATCHED_MONITOREXIT;
747 /* patcher_invokevirtual *******************************************************
751 <patched call position>
753 df3e0040 ld s8,64(t9)
757 *******************************************************************************/
759 bool patcher_invokevirtual(u1 *sp)
762 java_objectheader *o;
763 #if SIZEOF_VOID_P == 8
768 unresolved_method *um;
771 /* get stuff from the stack */
773 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
774 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
775 #if SIZEOF_VOID_P == 8
776 mcode = *((u8 *) (sp + 3 * 8));
778 mcode[0] = *((u4 *) (sp + 3 * 8));
779 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
781 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
783 PATCHER_MONITORENTER;
785 /* get the fieldinfo */
787 if (!(m = resolve_method_eager(um))) {
793 /* patch back original code */
795 #if SIZEOF_VOID_P == 8
796 *((u4 *) (ra + 0 * 4)) = mcode;
797 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
799 *((u4 *) (ra + 0 * 4)) = mcode[0];
800 *((u4 *) (ra + 1 * 4)) = mcode[1];
803 /* if we show disassembly, we have to skip the nop's */
805 if (opt_showdisassemble)
808 /* patch vftbl index */
810 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
811 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
813 /* synchronize instruction cache */
815 if (opt_showdisassemble)
816 cacheflush(ra - 2 * 4, 4 * 4, ICACHE);
818 cacheflush(ra, 2 * 4, ICACHE);
820 PATCHER_MARK_PATCHED_MONITOREXIT;
826 /* patcher_invokeinterface *****************************************************
830 <patched call position>
832 df39ffa0 ld t9,-96(t9)
833 df3e0018 ld s8,24(t9)
837 *******************************************************************************/
839 bool patcher_invokeinterface(u1 *sp)
842 java_objectheader *o;
843 #if SIZEOF_VOID_P == 8
848 unresolved_method *um;
851 /* get stuff from the stack */
853 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
854 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
855 #if SIZEOF_VOID_P == 8
856 mcode = *((u8 *) (sp + 3 * 8));
858 mcode[0] = *((u4 *) (sp + 3 * 8));
859 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
861 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
863 PATCHER_MONITORENTER;
865 /* get the fieldinfo */
867 if (!(m = resolve_method_eager(um))) {
873 /* patch back original code */
875 #if SIZEOF_VOID_P == 8
876 *((u4 *) (ra + 0 * 4)) = mcode;
877 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
879 *((u4 *) (ra + 0 * 4)) = mcode[0];
880 *((u4 *) (ra + 1 * 4)) = mcode[1];
883 /* if we show disassembly, we have to skip the nop's */
885 if (opt_showdisassemble)
888 /* patch interfacetable index */
890 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
891 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
893 /* patch method offset */
895 *((s4 *) (ra + 2 * 4)) |=
896 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
898 /* synchronize instruction cache */
900 if (opt_showdisassemble)
901 cacheflush(ra - 2 * 4, 5 * 4, ICACHE);
903 cacheflush(ra, 3 * 4, ICACHE);
905 PATCHER_MARK_PATCHED_MONITOREXIT;
911 /* patcher_checkcast_instanceof_flags ******************************************
915 <patched call position>
916 8fc3ff24 lw v1,-220(s8)
917 30630200 andi v1,v1,512
918 1060000d beq v1,zero,0x000000001051824c
921 *******************************************************************************/
923 bool patcher_checkcast_instanceof_flags(u1 *sp)
926 java_objectheader *o;
927 #if SIZEOF_VOID_P == 8
932 constant_classref *cr;
937 /* get stuff from the stack */
939 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
940 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
941 #if SIZEOF_VOID_P == 8
942 mcode = *((u8 *) (sp + 3 * 8));
944 mcode[0] = *((u4 *) (sp + 3 * 8));
945 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
947 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
948 disp = *((s4 *) (sp + 1 * 8));
949 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
951 PATCHER_MONITORENTER;
953 /* get the fieldinfo */
955 if (!(c = resolve_classref_eager(cr))) {
961 /* patch back original code */
963 #if SIZEOF_VOID_P == 8
964 *((u4 *) (ra + 0 * 4)) = mcode;
965 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
967 *((u4 *) (ra + 0 * 4)) = mcode[0];
968 *((u4 *) (ra + 1 * 4)) = mcode[1];
971 /* synchronize instruction cache */
973 cacheflush(ra, 2 * 4, ICACHE);
975 /* patch class flags */
977 *((s4 *) (pv + disp)) = (s4) c->flags;
979 /* synchronize data cache */
981 cacheflush(pv + disp, sizeof(s4), DCACHE);
983 PATCHER_MARK_PATCHED_MONITOREXIT;
989 /* patcher_checkcast_instanceof_interface **************************************
993 <patched call position>
995 8c79001c lw t9,28(v1)
996 27390000 addiu t9,t9,0
997 1b200082 blez t9,zero,0x000000001051843c
1001 *******************************************************************************/
1003 bool patcher_checkcast_instanceof_interface(u1 *sp)
1006 java_objectheader *o;
1007 #if SIZEOF_VOID_P == 8
1012 constant_classref *cr;
1015 /* get stuff from the stack */
1017 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1018 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1019 #if SIZEOF_VOID_P == 8
1020 mcode = *((u8 *) (sp + 3 * 8));
1022 mcode[0] = *((u4 *) (sp + 3 * 8));
1023 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1025 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
1027 PATCHER_MONITORENTER;
1029 /* get the fieldinfo */
1031 if (!(c = resolve_classref_eager(cr))) {
1032 PATCHER_MONITOREXIT;
1037 /* patch back original code */
1039 #if SIZEOF_VOID_P == 8
1040 *((u4 *) (ra + 0 * 4)) = mcode;
1041 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1043 *((u4 *) (ra + 0 * 4)) = mcode[0];
1044 *((u4 *) (ra + 1 * 4)) = mcode[1];
1047 /* if we show disassembly, we have to skip the nop's */
1049 if (opt_showdisassemble)
1052 /* patch super class index */
1054 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
1056 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
1057 c->index * sizeof(methodptr*)) & 0x0000ffff);
1059 /* synchronize instruction cache */
1061 if (opt_showdisassemble)
1062 cacheflush(ra - 2 * 4, 8 * 4, ICACHE);
1064 cacheflush(ra, 6 * 4, ICACHE);
1066 PATCHER_MARK_PATCHED_MONITOREXIT;
1072 /* patcher_checkcast_instanceof_class ******************************************
1076 <patched call position>
1077 dd030000 ld v1,0(a4)
1078 dfd9ff18 ld t9,-232(s8)
1080 *******************************************************************************/
1082 bool patcher_checkcast_instanceof_class(u1 *sp)
1085 java_objectheader *o;
1086 #if SIZEOF_VOID_P == 8
1091 constant_classref *cr;
1096 /* get stuff from the stack */
1098 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1099 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1100 #if SIZEOF_VOID_P == 8
1101 mcode = *((u8 *) (sp + 3 * 8));
1103 mcode[0] = *((u4 *) (sp + 3 * 8));
1104 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1106 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
1107 disp = *((s4 *) (sp + 1 * 8));
1108 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1110 PATCHER_MONITORENTER;
1112 /* get the fieldinfo */
1114 if (!(c = resolve_classref_eager(cr))) {
1115 PATCHER_MONITOREXIT;
1120 /* patch back original code */
1122 #if SIZEOF_VOID_P == 8
1123 *((u4 *) (ra + 0 * 4)) = mcode;
1124 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1126 *((u4 *) (ra + 0 * 4)) = mcode[0];
1127 *((u4 *) (ra + 1 * 4)) = mcode[1];
1130 /* synchronize instruction cache */
1132 cacheflush(ra, 2 * 4, ICACHE);
1134 /* patch super class' vftbl */
1136 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
1138 /* synchronize data cache */
1140 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
1142 PATCHER_MARK_PATCHED_MONITOREXIT;
1148 /* patcher_clinit **************************************************************
1150 No special machine code.
1152 *******************************************************************************/
1154 bool patcher_clinit(u1 *sp)
1157 java_objectheader *o;
1158 #if SIZEOF_VOID_P == 8
1165 /* get stuff from the stack */
1167 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1168 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1169 #if SIZEOF_VOID_P == 8
1170 mcode = *((u8 *) (sp + 3 * 8));
1172 mcode[0] = *((u4 *) (sp + 3 * 8));
1173 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1175 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
1177 PATCHER_MONITORENTER;
1179 /* check if the class is initialized */
1181 if (!c->initialized) {
1182 if (!initialize_class(c)) {
1183 PATCHER_MONITOREXIT;
1189 /* patch back original code */
1191 #if SIZEOF_VOID_P == 8
1192 *((u4 *) (ra + 0 * 4)) = mcode;
1193 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1195 *((u4 *) (ra + 0 * 4)) = mcode[0];
1196 *((u4 *) (ra + 1 * 4)) = mcode[1];
1199 /* synchronize instruction cache */
1201 cacheflush(ra, 2 * 4, ICACHE);
1203 PATCHER_MARK_PATCHED_MONITOREXIT;
1209 /* patcher_athrow_areturn ******************************************************
1213 <patched call position>
1215 *******************************************************************************/
1217 bool patcher_athrow_areturn(u1 *sp)
1220 java_objectheader *o;
1221 #if SIZEOF_VOID_P == 8
1226 unresolved_class *uc;
1229 /* get stuff from the stack */
1231 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1232 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1233 #if SIZEOF_VOID_P == 8
1234 mcode = *((u8 *) (sp + 3 * 8));
1236 mcode[0] = *((u4 *) (sp + 3 * 8));
1237 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1239 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
1241 PATCHER_MONITORENTER;
1243 /* resolve the class */
1245 if (!resolve_class(uc, resolveEager, false, &c)) {
1246 PATCHER_MONITOREXIT;
1251 /* patch back original code */
1253 #if SIZEOF_VOID_P == 8
1254 *((u4 *) (ra + 0 * 4)) = mcode;
1255 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1257 *((u4 *) (ra + 0 * 4)) = mcode[0];
1258 *((u4 *) (ra + 1 * 4)) = mcode[1];
1261 /* synchronize instruction cache */
1263 cacheflush(ra, 2 * 4, ICACHE);
1265 PATCHER_MARK_PATCHED_MONITOREXIT;
1271 /* patcher_resolve_native ******************************************************
1275 *******************************************************************************/
1277 #if !defined(ENABLE_STATICVM)
1278 bool patcher_resolve_native(u1 *sp)
1281 java_objectheader *o;
1282 #if SIZEOF_VOID_P == 8
1292 /* get stuff from the stack */
1294 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1295 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1296 #if SIZEOF_VOID_P == 8
1297 mcode = *((u8 *) (sp + 3 * 8));
1299 mcode[0] = *((u4 *) (sp + 3 * 8));
1300 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1302 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1303 disp = *((s4 *) (sp + 1 * 8));
1304 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1306 /* calculate and set the new return address */
1309 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1311 PATCHER_MONITORENTER;
1313 /* resolve native function */
1315 if (!(f = native_resolve_function(m))) {
1316 PATCHER_MONITOREXIT;
1321 /* patch back original code */
1323 #if SIZEOF_VOID_P == 8
1324 *((u4 *) (ra + 0 * 4)) = mcode;
1325 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1327 *((u4 *) (ra + 0 * 4)) = mcode[0];
1328 *((u4 *) (ra + 1 * 4)) = mcode[1];
1331 /* synchronize instruction cache */
1333 cacheflush(ra, 2 * 4, ICACHE);
1335 /* patch native function pointer */
1337 *((ptrint *) (pv + disp)) = (ptrint) f;
1339 /* synchronize data cache */
1341 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
1343 PATCHER_MARK_PATCHED_MONITOREXIT;
1347 #endif /* !defined(ENABLE_STATICVM) */
1351 * These are local overrides for various environment variables in Emacs.
1352 * Please do not remove this and leave it at the end of the file, where
1353 * Emacs will automagically detect them.
1354 * ---------------------------------------------------------------------
1357 * indent-tabs-mode: t
1361 * vim:noexpandtab:sw=4:ts=4: