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 3659 2005-11-11 11:59:05Z 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_aconst **************************************************************
235 <patched call postition>
236 dfc4ff98 ld a0,-104(s8)
238 *******************************************************************************/
240 bool patcher_aconst(u1 *sp)
243 java_objectheader *o;
244 #if SIZEOF_VOID_P == 8
249 constant_classref *cr;
254 /* get stuff from the stack */
256 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
257 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
258 #if SIZEOF_VOID_P == 8
259 mcode = *((u8 *) (sp + 3 * 8));
261 mcode[0] = *((u4 *) (sp + 3 * 8));
262 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
264 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
265 disp = *((s4 *) (sp + 1 * 8));
266 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
268 PATCHER_MONITORENTER;
270 /* get the classinfo */
272 if (!(c = resolve_classref_eager(cr))) {
278 /* patch back original code */
280 #if SIZEOF_VOID_P == 8
281 *((u4 *) (ra + 0 * 4)) = mcode;
282 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
284 *((u4 *) (ra + 0 * 4)) = mcode[0];
285 *((u4 *) (ra + 1 * 4)) = mcode[1];
288 /* synchronize instruction cache */
290 cacheflush(ra, 2 * 4, ICACHE);
292 /* patch the classinfo pointer */
294 *((ptrint *) (pv + disp)) = (ptrint) c;
296 /* synchronize data cache */
298 cacheflush(pv + disp, SIZEOF_VOID_P * 1, DCACHE);
300 PATCHER_MARK_PATCHED_MONITOREXIT;
306 /* patcher_builtin_multianewarray **********************************************
310 <patched call position>
311 dfc5ff90 ld a1,-112(s8)
313 dfd9ff88 ld t9,-120(s8)
317 *******************************************************************************/
319 bool patcher_builtin_multianewarray(u1 *sp)
322 java_objectheader *o;
323 #if SIZEOF_VOID_P == 8
328 constant_classref *cr;
333 /* get stuff from the stack */
335 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
336 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
337 #if SIZEOF_VOID_P == 8
338 mcode = *((u8 *) (sp + 3 * 8));
340 mcode[0] = *((u4 *) (sp + 3 * 8));
341 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
343 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
344 disp = *((s4 *) (sp + 1 * 8));
345 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
347 PATCHER_MONITORENTER;
349 /* get the classinfo */
351 if (!(c = resolve_classref_eager(cr))) {
357 /* patch back original code */
359 #if SIZEOF_VOID_P == 8
360 *((u4 *) (ra + 0 * 4)) = mcode;
361 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
363 *((u4 *) (ra + 0 * 4)) = mcode[0];
364 *((u4 *) (ra + 1 * 4)) = mcode[1];
367 /* synchronize instruction cache */
369 cacheflush(ra, 2 * 4, ICACHE);
371 /* patch the classinfo pointer */
373 *((ptrint *) (pv + disp)) = (ptrint) c;
375 /* synchronize data cache */
377 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
379 PATCHER_MARK_PATCHED_MONITOREXIT;
385 /* patcher_builtin_arraycheckcast **********************************************
389 <patched call position>
390 dfc5ffc0 ld a1,-64(s8)
391 dfd9ffb8 ld t9,-72(s8)
395 *******************************************************************************/
397 bool patcher_builtin_arraycheckcast(u1 *sp)
400 java_objectheader *o;
401 #if SIZEOF_VOID_P == 8
406 constant_classref *cr;
411 /* get stuff from the stack */
413 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
414 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
415 #if SIZEOF_VOID_P == 8
416 mcode = *((u8 *) (sp + 3 * 8));
418 mcode[0] = *((u4 *) (sp + 3 * 8));
419 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
421 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
422 disp = *((s4 *) (sp + 1 * 8));
423 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
425 PATCHER_MONITORENTER;
427 /* get the classinfo */
429 if (!(c = resolve_classref_eager(cr))) {
435 /* patch back original code */
437 #if SIZEOF_VOID_P == 8
438 *((u4 *) (ra + 0 * 4)) = mcode;
439 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
441 *((u4 *) (ra + 0 * 4)) = mcode[0];
442 *((u4 *) (ra + 1 * 4)) = mcode[1];
445 /* synchronize instruction cache */
447 cacheflush(ra, 2 * 4, ICACHE);
449 /* patch the classinfo pointer */
451 *((ptrint *) (pv + disp)) = (ptrint) c;
453 /* synchronize data cache */
455 cacheflush(pv + disp, SIZEOF_VOID_P * 1, DCACHE);
457 PATCHER_MARK_PATCHED_MONITOREXIT;
463 /* patcher_invokestatic_special ************************************************
467 <patched call position>
468 dfdeffc0 ld s8,-64(s8)
472 ******************************************************************************/
474 bool patcher_invokestatic_special(u1 *sp)
477 java_objectheader *o;
478 #if SIZEOF_VOID_P == 8
483 unresolved_method *um;
488 /* get stuff from the stack */
490 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
491 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
492 #if SIZEOF_VOID_P == 8
493 mcode = *((u8 *) (sp + 3 * 8));
495 mcode[0] = *((u4 *) (sp + 3 * 8));
496 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
498 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
499 disp = *((s4 *) (sp + 1 * 8));
500 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
502 PATCHER_MONITORENTER;
504 /* get the fieldinfo */
506 if (!(m = resolve_method_eager(um))) {
512 /* patch back original code */
514 #if SIZEOF_VOID_P == 8
515 *((u4 *) (ra + 0 * 4)) = mcode;
516 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
518 *((u4 *) (ra + 0 * 4)) = mcode[0];
519 *((u4 *) (ra + 1 * 4)) = mcode[1];
522 /* synchronize instruction cache */
524 cacheflush(ra, 2 * 4, ICACHE);
526 /* patch stubroutine */
528 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
530 /* synchronize data cache */
532 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
534 PATCHER_MARK_PATCHED_MONITOREXIT;
540 /* patcher_invokevirtual *******************************************************
544 <patched call position>
546 df3e0040 ld s8,64(t9)
550 *******************************************************************************/
552 bool patcher_invokevirtual(u1 *sp)
555 java_objectheader *o;
556 #if SIZEOF_VOID_P == 8
561 unresolved_method *um;
564 /* get stuff from the stack */
566 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
567 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
568 #if SIZEOF_VOID_P == 8
569 mcode = *((u8 *) (sp + 3 * 8));
571 mcode[0] = *((u4 *) (sp + 3 * 8));
572 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
574 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
576 PATCHER_MONITORENTER;
578 /* get the fieldinfo */
580 if (!(m = resolve_method_eager(um))) {
586 /* patch back original code */
588 #if SIZEOF_VOID_P == 8
589 *((u4 *) (ra + 0 * 4)) = mcode;
590 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
592 *((u4 *) (ra + 0 * 4)) = mcode[0];
593 *((u4 *) (ra + 1 * 4)) = mcode[1];
596 /* if we show disassembly, we have to skip the nop's */
598 if (opt_showdisassemble)
601 /* patch vftbl index */
603 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
604 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
606 /* synchronize instruction cache */
608 if (opt_showdisassemble)
609 cacheflush(ra - 2 * 4, 4 * 4, ICACHE);
611 cacheflush(ra, 2 * 4, ICACHE);
613 PATCHER_MARK_PATCHED_MONITOREXIT;
619 /* patcher_invokeinterface *****************************************************
623 <patched call position>
625 df39ffa0 ld t9,-96(t9)
626 df3e0018 ld s8,24(t9)
630 *******************************************************************************/
632 bool patcher_invokeinterface(u1 *sp)
635 java_objectheader *o;
636 #if SIZEOF_VOID_P == 8
641 unresolved_method *um;
644 /* get stuff from the stack */
646 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
647 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
648 #if SIZEOF_VOID_P == 8
649 mcode = *((u8 *) (sp + 3 * 8));
651 mcode[0] = *((u4 *) (sp + 3 * 8));
652 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
654 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
656 PATCHER_MONITORENTER;
658 /* get the fieldinfo */
660 if (!(m = resolve_method_eager(um))) {
666 /* patch back original code */
668 #if SIZEOF_VOID_P == 8
669 *((u4 *) (ra + 0 * 4)) = mcode;
670 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
672 *((u4 *) (ra + 0 * 4)) = mcode[0];
673 *((u4 *) (ra + 1 * 4)) = mcode[1];
676 /* if we show disassembly, we have to skip the nop's */
678 if (opt_showdisassemble)
681 /* patch interfacetable index */
683 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
684 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
686 /* patch method offset */
688 *((s4 *) (ra + 2 * 4)) |=
689 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
691 /* synchronize instruction cache */
693 if (opt_showdisassemble)
694 cacheflush(ra - 2 * 4, 5 * 4, ICACHE);
696 cacheflush(ra, 3 * 4, ICACHE);
698 PATCHER_MARK_PATCHED_MONITOREXIT;
704 /* patcher_checkcast_instanceof_flags ******************************************
708 <patched call position>
709 8fc3ff24 lw v1,-220(s8)
710 30630200 andi v1,v1,512
711 1060000d beq v1,zero,0x000000001051824c
714 *******************************************************************************/
716 bool patcher_checkcast_instanceof_flags(u1 *sp)
719 java_objectheader *o;
720 #if SIZEOF_VOID_P == 8
725 constant_classref *cr;
730 /* get stuff from the stack */
732 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
733 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
734 #if SIZEOF_VOID_P == 8
735 mcode = *((u8 *) (sp + 3 * 8));
737 mcode[0] = *((u4 *) (sp + 3 * 8));
738 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
740 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
741 disp = *((s4 *) (sp + 1 * 8));
742 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
744 PATCHER_MONITORENTER;
746 /* get the fieldinfo */
748 if (!(c = resolve_classref_eager(cr))) {
754 /* patch back original code */
756 #if SIZEOF_VOID_P == 8
757 *((u4 *) (ra + 0 * 4)) = mcode;
758 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
760 *((u4 *) (ra + 0 * 4)) = mcode[0];
761 *((u4 *) (ra + 1 * 4)) = mcode[1];
764 /* synchronize instruction cache */
766 cacheflush(ra, 2 * 4, ICACHE);
768 /* patch class flags */
770 *((s4 *) (pv + disp)) = (s4) c->flags;
772 /* synchronize data cache */
774 cacheflush(pv + disp, sizeof(s4), DCACHE);
776 PATCHER_MARK_PATCHED_MONITOREXIT;
782 /* patcher_checkcast_instanceof_interface **************************************
786 <patched call position>
788 8c79001c lw t9,28(v1)
789 27390000 addiu t9,t9,0
790 1b200082 blez t9,zero,0x000000001051843c
794 *******************************************************************************/
796 bool patcher_checkcast_instanceof_interface(u1 *sp)
799 java_objectheader *o;
800 #if SIZEOF_VOID_P == 8
805 constant_classref *cr;
808 /* get stuff from the stack */
810 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
811 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
812 #if SIZEOF_VOID_P == 8
813 mcode = *((u8 *) (sp + 3 * 8));
815 mcode[0] = *((u4 *) (sp + 3 * 8));
816 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
818 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
820 PATCHER_MONITORENTER;
822 /* get the fieldinfo */
824 if (!(c = resolve_classref_eager(cr))) {
830 /* patch back original code */
832 #if SIZEOF_VOID_P == 8
833 *((u4 *) (ra + 0 * 4)) = mcode;
834 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
836 *((u4 *) (ra + 0 * 4)) = mcode[0];
837 *((u4 *) (ra + 1 * 4)) = mcode[1];
840 /* if we show disassembly, we have to skip the nop's */
842 if (opt_showdisassemble)
845 /* patch super class index */
847 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
849 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
850 c->index * sizeof(methodptr*)) & 0x0000ffff);
852 /* synchronize instruction cache */
854 if (opt_showdisassemble)
855 cacheflush(ra - 2 * 4, 8 * 4, ICACHE);
857 cacheflush(ra, 6 * 4, ICACHE);
859 PATCHER_MARK_PATCHED_MONITOREXIT;
865 /* patcher_checkcast_instanceof_class ******************************************
869 <patched call position>
871 dfd9ff18 ld t9,-232(s8)
873 *******************************************************************************/
875 bool patcher_checkcast_instanceof_class(u1 *sp)
878 java_objectheader *o;
879 #if SIZEOF_VOID_P == 8
884 constant_classref *cr;
889 /* get stuff from the stack */
891 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
892 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
893 #if SIZEOF_VOID_P == 8
894 mcode = *((u8 *) (sp + 3 * 8));
896 mcode[0] = *((u4 *) (sp + 3 * 8));
897 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
899 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
900 disp = *((s4 *) (sp + 1 * 8));
901 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
903 PATCHER_MONITORENTER;
905 /* get the fieldinfo */
907 if (!(c = resolve_classref_eager(cr))) {
913 /* patch back original code */
915 #if SIZEOF_VOID_P == 8
916 *((u4 *) (ra + 0 * 4)) = mcode;
917 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
919 *((u4 *) (ra + 0 * 4)) = mcode[0];
920 *((u4 *) (ra + 1 * 4)) = mcode[1];
923 /* synchronize instruction cache */
925 cacheflush(ra, 2 * 4, ICACHE);
927 /* patch super class' vftbl */
929 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
931 /* synchronize data cache */
933 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
935 PATCHER_MARK_PATCHED_MONITOREXIT;
941 /* patcher_clinit **************************************************************
943 No special machine code.
945 *******************************************************************************/
947 bool patcher_clinit(u1 *sp)
950 java_objectheader *o;
951 #if SIZEOF_VOID_P == 8
958 /* get stuff from the stack */
960 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
961 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
962 #if SIZEOF_VOID_P == 8
963 mcode = *((u8 *) (sp + 3 * 8));
965 mcode[0] = *((u4 *) (sp + 3 * 8));
966 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
968 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
970 PATCHER_MONITORENTER;
972 /* check if the class is initialized */
974 if (!c->initialized) {
975 if (!initialize_class(c)) {
982 /* patch back original code */
984 #if SIZEOF_VOID_P == 8
985 *((u4 *) (ra + 0 * 4)) = mcode;
986 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
988 *((u4 *) (ra + 0 * 4)) = mcode[0];
989 *((u4 *) (ra + 1 * 4)) = mcode[1];
992 /* synchronize instruction cache */
994 cacheflush(ra, 2 * 4, ICACHE);
996 PATCHER_MARK_PATCHED_MONITOREXIT;
1002 /* patcher_athrow_areturn ******************************************************
1006 <patched call position>
1008 *******************************************************************************/
1010 bool patcher_athrow_areturn(u1 *sp)
1013 java_objectheader *o;
1014 #if SIZEOF_VOID_P == 8
1019 unresolved_class *uc;
1022 /* get stuff from the stack */
1024 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1025 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1026 #if SIZEOF_VOID_P == 8
1027 mcode = *((u8 *) (sp + 3 * 8));
1029 mcode[0] = *((u4 *) (sp + 3 * 8));
1030 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1032 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
1034 PATCHER_MONITORENTER;
1036 /* resolve the class */
1038 if (!resolve_class(uc, resolveEager, false, &c)) {
1039 PATCHER_MONITOREXIT;
1044 /* patch back original code */
1046 #if SIZEOF_VOID_P == 8
1047 *((u4 *) (ra + 0 * 4)) = mcode;
1048 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1050 *((u4 *) (ra + 0 * 4)) = mcode[0];
1051 *((u4 *) (ra + 1 * 4)) = mcode[1];
1054 /* synchronize instruction cache */
1056 cacheflush(ra, 2 * 4, ICACHE);
1058 PATCHER_MARK_PATCHED_MONITOREXIT;
1064 /* patcher_resolve_native ******************************************************
1068 *******************************************************************************/
1070 #if !defined(ENABLE_STATICVM)
1071 bool patcher_resolve_native(u1 *sp)
1074 java_objectheader *o;
1075 #if SIZEOF_VOID_P == 8
1085 /* get stuff from the stack */
1087 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1088 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1089 #if SIZEOF_VOID_P == 8
1090 mcode = *((u8 *) (sp + 3 * 8));
1092 mcode[0] = *((u4 *) (sp + 3 * 8));
1093 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1095 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1096 disp = *((s4 *) (sp + 1 * 8));
1097 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1099 /* calculate and set the new return address */
1102 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1104 PATCHER_MONITORENTER;
1106 /* resolve native function */
1108 if (!(f = native_resolve_function(m))) {
1109 PATCHER_MONITOREXIT;
1114 /* patch back original code */
1116 #if SIZEOF_VOID_P == 8
1117 *((u4 *) (ra + 0 * 4)) = mcode;
1118 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1120 *((u4 *) (ra + 0 * 4)) = mcode[0];
1121 *((u4 *) (ra + 1 * 4)) = mcode[1];
1124 /* synchronize instruction cache */
1126 cacheflush(ra, 2 * 4, ICACHE);
1128 /* patch native function pointer */
1130 *((ptrint *) (pv + disp)) = (ptrint) f;
1132 /* synchronize data cache */
1134 cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE);
1136 PATCHER_MARK_PATCHED_MONITOREXIT;
1140 #endif /* !defined(ENABLE_STATICVM) */
1144 * These are local overrides for various environment variables in Emacs.
1145 * Please do not remove this and leave it at the end of the file, where
1146 * Emacs will automagically detect them.
1147 * ---------------------------------------------------------------------
1150 * indent-tabs-mode: t
1154 * vim:noexpandtab:sw=4:ts=4: