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 3880 2005-12-05 19:37:20Z twisti $
36 #include <sys/cachectl.h>
41 #include "mm/memory.h"
42 #include "native/native.h"
43 #include "vm/builtin.h"
46 #include "vm/initialize.h"
47 #include "vm/options.h"
48 #include "vm/resolve.h"
49 #include "vm/references.h"
50 #include "vm/jit/asmpart.h"
51 #include "vm/jit/patcher.h"
54 /* patcher_get_putstatic *******************************************************
58 <patched call position>
59 dfc1ffb8 ld at,-72(s8)
62 *******************************************************************************/
64 bool patcher_get_putstatic(u1 *sp)
68 #if SIZEOF_VOID_P == 8
78 /* get stuff from the stack */
80 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
81 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
82 #if SIZEOF_VOID_P == 8
83 mcode = *((u8 *) (sp + 3 * 8));
85 mcode[0] = *((u4 *) (sp + 3 * 8));
86 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
88 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
89 disp = *((s4 *) (sp + 1 * 8));
90 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
94 /* get the fieldinfo */
96 if (!(fi = resolve_field_eager(uf))) {
102 /* check if the field's class is initialized */
104 if (!(fi->class->state & CLASS_INITIALIZED)) {
105 if (!initialize_class(fi->class)) {
112 /* patch back original code */
114 #if SIZEOF_VOID_P == 8
115 *((u4 *) (ra + 0 * 4)) = mcode;
116 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
118 *((u4 *) (ra + 0 * 4)) = mcode[0];
119 *((u4 *) (ra + 1 * 4)) = mcode[1];
122 /* synchronize instruction cache */
124 cacheflush(ra, 2 * 4, ICACHE);
126 /* patch the field value's address */
128 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
130 /* synchronize data cache */
132 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
134 PATCHER_MARK_PATCHED_MONITOREXIT;
140 /* patcher_get_putfield ********************************************************
144 <patched call position>
145 8ee90020 lw a5,32(s7)
147 *******************************************************************************/
149 bool patcher_get_putfield(u1 *sp)
152 java_objectheader *o;
153 #if SIZEOF_VOID_P == 8
158 unresolved_field *uf;
161 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
162 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
163 #if SIZEOF_VOID_P == 8
164 mcode = *((u8 *) (sp + 3 * 8));
166 mcode[0] = *((u4 *) (sp + 3 * 8));
167 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
169 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
171 PATCHER_MONITORENTER;
173 /* get the fieldinfo */
175 if (!(fi = resolve_field_eager(uf))) {
181 /* patch back original code */
183 #if SIZEOF_VOID_P == 8
184 *((u4 *) (ra + 0 * 4)) = mcode;
185 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
187 *((u4 *) (ra + 0 * 4)) = mcode[0];
188 *((u4 *) (ra + 1 * 4)) = mcode[1];
191 /* if we show disassembly, we have to skip the nop's */
193 if (opt_showdisassemble)
196 /* patch the field's offset */
198 #if SIZEOF_VOID_P == 4
199 if (fi->type == TYPE_LNG) {
200 # if WORDS_BIGENDIAN == 1
201 /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
202 *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
203 *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
205 /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
206 *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
207 *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
211 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
213 /* synchronize instruction cache */
215 if (opt_showdisassemble) {
216 #if SIZEOF_VOID_P == 4
217 if (fi->type == TYPE_LNG) {
218 cacheflush(ra - 2 * 4, 4 * 4, ICACHE);
221 cacheflush(ra - 2 * 4, 3 * 4, ICACHE);
223 cacheflush(ra, 2 * 4, ICACHE);
226 PATCHER_MARK_PATCHED_MONITOREXIT;
232 /* patcher_aconst **************************************************************
236 <patched call postition>
237 dfc4ff98 ld a0,-104(s8)
239 *******************************************************************************/
241 bool patcher_aconst(u1 *sp)
244 java_objectheader *o;
245 #if SIZEOF_VOID_P == 8
250 constant_classref *cr;
255 /* get stuff from the stack */
257 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
258 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
259 #if SIZEOF_VOID_P == 8
260 mcode = *((u8 *) (sp + 3 * 8));
262 mcode[0] = *((u4 *) (sp + 3 * 8));
263 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
265 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
266 disp = *((s4 *) (sp + 1 * 8));
267 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
269 PATCHER_MONITORENTER;
271 /* get the classinfo */
273 if (!(c = resolve_classref_eager(cr))) {
279 /* patch back original code */
281 #if SIZEOF_VOID_P == 8
282 *((u4 *) (ra + 0 * 4)) = mcode;
283 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
285 *((u4 *) (ra + 0 * 4)) = mcode[0];
286 *((u4 *) (ra + 1 * 4)) = mcode[1];
289 /* synchronize instruction cache */
291 cacheflush(ra, 2 * 4, ICACHE);
293 /* patch the classinfo pointer */
295 *((ptrint *) (pv + disp)) = (ptrint) c;
297 /* synchronize data cache */
299 cacheflush(pv + disp, SIZEOF_VOID_P * 1, DCACHE);
301 PATCHER_MARK_PATCHED_MONITOREXIT;
307 /* patcher_builtin_multianewarray **********************************************
311 <patched call position>
312 dfc5ff90 ld a1,-112(s8)
314 dfd9ff88 ld t9,-120(s8)
318 *******************************************************************************/
320 bool patcher_builtin_multianewarray(u1 *sp)
323 java_objectheader *o;
324 #if SIZEOF_VOID_P == 8
329 constant_classref *cr;
334 /* get stuff from the stack */
336 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
337 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
338 #if SIZEOF_VOID_P == 8
339 mcode = *((u8 *) (sp + 3 * 8));
341 mcode[0] = *((u4 *) (sp + 3 * 8));
342 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
344 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
345 disp = *((s4 *) (sp + 1 * 8));
346 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
348 PATCHER_MONITORENTER;
350 /* get the classinfo */
352 if (!(c = resolve_classref_eager(cr))) {
358 /* patch back original code */
360 #if SIZEOF_VOID_P == 8
361 *((u4 *) (ra + 0 * 4)) = mcode;
362 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
364 *((u4 *) (ra + 0 * 4)) = mcode[0];
365 *((u4 *) (ra + 1 * 4)) = mcode[1];
368 /* synchronize instruction cache */
370 cacheflush(ra, 2 * 4, ICACHE);
372 /* patch the classinfo pointer */
374 *((ptrint *) (pv + disp)) = (ptrint) c;
376 /* synchronize data cache */
378 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
380 PATCHER_MARK_PATCHED_MONITOREXIT;
386 /* patcher_builtin_arraycheckcast **********************************************
390 <patched call position>
391 dfc5ffc0 ld a1,-64(s8)
392 dfd9ffb8 ld t9,-72(s8)
396 *******************************************************************************/
398 bool patcher_builtin_arraycheckcast(u1 *sp)
401 java_objectheader *o;
402 #if SIZEOF_VOID_P == 8
407 constant_classref *cr;
412 /* get stuff from the stack */
414 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
415 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
416 #if SIZEOF_VOID_P == 8
417 mcode = *((u8 *) (sp + 3 * 8));
419 mcode[0] = *((u4 *) (sp + 3 * 8));
420 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
422 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
423 disp = *((s4 *) (sp + 1 * 8));
424 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
426 PATCHER_MONITORENTER;
428 /* get the classinfo */
430 if (!(c = resolve_classref_eager(cr))) {
436 /* patch back original code */
438 #if SIZEOF_VOID_P == 8
439 *((u4 *) (ra + 0 * 4)) = mcode;
440 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
442 *((u4 *) (ra + 0 * 4)) = mcode[0];
443 *((u4 *) (ra + 1 * 4)) = mcode[1];
446 /* synchronize instruction cache */
448 cacheflush(ra, 2 * 4, ICACHE);
450 /* patch the classinfo pointer */
452 *((ptrint *) (pv + disp)) = (ptrint) c;
454 /* synchronize data cache */
456 cacheflush(pv + disp, SIZEOF_VOID_P * 1, DCACHE);
458 PATCHER_MARK_PATCHED_MONITOREXIT;
464 /* patcher_invokestatic_special ************************************************
468 <patched call position>
469 dfdeffc0 ld s8,-64(s8)
473 ******************************************************************************/
475 bool patcher_invokestatic_special(u1 *sp)
478 java_objectheader *o;
479 #if SIZEOF_VOID_P == 8
484 unresolved_method *um;
489 /* get stuff from the stack */
491 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
492 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
493 #if SIZEOF_VOID_P == 8
494 mcode = *((u8 *) (sp + 3 * 8));
496 mcode[0] = *((u4 *) (sp + 3 * 8));
497 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
499 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
500 disp = *((s4 *) (sp + 1 * 8));
501 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
503 PATCHER_MONITORENTER;
505 /* get the fieldinfo */
507 if (!(m = resolve_method_eager(um))) {
513 /* patch back original code */
515 #if SIZEOF_VOID_P == 8
516 *((u4 *) (ra + 0 * 4)) = mcode;
517 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
519 *((u4 *) (ra + 0 * 4)) = mcode[0];
520 *((u4 *) (ra + 1 * 4)) = mcode[1];
523 /* synchronize instruction cache */
525 cacheflush(ra, 2 * 4, ICACHE);
527 /* patch stubroutine */
529 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
531 /* synchronize data cache */
533 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
535 PATCHER_MARK_PATCHED_MONITOREXIT;
541 /* patcher_invokevirtual *******************************************************
545 <patched call position>
547 df3e0040 ld s8,64(t9)
551 *******************************************************************************/
553 bool patcher_invokevirtual(u1 *sp)
556 java_objectheader *o;
557 #if SIZEOF_VOID_P == 8
562 unresolved_method *um;
565 /* get stuff from the stack */
567 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
568 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
569 #if SIZEOF_VOID_P == 8
570 mcode = *((u8 *) (sp + 3 * 8));
572 mcode[0] = *((u4 *) (sp + 3 * 8));
573 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
575 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
577 PATCHER_MONITORENTER;
579 /* get the fieldinfo */
581 if (!(m = resolve_method_eager(um))) {
587 /* patch back original code */
589 #if SIZEOF_VOID_P == 8
590 *((u4 *) (ra + 0 * 4)) = mcode;
591 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
593 *((u4 *) (ra + 0 * 4)) = mcode[0];
594 *((u4 *) (ra + 1 * 4)) = mcode[1];
597 /* if we show disassembly, we have to skip the nop's */
599 if (opt_showdisassemble)
602 /* patch vftbl index */
604 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
605 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
607 /* synchronize instruction cache */
609 if (opt_showdisassemble)
610 cacheflush(ra - 2 * 4, 4 * 4, ICACHE);
612 cacheflush(ra, 2 * 4, ICACHE);
614 PATCHER_MARK_PATCHED_MONITOREXIT;
620 /* patcher_invokeinterface *****************************************************
624 <patched call position>
626 df39ffa0 ld t9,-96(t9)
627 df3e0018 ld s8,24(t9)
631 *******************************************************************************/
633 bool patcher_invokeinterface(u1 *sp)
636 java_objectheader *o;
637 #if SIZEOF_VOID_P == 8
642 unresolved_method *um;
645 /* get stuff from the stack */
647 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
648 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
649 #if SIZEOF_VOID_P == 8
650 mcode = *((u8 *) (sp + 3 * 8));
652 mcode[0] = *((u4 *) (sp + 3 * 8));
653 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
655 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
657 PATCHER_MONITORENTER;
659 /* get the fieldinfo */
661 if (!(m = resolve_method_eager(um))) {
667 /* patch back original code */
669 #if SIZEOF_VOID_P == 8
670 *((u4 *) (ra + 0 * 4)) = mcode;
671 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
673 *((u4 *) (ra + 0 * 4)) = mcode[0];
674 *((u4 *) (ra + 1 * 4)) = mcode[1];
677 /* if we show disassembly, we have to skip the nop's */
679 if (opt_showdisassemble)
682 /* patch interfacetable index */
684 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
685 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
687 /* patch method offset */
689 *((s4 *) (ra + 2 * 4)) |=
690 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
692 /* synchronize instruction cache */
694 if (opt_showdisassemble)
695 cacheflush(ra - 2 * 4, 5 * 4, ICACHE);
697 cacheflush(ra, 3 * 4, ICACHE);
699 PATCHER_MARK_PATCHED_MONITOREXIT;
705 /* patcher_checkcast_instanceof_flags ******************************************
709 <patched call position>
710 8fc3ff24 lw v1,-220(s8)
711 30630200 andi v1,v1,512
712 1060000d beq v1,zero,0x000000001051824c
715 *******************************************************************************/
717 bool patcher_checkcast_instanceof_flags(u1 *sp)
720 java_objectheader *o;
721 #if SIZEOF_VOID_P == 8
726 constant_classref *cr;
731 /* get stuff from the stack */
733 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
734 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
735 #if SIZEOF_VOID_P == 8
736 mcode = *((u8 *) (sp + 3 * 8));
738 mcode[0] = *((u4 *) (sp + 3 * 8));
739 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
741 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
742 disp = *((s4 *) (sp + 1 * 8));
743 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
745 PATCHER_MONITORENTER;
747 /* get the fieldinfo */
749 if (!(c = resolve_classref_eager(cr))) {
755 /* patch back original code */
757 #if SIZEOF_VOID_P == 8
758 *((u4 *) (ra + 0 * 4)) = mcode;
759 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
761 *((u4 *) (ra + 0 * 4)) = mcode[0];
762 *((u4 *) (ra + 1 * 4)) = mcode[1];
765 /* synchronize instruction cache */
767 cacheflush(ra, 2 * 4, ICACHE);
769 /* patch class flags */
771 *((s4 *) (pv + disp)) = (s4) c->flags;
773 /* synchronize data cache */
775 cacheflush(pv + disp, sizeof(s4), DCACHE);
777 PATCHER_MARK_PATCHED_MONITOREXIT;
783 /* patcher_checkcast_instanceof_interface **************************************
787 <patched call position>
789 8c79001c lw t9,28(v1)
790 27390000 addiu t9,t9,0
791 1b200082 blez t9,zero,0x000000001051843c
795 *******************************************************************************/
797 bool patcher_checkcast_instanceof_interface(u1 *sp)
800 java_objectheader *o;
801 #if SIZEOF_VOID_P == 8
806 constant_classref *cr;
809 /* get stuff from the stack */
811 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
812 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
813 #if SIZEOF_VOID_P == 8
814 mcode = *((u8 *) (sp + 3 * 8));
816 mcode[0] = *((u4 *) (sp + 3 * 8));
817 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
819 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
821 PATCHER_MONITORENTER;
823 /* get the fieldinfo */
825 if (!(c = resolve_classref_eager(cr))) {
831 /* patch back original code */
833 #if SIZEOF_VOID_P == 8
834 *((u4 *) (ra + 0 * 4)) = mcode;
835 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
837 *((u4 *) (ra + 0 * 4)) = mcode[0];
838 *((u4 *) (ra + 1 * 4)) = mcode[1];
841 /* if we show disassembly, we have to skip the nop's */
843 if (opt_showdisassemble)
846 /* patch super class index */
848 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
850 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
851 c->index * sizeof(methodptr*)) & 0x0000ffff);
853 /* synchronize instruction cache */
855 if (opt_showdisassemble)
856 cacheflush(ra - 2 * 4, 8 * 4, ICACHE);
858 cacheflush(ra, 6 * 4, ICACHE);
860 PATCHER_MARK_PATCHED_MONITOREXIT;
866 /* patcher_checkcast_instanceof_class ******************************************
870 <patched call position>
872 dfd9ff18 ld t9,-232(s8)
874 *******************************************************************************/
876 bool patcher_checkcast_instanceof_class(u1 *sp)
879 java_objectheader *o;
880 #if SIZEOF_VOID_P == 8
885 constant_classref *cr;
890 /* get stuff from the stack */
892 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
893 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
894 #if SIZEOF_VOID_P == 8
895 mcode = *((u8 *) (sp + 3 * 8));
897 mcode[0] = *((u4 *) (sp + 3 * 8));
898 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
900 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
901 disp = *((s4 *) (sp + 1 * 8));
902 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
904 PATCHER_MONITORENTER;
906 /* get the fieldinfo */
908 if (!(c = resolve_classref_eager(cr))) {
914 /* patch back original code */
916 #if SIZEOF_VOID_P == 8
917 *((u4 *) (ra + 0 * 4)) = mcode;
918 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
920 *((u4 *) (ra + 0 * 4)) = mcode[0];
921 *((u4 *) (ra + 1 * 4)) = mcode[1];
924 /* synchronize instruction cache */
926 cacheflush(ra, 2 * 4, ICACHE);
928 /* patch super class' vftbl */
930 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
932 /* synchronize data cache */
934 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
936 PATCHER_MARK_PATCHED_MONITOREXIT;
942 /* patcher_clinit **************************************************************
944 No special machine code.
946 *******************************************************************************/
948 bool patcher_clinit(u1 *sp)
951 java_objectheader *o;
952 #if SIZEOF_VOID_P == 8
959 /* get stuff from the stack */
961 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
962 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
963 #if SIZEOF_VOID_P == 8
964 mcode = *((u8 *) (sp + 3 * 8));
966 mcode[0] = *((u4 *) (sp + 3 * 8));
967 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
969 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
971 PATCHER_MONITORENTER;
973 /* check if the class is initialized */
975 if (!(c->state & CLASS_INITIALIZED)) {
976 if (!initialize_class(c)) {
983 /* patch back original code */
985 #if SIZEOF_VOID_P == 8
986 *((u4 *) (ra + 0 * 4)) = mcode;
987 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
989 *((u4 *) (ra + 0 * 4)) = mcode[0];
990 *((u4 *) (ra + 1 * 4)) = mcode[1];
993 /* synchronize instruction cache */
995 cacheflush(ra, 2 * 4, ICACHE);
997 PATCHER_MARK_PATCHED_MONITOREXIT;
1003 /* patcher_athrow_areturn ******************************************************
1007 <patched call position>
1009 *******************************************************************************/
1011 #ifdef ENABLE_VERIFIER
1012 bool patcher_athrow_areturn(u1 *sp)
1015 java_objectheader *o;
1016 #if SIZEOF_VOID_P == 8
1021 unresolved_class *uc;
1024 /* get stuff from the stack */
1026 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1027 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1028 #if SIZEOF_VOID_P == 8
1029 mcode = *((u8 *) (sp + 3 * 8));
1031 mcode[0] = *((u4 *) (sp + 3 * 8));
1032 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1034 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
1036 PATCHER_MONITORENTER;
1038 /* resolve the class */
1040 if (!resolve_class(uc, resolveEager, false, &c)) {
1041 PATCHER_MONITOREXIT;
1046 /* patch back original code */
1048 #if SIZEOF_VOID_P == 8
1049 *((u4 *) (ra + 0 * 4)) = mcode;
1050 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1052 *((u4 *) (ra + 0 * 4)) = mcode[0];
1053 *((u4 *) (ra + 1 * 4)) = mcode[1];
1056 /* synchronize instruction cache */
1058 cacheflush(ra, 2 * 4, ICACHE);
1060 PATCHER_MARK_PATCHED_MONITOREXIT;
1064 #endif /* ENABLE_VERIFIER */
1067 /* patcher_resolve_native ******************************************************
1071 *******************************************************************************/
1073 #if !defined(ENABLE_STATICVM)
1074 bool patcher_resolve_native(u1 *sp)
1077 java_objectheader *o;
1078 #if SIZEOF_VOID_P == 8
1088 /* get stuff from the stack */
1090 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1091 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1092 #if SIZEOF_VOID_P == 8
1093 mcode = *((u8 *) (sp + 3 * 8));
1095 mcode[0] = *((u4 *) (sp + 3 * 8));
1096 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1098 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1099 disp = *((s4 *) (sp + 1 * 8));
1100 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1102 /* calculate and set the new return address */
1105 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1107 PATCHER_MONITORENTER;
1109 /* resolve native function */
1111 if (!(f = native_resolve_function(m))) {
1112 PATCHER_MONITOREXIT;
1117 /* patch back original code */
1119 #if SIZEOF_VOID_P == 8
1120 *((u4 *) (ra + 0 * 4)) = mcode;
1121 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1123 *((u4 *) (ra + 0 * 4)) = mcode[0];
1124 *((u4 *) (ra + 1 * 4)) = mcode[1];
1127 /* synchronize instruction cache */
1129 cacheflush(ra, 2 * 4, ICACHE);
1131 /* patch native function pointer */
1133 *((ptrint *) (pv + disp)) = (ptrint) f;
1135 /* synchronize data cache */
1137 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
1139 PATCHER_MARK_PATCHED_MONITOREXIT;
1143 #endif /* !defined(ENABLE_STATICVM) */
1147 * These are local overrides for various environment variables in Emacs.
1148 * Please do not remove this and leave it at the end of the file, where
1149 * Emacs will automagically detect them.
1150 * ---------------------------------------------------------------------
1153 * indent-tabs-mode: t
1157 * vim:noexpandtab:sw=4:ts=4: