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 3463 2005-10-20 10:07:16Z 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/references.h"
48 #include "vm/jit/asmpart.h"
49 #include "vm/jit/patcher.h"
52 /* patcher_get_putstatic *******************************************************
56 <patched call position>
57 dfc1ffb8 ld at,-72(s8)
60 *******************************************************************************/
62 bool patcher_get_putstatic(u1 *sp)
66 #if SIZEOF_VOID_P == 8
76 /* get stuff from the stack */
78 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
79 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
80 #if SIZEOF_VOID_P == 8
81 mcode = *((u8 *) (sp + 3 * 8));
83 mcode[0] = *((u4 *) (sp + 3 * 8));
84 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
86 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
87 disp = *((s4 *) (sp + 1 * 8));
88 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
90 /* calculate and set the new return address */
93 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
97 /* get the fieldinfo */
99 if (!(fi = resolve_field_eager(uf))) {
105 /* check if the field's class is initialized */
107 if (!fi->class->initialized) {
108 if (!initialize_class(fi->class)) {
115 /* patch back original code */
117 #if SIZEOF_VOID_P == 8
118 *((u4 *) (ra + 0 * 4)) = mcode;
119 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
121 *((u4 *) (ra + 0 * 4)) = mcode[0];
122 *((u4 *) (ra + 1 * 4)) = mcode[1];
125 /* synchronize instruction cache */
127 cacheflush(ra, 2 * 4, ICACHE);
129 /* patch the field value's address */
131 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
133 /* synchronize data cache */
135 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
137 PATCHER_MARK_PATCHED_MONITOREXIT;
143 /* patcher_get_putfield ********************************************************
147 <patched call position>
148 8ee90020 lw a5,32(s7)
150 *******************************************************************************/
152 bool patcher_get_putfield(u1 *sp)
155 java_objectheader *o;
156 #if SIZEOF_VOID_P == 8
161 unresolved_field *uf;
164 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
165 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
166 #if SIZEOF_VOID_P == 8
167 mcode = *((u8 *) (sp + 3 * 8));
169 mcode[0] = *((u4 *) (sp + 3 * 8));
170 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
172 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
174 /* calculate and set the new return address */
177 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
179 PATCHER_MONITORENTER;
181 /* get the fieldinfo */
183 if (!(fi = resolve_field_eager(uf))) {
189 /* patch back original code */
191 #if SIZEOF_VOID_P == 8
192 *((u4 *) (ra + 0 * 4)) = mcode;
193 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
195 *((u4 *) (ra + 0 * 4)) = mcode[0];
196 *((u4 *) (ra + 1 * 4)) = mcode[1];
199 /* if we show disassembly, we have to skip the nop's */
201 if (opt_showdisassemble)
204 /* patch the field's offset */
206 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
208 /* synchronize instruction cache */
210 if (opt_showdisassemble)
211 cacheflush(ra - 2 * 4, 3 * 4, ICACHE);
213 cacheflush(ra, 2 * 4, ICACHE);
215 PATCHER_MARK_PATCHED_MONITOREXIT;
221 /* patcher_builtin_new *********************************************************
225 dfc4ff98 ld a0,-104(s8)
226 <patched call postition>
227 dfd9ff90 ld t9,-112(s8)
231 NOTICE: Only the displacement for the function address is passed,
232 but the address of the classinfo pointer is one below (above, in
233 addresses speaking). This is for sure.
235 *******************************************************************************/
237 bool patcher_builtin_new(u1 *sp)
240 java_objectheader *o;
241 #if SIZEOF_VOID_P == 8
246 constant_classref *cr;
251 /* get stuff from the stack */
253 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
254 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
255 #if SIZEOF_VOID_P == 8
256 mcode = *((u8 *) (sp + 3 * 8));
258 mcode[0] = *((u4 *) (sp + 3 * 8));
259 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
261 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
262 disp = *((s4 *) (sp + 1 * 8));
263 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
265 /* calculate and set the new return address */
268 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
270 PATCHER_MONITORENTER;
272 /* get the classinfo */
274 if (!(c = resolve_classref_eager_nonabstract(cr))) {
280 /* patch back original code */
282 #if SIZEOF_VOID_P == 8
283 *((u4 *) (ra + 1 * 4)) = mcode;
284 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
286 *((u4 *) (ra + 1 * 4)) = mcode[0];
287 *((u4 *) (ra + 2 * 4)) = mcode[1];
290 /* synchronize instruction cache */
292 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
294 /* patch the classinfo pointer */
296 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c;
298 /* patch new function address */
300 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_new;
302 PATCHER_MARK_PATCHED_MONITOREXIT;
308 /* patcher_builtin_newarray ****************************************************
312 dfc5ffa0 ld a1,-96(s8)
313 <patched call position>
314 dfd9ff98 ld t9,-104(s8)
318 NOTICE: Only the displacement for the function address is passed,
319 but the address of the classinfo pointer is one below (above, in
320 addresses speaking). This is for sure.
322 *******************************************************************************/
324 bool patcher_builtin_newarray(u1 *sp)
327 java_objectheader *o;
328 #if SIZEOF_VOID_P == 8
333 constant_classref *cr;
338 /* get stuff from the stack */
340 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
341 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
342 #if SIZEOF_VOID_P == 8
343 mcode = *((u8 *) (sp + 3 * 8));
345 mcode[0] = *((u4 *) (sp + 3 * 8));
346 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
348 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
349 disp = *((s4 *) (sp + 1 * 8));
350 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
352 /* calculate and set the new return address */
355 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
357 PATCHER_MONITORENTER;
359 /* get the classinfo */
361 if (!(c = resolve_classref_eager(cr))) {
367 /* patch back original code */
369 #if SIZEOF_VOID_P == 8
370 *((u4 *) (ra + 1 * 4)) = mcode;
371 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
373 *((u4 *) (ra + 1 * 4)) = mcode[0];
374 *((u4 *) (ra + 2 * 4)) = mcode[1];
377 /* synchronize instruction cache */
379 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
381 /* patch the class' vftbl pointer */
383 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
385 /* patch new function address */
387 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_newarray;
389 PATCHER_MARK_PATCHED_MONITOREXIT;
395 /* patcher_builtin_multianewarray **********************************************
399 <patched call position>
400 dfc5ff90 ld a1,-112(s8)
402 dfd9ff88 ld t9,-120(s8)
406 *******************************************************************************/
408 bool patcher_builtin_multianewarray(u1 *sp)
411 java_objectheader *o;
412 #if SIZEOF_VOID_P == 8
417 constant_classref *cr;
422 /* get stuff from the stack */
424 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
425 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
426 #if SIZEOF_VOID_P == 8
427 mcode = *((u8 *) (sp + 3 * 8));
429 mcode[0] = *((u4 *) (sp + 3 * 8));
430 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
432 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
433 disp = *((s4 *) (sp + 1 * 8));
434 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
436 /* calculate and set the new return address */
439 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
441 PATCHER_MONITORENTER;
443 /* get the classinfo */
445 if (!(c = resolve_classref_eager(cr))) {
451 /* patch back original code */
453 #if SIZEOF_VOID_P == 8
454 *((u4 *) (ra + 0 * 4)) = mcode;
455 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
457 *((u4 *) (ra + 0 * 4)) = mcode[0];
458 *((u4 *) (ra + 1 * 4)) = mcode[1];
461 /* synchronize instruction cache */
463 cacheflush(ra, 2 * 4, ICACHE);
465 /* patch the class' vftbl pointer */
467 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
469 PATCHER_MARK_PATCHED_MONITOREXIT;
475 /* patcher_builtin_arraycheckcast **********************************************
479 <patched call position>
480 dfc5ffc0 ld a1,-64(s8)
481 dfd9ffb8 ld t9,-72(s8)
485 NOTICE: Only the displacement of the vftbl pointer address is
486 passed, but the address of the function pointer is one above
487 (below, in addresses speaking). This is for sure.
489 *******************************************************************************/
491 bool patcher_builtin_arraycheckcast(u1 *sp)
494 java_objectheader *o;
495 #if SIZEOF_VOID_P == 8
500 constant_classref *cr;
505 /* get stuff from the stack */
507 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
508 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
509 #if SIZEOF_VOID_P == 8
510 mcode = *((u8 *) (sp + 3 * 8));
512 mcode[0] = *((u4 *) (sp + 3 * 8));
513 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
515 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
516 disp = *((s4 *) (sp + 1 * 8));
517 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
519 /* calculate and set the new return address */
522 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
524 PATCHER_MONITORENTER;
526 /* get the classinfo */
528 if (!(c = resolve_classref_eager(cr))) {
534 /* patch back original code */
536 #if SIZEOF_VOID_P == 8
537 *((u4 *) (ra + 0 * 4)) = mcode;
538 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
540 *((u4 *) (ra + 0 * 4)) = mcode[0];
541 *((u4 *) (ra + 1 * 4)) = mcode[1];
544 /* synchronize instruction cache */
546 cacheflush(ra, 2 * 4, ICACHE);
548 /* patch the class' vftbl pointer */
550 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
552 /* patch new function address */
554 *((ptrint *) (pv + (disp - SIZEOF_VOID_P))) =
555 (ptrint) BUILTIN_arraycheckcast;
557 PATCHER_MARK_PATCHED_MONITOREXIT;
563 /* patcher_builtin_arrayinstanceof *********************************************
567 dfc5fe98 ld a1,-360(s8)
568 <patched call position>
569 dfd9fe90 ld t9,-368(s8)
573 NOTICE: Only the displacement for the function address is passed,
574 but the address of the vftbl pointer is one below (above, in
575 addresses speaking). This is for sure.
577 *******************************************************************************/
579 bool patcher_builtin_arrayinstanceof(u1 *sp)
582 java_objectheader *o;
583 #if SIZEOF_VOID_P == 8
588 constant_classref *cr;
593 /* get stuff from the stack */
595 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
596 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
597 #if SIZEOF_VOID_P == 8
598 mcode = *((u8 *) (sp + 3 * 8));
600 mcode[0] = *((u4 *) (sp + 3 * 8));
601 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
603 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
604 disp = *((s4 *) (sp + 1 * 8));
605 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
607 /* calculate and set the new return address */
610 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
612 PATCHER_MONITORENTER;
614 /* get the classinfo */
616 if (!(c = resolve_classref_eager(cr))) {
622 /* patch back original code */
624 #if SIZEOF_VOID_P == 8
625 *((u4 *) (ra + 1 * 4)) = mcode;
626 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
628 *((u4 *) (ra + 1 * 4)) = mcode[0];
629 *((u4 *) (ra + 2 * 4)) = mcode[1];
632 /* synchronize instruction cache */
634 cacheflush(ra + 1 * 4, 2 * 4, ICACHE);
636 /* patch the class' vftbl pointer */
638 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
640 /* patch new function address */
642 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_arrayinstanceof;
644 PATCHER_MARK_PATCHED_MONITOREXIT;
650 /* patcher_invokestatic_special ************************************************
654 <patched call position>
655 dfdeffc0 ld s8,-64(s8)
659 ******************************************************************************/
661 bool patcher_invokestatic_special(u1 *sp)
664 java_objectheader *o;
665 #if SIZEOF_VOID_P == 8
670 unresolved_method *um;
675 /* get stuff from the stack */
677 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
678 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
679 #if SIZEOF_VOID_P == 8
680 mcode = *((u8 *) (sp + 3 * 8));
682 mcode[0] = *((u4 *) (sp + 3 * 8));
683 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
685 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
686 disp = *((s4 *) (sp + 1 * 8));
687 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
689 /* calculate and set the new return address */
692 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
694 PATCHER_MONITORENTER;
696 /* get the fieldinfo */
698 if (!(m = resolve_method_eager(um))) {
704 /* patch back original code */
706 #if SIZEOF_VOID_P == 8
707 *((u4 *) (ra + 0 * 4)) = mcode;
708 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
710 *((u4 *) (ra + 0 * 4)) = mcode[0];
711 *((u4 *) (ra + 1 * 4)) = mcode[1];
714 /* synchronize instruction cache */
716 cacheflush(ra, 2 * 4, ICACHE);
718 /* patch stubroutine */
720 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
722 PATCHER_MARK_PATCHED_MONITOREXIT;
728 /* patcher_invokevirtual *******************************************************
732 <patched call position>
734 df3e0040 ld s8,64(t9)
738 *******************************************************************************/
740 bool patcher_invokevirtual(u1 *sp)
743 java_objectheader *o;
744 #if SIZEOF_VOID_P == 8
749 unresolved_method *um;
752 /* get stuff from the stack */
754 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
755 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
756 #if SIZEOF_VOID_P == 8
757 mcode = *((u8 *) (sp + 3 * 8));
759 mcode[0] = *((u4 *) (sp + 3 * 8));
760 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
762 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
764 /* calculate and set the new return address */
767 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
769 PATCHER_MONITORENTER;
771 /* get the fieldinfo */
773 if (!(m = resolve_method_eager(um))) {
779 /* patch back original code */
781 #if SIZEOF_VOID_P == 8
782 *((u4 *) (ra + 0 * 4)) = mcode;
783 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
785 *((u4 *) (ra + 0 * 4)) = mcode[0];
786 *((u4 *) (ra + 1 * 4)) = mcode[1];
789 /* if we show disassembly, we have to skip the nop's */
791 if (opt_showdisassemble)
794 /* patch vftbl index */
796 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
797 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
799 /* synchronize instruction cache */
801 if (opt_showdisassemble)
802 cacheflush(ra - 2 * 4, 4 * 4, ICACHE);
804 cacheflush(ra, 2 * 4, ICACHE);
806 PATCHER_MARK_PATCHED_MONITOREXIT;
812 /* patcher_invokeinterface *****************************************************
816 <patched call position>
818 df39ffa0 ld t9,-96(t9)
819 df3e0018 ld s8,24(t9)
823 *******************************************************************************/
825 bool patcher_invokeinterface(u1 *sp)
828 java_objectheader *o;
829 #if SIZEOF_VOID_P == 8
834 unresolved_method *um;
837 /* get stuff from the stack */
839 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
840 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
841 #if SIZEOF_VOID_P == 8
842 mcode = *((u8 *) (sp + 3 * 8));
844 mcode[0] = *((u4 *) (sp + 3 * 8));
845 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
847 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
849 /* calculate and set the new return address */
852 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
854 PATCHER_MONITORENTER;
856 /* get the fieldinfo */
858 if (!(m = resolve_method_eager(um))) {
864 /* patch back original code */
866 #if SIZEOF_VOID_P == 8
867 *((u4 *) (ra + 0 * 4)) = mcode;
868 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
870 *((u4 *) (ra + 0 * 4)) = mcode[0];
871 *((u4 *) (ra + 1 * 4)) = mcode[1];
874 /* if we show disassembly, we have to skip the nop's */
876 if (opt_showdisassemble)
879 /* patch interfacetable index */
881 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
882 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
884 /* patch method offset */
886 *((s4 *) (ra + 2 * 4)) |=
887 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
889 /* synchronize instruction cache */
891 if (opt_showdisassemble)
892 cacheflush(ra - 2 * 4, 5 * 4, ICACHE);
894 cacheflush(ra, 3 * 4, ICACHE);
896 PATCHER_MARK_PATCHED_MONITOREXIT;
902 /* patcher_checkcast_instanceof_flags ******************************************
906 <patched call position>
907 8fc3ff24 lw v1,-220(s8)
908 30630200 andi v1,v1,512
909 1060000d beq v1,zero,0x000000001051824c
912 *******************************************************************************/
914 bool patcher_checkcast_instanceof_flags(u1 *sp)
917 java_objectheader *o;
918 #if SIZEOF_VOID_P == 8
923 constant_classref *cr;
928 /* get stuff from the stack */
930 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
931 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
932 #if SIZEOF_VOID_P == 8
933 mcode = *((u8 *) (sp + 3 * 8));
935 mcode[0] = *((u4 *) (sp + 3 * 8));
936 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
938 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
939 disp = *((s4 *) (sp + 1 * 8));
940 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
942 /* calculate and set the new return address */
945 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
947 PATCHER_MONITORENTER;
949 /* get the fieldinfo */
951 if (!(c = resolve_classref_eager(cr))) {
957 /* patch back original code */
959 #if SIZEOF_VOID_P == 8
960 *((u4 *) (ra + 0 * 4)) = mcode;
961 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
963 *((u4 *) (ra + 0 * 4)) = mcode[0];
964 *((u4 *) (ra + 1 * 4)) = mcode[1];
967 /* synchronize instruction cache */
969 cacheflush(ra, 2 * 4, ICACHE);
971 /* patch class flags */
973 *((s4 *) (pv + disp)) = (s4) c->flags;
975 PATCHER_MARK_PATCHED_MONITOREXIT;
981 /* patcher_checkcast_instanceof_interface **************************************
985 <patched call position>
987 8c79001c lw t9,28(v1)
988 27390000 addiu t9,t9,0
989 1b200082 blez t9,zero,0x000000001051843c
993 *******************************************************************************/
995 bool patcher_checkcast_instanceof_interface(u1 *sp)
998 java_objectheader *o;
999 #if SIZEOF_VOID_P == 8
1004 constant_classref *cr;
1007 /* get stuff from the stack */
1009 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1010 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1011 #if SIZEOF_VOID_P == 8
1012 mcode = *((u8 *) (sp + 3 * 8));
1014 mcode[0] = *((u4 *) (sp + 3 * 8));
1015 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1017 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
1019 /* calculate and set the new return address */
1022 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1024 PATCHER_MONITORENTER;
1026 /* get the fieldinfo */
1028 if (!(c = resolve_classref_eager(cr))) {
1029 PATCHER_MONITOREXIT;
1034 /* patch back original code */
1036 #if SIZEOF_VOID_P == 8
1037 *((u4 *) (ra + 0 * 4)) = mcode;
1038 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1040 *((u4 *) (ra + 0 * 4)) = mcode[0];
1041 *((u4 *) (ra + 1 * 4)) = mcode[1];
1044 /* if we show disassembly, we have to skip the nop's */
1046 if (opt_showdisassemble)
1049 /* patch super class index */
1051 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
1053 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
1054 c->index * sizeof(methodptr*)) & 0x0000ffff);
1056 /* synchronize instruction cache */
1058 if (opt_showdisassemble)
1059 cacheflush(ra - 2 * 4, 8 * 4, ICACHE);
1061 cacheflush(ra, 6 * 4, ICACHE);
1063 PATCHER_MARK_PATCHED_MONITOREXIT;
1069 /* patcher_checkcast_instanceof_class ******************************************
1073 <patched call position>
1074 dd030000 ld v1,0(a4)
1075 dfd9ff18 ld t9,-232(s8)
1077 *******************************************************************************/
1079 bool patcher_checkcast_instanceof_class(u1 *sp)
1082 java_objectheader *o;
1083 #if SIZEOF_VOID_P == 8
1088 constant_classref *cr;
1093 /* get stuff from the stack */
1095 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1096 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1097 #if SIZEOF_VOID_P == 8
1098 mcode = *((u8 *) (sp + 3 * 8));
1100 mcode[0] = *((u4 *) (sp + 3 * 8));
1101 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1103 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
1104 disp = *((s4 *) (sp + 1 * 8));
1105 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1107 /* calculate and set the new return address */
1110 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1112 PATCHER_MONITORENTER;
1114 /* get the fieldinfo */
1116 if (!(c = resolve_classref_eager(cr))) {
1117 PATCHER_MONITOREXIT;
1122 /* patch back original code */
1124 #if SIZEOF_VOID_P == 8
1125 *((u4 *) (ra + 0 * 4)) = mcode;
1126 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1128 *((u4 *) (ra + 0 * 4)) = mcode[0];
1129 *((u4 *) (ra + 1 * 4)) = mcode[1];
1132 /* synchronize instruction cache */
1134 cacheflush(ra, 2 * 4, ICACHE);
1136 /* patch super class' vftbl */
1138 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
1140 PATCHER_MARK_PATCHED_MONITOREXIT;
1146 /* patcher_clinit **************************************************************
1148 No special machine code.
1150 *******************************************************************************/
1152 bool patcher_clinit(u1 *sp)
1155 java_objectheader *o;
1156 #if SIZEOF_VOID_P == 8
1163 /* get stuff from the stack */
1165 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1166 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1167 #if SIZEOF_VOID_P == 8
1168 mcode = *((u8 *) (sp + 3 * 8));
1170 mcode[0] = *((u4 *) (sp + 3 * 8));
1171 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1173 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
1175 /* calculate and set the new return address */
1178 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1180 PATCHER_MONITORENTER;
1182 /* check if the class is initialized */
1184 if (!c->initialized) {
1185 if (!initialize_class(c)) {
1186 PATCHER_MONITOREXIT;
1192 /* patch back original code */
1194 #if SIZEOF_VOID_P == 8
1195 *((u4 *) (ra + 0 * 4)) = mcode;
1196 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1198 *((u4 *) (ra + 0 * 4)) = mcode[0];
1199 *((u4 *) (ra + 1 * 4)) = mcode[1];
1202 /* synchronize instruction cache */
1204 cacheflush(ra, 2 * 4, ICACHE);
1206 PATCHER_MARK_PATCHED_MONITOREXIT;
1212 /* patcher_resolve_native ******************************************************
1216 *******************************************************************************/
1218 #if !defined(ENABLE_STATICVM)
1219 bool patcher_resolve_native(u1 *sp)
1222 java_objectheader *o;
1223 #if SIZEOF_VOID_P == 8
1233 /* get stuff from the stack */
1235 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1236 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1237 #if SIZEOF_VOID_P == 8
1238 mcode = *((u8 *) (sp + 3 * 8));
1240 mcode[0] = *((u4 *) (sp + 3 * 8));
1241 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1243 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1244 disp = *((s4 *) (sp + 1 * 8));
1245 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1247 /* calculate and set the new return address */
1250 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1252 PATCHER_MONITORENTER;
1254 /* resolve native function */
1256 if (!(f = native_resolve_function(m))) {
1257 PATCHER_MONITOREXIT;
1262 /* patch back original code */
1264 #if SIZEOF_VOID_P == 8
1265 *((u4 *) (ra + 0 * 4)) = mcode;
1266 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1268 *((u4 *) (ra + 0 * 4)) = mcode[0];
1269 *((u4 *) (ra + 1 * 4)) = mcode[1];
1272 /* synchronize instruction cache */
1274 cacheflush(ra, 2 * 4, ICACHE);
1276 /* patch native function pointer */
1278 *((ptrint *) (pv + disp)) = (ptrint) f;
1280 PATCHER_MARK_PATCHED_MONITOREXIT;
1284 #endif /* !defined(ENABLE_STATICVM) */
1288 * These are local overrides for various environment variables in Emacs.
1289 * Please do not remove this and leave it at the end of the file, where
1290 * Emacs will automagically detect them.
1291 * ---------------------------------------------------------------------
1294 * indent-tabs-mode: t
1298 * vim:noexpandtab:sw=4:ts=4: