1 /* src/vm/jit/mips/patcher.c - MIPS code patching functions
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
31 $Id: patcher.c 5164 2006-07-19 15:54:01Z twisti $
42 #include "mm/memory.h"
43 #include "native/native.h"
44 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
48 #include "vm/initialize.h"
49 #include "vm/options.h"
50 #include "vm/resolve.h"
51 #include "vm/references.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/patcher.h"
56 /* patcher_wrapper *************************************************************
58 Wrapper for all patchers. It also creates the stackframe info
61 If the return value of the patcher function is false, it gets the
62 exception object, clears the exception pointer and returns the
65 *******************************************************************************/
67 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
76 /* define the patcher function */
78 bool (*patcher_function)(u1 *);
82 /* get stuff from the stack */
84 xpc = (u1 *) *((ptrint *) (sp + 5 * 8));
85 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
86 f = (functionptr) *((ptrint *) (sp + 0 * 8));
88 /* store PV into the patcher function position */
90 *((ptrint *) (sp + 0 * 8)) = (ptrint) pv;
92 /* cast the passed function to a patcher function */
94 patcher_function = (bool (*)(u1 *)) (ptrint) f;
96 /* enter a monitor on the patching position */
100 /* create the stackframeinfo */
102 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 8, ra, xpc);
104 /* call the proper patcher function */
106 result = (patcher_function)(sp);
108 /* remove the stackframeinfo */
110 stacktrace_remove_stackframeinfo(&sfi);
112 /* check for return value and exit accordingly */
114 if (result == false) {
115 e = exceptions_get_and_clear_exception();
122 PATCHER_MARK_PATCHED_MONITOREXIT;
128 /* patcher_get_putstatic *******************************************************
132 <patched call position>
133 dfc1ffb8 ld at,-72(s8)
136 *******************************************************************************/
138 bool patcher_get_putstatic(u1 *sp)
141 #if SIZEOF_VOID_P == 8
146 unresolved_field *uf;
151 /* get stuff from the stack */
153 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
154 #if SIZEOF_VOID_P == 8
155 mcode = *((u8 *) (sp + 3 * 8));
157 mcode[0] = *((u4 *) (sp + 3 * 8));
158 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
160 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
161 disp = *((s4 *) (sp + 1 * 8));
162 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
164 /* get the fieldinfo */
166 if (!(fi = resolve_field_eager(uf)))
169 /* check if the field's class is initialized */
171 if (!(fi->class->state & CLASS_INITIALIZED))
172 if (!initialize_class(fi->class))
175 /* patch back original code */
177 #if SIZEOF_VOID_P == 8
178 *((u4 *) (ra + 0 * 4)) = mcode;
179 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
181 *((u4 *) (ra + 0 * 4)) = mcode[0];
182 *((u4 *) (ra + 1 * 4)) = mcode[1];
185 /* synchronize instruction cache */
187 md_icacheflush(ra, 2 * 4);
189 /* patch the field value's address */
191 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
193 /* synchronize data cache */
195 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
201 /* patcher_get_putfield ********************************************************
205 <patched call position>
206 8ee90020 lw a5,32(s7)
208 *******************************************************************************/
210 bool patcher_get_putfield(u1 *sp)
213 #if SIZEOF_VOID_P == 8
218 unresolved_field *uf;
221 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
222 #if SIZEOF_VOID_P == 8
223 mcode = *((u8 *) (sp + 3 * 8));
225 mcode[0] = *((u4 *) (sp + 3 * 8));
226 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
228 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
230 /* get the fieldinfo */
232 if (!(fi = resolve_field_eager(uf)))
235 /* patch back original code */
237 #if SIZEOF_VOID_P == 8
238 *((u4 *) (ra + 0 * 4)) = mcode;
239 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
241 *((u4 *) (ra + 0 * 4)) = mcode[0];
242 *((u4 *) (ra + 1 * 4)) = mcode[1];
245 /* if we show disassembly, we have to skip the nop's */
247 if (opt_showdisassemble)
250 /* patch the field's offset */
252 #if SIZEOF_VOID_P == 4
253 if (fi->type == TYPE_LNG) {
254 # if WORDS_BIGENDIAN == 1
255 /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
256 *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
257 *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
259 /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
260 *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
261 *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
265 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
267 /* synchronize instruction cache */
269 if (opt_showdisassemble) {
270 #if SIZEOF_VOID_P == 4
271 if (fi->type == TYPE_LNG)
272 md_icacheflush(ra - 2 * 4, 4 * 4);
275 md_icacheflush(ra - 2 * 4, 3 * 4);
278 md_icacheflush(ra, 2 * 4);
285 /* patcher_aconst **************************************************************
289 <patched call postition>
290 dfc4ff98 ld a0,-104(s8)
292 *******************************************************************************/
294 bool patcher_aconst(u1 *sp)
297 #if SIZEOF_VOID_P == 8
302 constant_classref *cr;
307 /* get stuff from the stack */
309 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
310 #if SIZEOF_VOID_P == 8
311 mcode = *((u8 *) (sp + 3 * 8));
313 mcode[0] = *((u4 *) (sp + 3 * 8));
314 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
316 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
317 disp = *((s4 *) (sp + 1 * 8));
318 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
320 /* get the classinfo */
322 if (!(c = resolve_classref_eager(cr)))
325 /* patch back original code */
327 #if SIZEOF_VOID_P == 8
328 *((u4 *) (ra + 0 * 4)) = mcode;
329 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
331 *((u4 *) (ra + 0 * 4)) = mcode[0];
332 *((u4 *) (ra + 1 * 4)) = mcode[1];
335 /* synchronize instruction cache */
337 md_icacheflush(ra, 2 * 4);
339 /* patch the classinfo pointer */
341 *((ptrint *) (pv + disp)) = (ptrint) c;
343 /* synchronize data cache */
345 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
351 /* patcher_builtin_multianewarray **********************************************
355 <patched call position>
356 dfc5ff90 ld a1,-112(s8)
358 dfd9ff88 ld t9,-120(s8)
362 *******************************************************************************/
364 bool patcher_builtin_multianewarray(u1 *sp)
367 #if SIZEOF_VOID_P == 8
372 constant_classref *cr;
377 /* get stuff from the stack */
379 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
380 #if SIZEOF_VOID_P == 8
381 mcode = *((u8 *) (sp + 3 * 8));
383 mcode[0] = *((u4 *) (sp + 3 * 8));
384 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
386 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
387 disp = *((s4 *) (sp + 1 * 8));
388 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
390 /* get the classinfo */
392 if (!(c = resolve_classref_eager(cr)))
395 /* patch back original code */
397 #if SIZEOF_VOID_P == 8
398 *((u4 *) (ra + 0 * 4)) = mcode;
399 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
401 *((u4 *) (ra + 0 * 4)) = mcode[0];
402 *((u4 *) (ra + 1 * 4)) = mcode[1];
405 /* synchronize instruction cache */
407 md_icacheflush(ra, 2 * 4);
409 /* patch the classinfo pointer */
411 *((ptrint *) (pv + disp)) = (ptrint) c;
413 /* synchronize data cache */
415 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
421 /* patcher_builtin_arraycheckcast **********************************************
425 <patched call position>
426 dfc5ffc0 ld a1,-64(s8)
427 dfd9ffb8 ld t9,-72(s8)
431 *******************************************************************************/
433 bool patcher_builtin_arraycheckcast(u1 *sp)
436 #if SIZEOF_VOID_P == 8
441 constant_classref *cr;
446 /* get stuff from the stack */
448 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
449 #if SIZEOF_VOID_P == 8
450 mcode = *((u8 *) (sp + 3 * 8));
452 mcode[0] = *((u4 *) (sp + 3 * 8));
453 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
455 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
456 disp = *((s4 *) (sp + 1 * 8));
457 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
459 /* get the classinfo */
461 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 md_icacheflush(ra, 2 * 4);
478 /* patch the classinfo pointer */
480 *((ptrint *) (pv + disp)) = (ptrint) c;
482 /* synchronize data cache */
484 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
490 /* patcher_invokestatic_special ************************************************
494 <patched call position>
495 dfdeffc0 ld s8,-64(s8)
499 ******************************************************************************/
501 bool patcher_invokestatic_special(u1 *sp)
504 #if SIZEOF_VOID_P == 8
509 unresolved_method *um;
514 /* get stuff from the stack */
516 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
517 #if SIZEOF_VOID_P == 8
518 mcode = *((u8 *) (sp + 3 * 8));
520 mcode[0] = *((u4 *) (sp + 3 * 8));
521 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
523 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
524 disp = *((s4 *) (sp + 1 * 8));
525 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
527 /* get the fieldinfo */
529 if (!(m = resolve_method_eager(um)))
532 /* patch back original code */
534 #if SIZEOF_VOID_P == 8
535 *((u4 *) (ra + 0 * 4)) = mcode;
536 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
538 *((u4 *) (ra + 0 * 4)) = mcode[0];
539 *((u4 *) (ra + 1 * 4)) = mcode[1];
542 /* synchronize instruction cache */
544 md_icacheflush(ra, 2 * 4);
546 /* patch stubroutine */
548 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
550 /* synchronize data cache */
552 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
558 /* patcher_invokevirtual *******************************************************
562 <patched call position>
564 df3e0040 ld s8,64(t9)
568 *******************************************************************************/
570 bool patcher_invokevirtual(u1 *sp)
573 #if SIZEOF_VOID_P == 8
578 unresolved_method *um;
581 /* get stuff from the stack */
583 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
584 #if SIZEOF_VOID_P == 8
585 mcode = *((u8 *) (sp + 3 * 8));
587 mcode[0] = *((u4 *) (sp + 3 * 8));
588 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
590 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
592 /* get the fieldinfo */
594 if (!(m = resolve_method_eager(um)))
597 /* patch back original code */
599 #if SIZEOF_VOID_P == 8
600 *((u4 *) (ra + 0 * 4)) = mcode;
601 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
603 *((u4 *) (ra + 0 * 4)) = mcode[0];
604 *((u4 *) (ra + 1 * 4)) = mcode[1];
607 /* if we show disassembly, we have to skip the nop's */
609 if (opt_showdisassemble)
612 /* patch vftbl index */
614 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
615 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
617 /* synchronize instruction cache */
619 if (opt_showdisassemble)
620 md_icacheflush(ra - 2 * 4, 4 * 4);
622 md_icacheflush(ra, 2 * 4);
628 /* patcher_invokeinterface *****************************************************
632 <patched call position>
634 df39ffa0 ld t9,-96(t9)
635 df3e0018 ld s8,24(t9)
639 *******************************************************************************/
641 bool patcher_invokeinterface(u1 *sp)
644 #if SIZEOF_VOID_P == 8
649 unresolved_method *um;
652 /* get stuff from the stack */
654 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
655 #if SIZEOF_VOID_P == 8
656 mcode = *((u8 *) (sp + 3 * 8));
658 mcode[0] = *((u4 *) (sp + 3 * 8));
659 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
661 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
663 /* get the fieldinfo */
665 if (!(m = resolve_method_eager(um)))
668 /* patch back original code */
670 #if SIZEOF_VOID_P == 8
671 *((u4 *) (ra + 0 * 4)) = mcode;
672 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
674 *((u4 *) (ra + 0 * 4)) = mcode[0];
675 *((u4 *) (ra + 1 * 4)) = mcode[1];
678 /* if we show disassembly, we have to skip the nop's */
680 if (opt_showdisassemble)
683 /* patch interfacetable index */
685 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
686 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
688 /* patch method offset */
690 *((s4 *) (ra + 2 * 4)) |=
691 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
693 /* synchronize instruction cache */
695 if (opt_showdisassemble)
696 md_icacheflush(ra - 2 * 4, 5 * 4);
698 md_icacheflush(ra, 3 * 4);
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 #if SIZEOF_VOID_P == 8
724 constant_classref *cr;
729 /* get stuff from the stack */
731 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
732 #if SIZEOF_VOID_P == 8
733 mcode = *((u8 *) (sp + 3 * 8));
735 mcode[0] = *((u4 *) (sp + 3 * 8));
736 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
738 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
739 disp = *((s4 *) (sp + 1 * 8));
740 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
742 /* get the fieldinfo */
744 if (!(c = resolve_classref_eager(cr)))
747 /* patch back original code */
749 #if SIZEOF_VOID_P == 8
750 *((u4 *) (ra + 0 * 4)) = mcode;
751 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
753 *((u4 *) (ra + 0 * 4)) = mcode[0];
754 *((u4 *) (ra + 1 * 4)) = mcode[1];
757 /* synchronize instruction cache */
759 md_icacheflush(ra, 2 * 4);
761 /* patch class flags */
763 *((s4 *) (pv + disp)) = (s4) c->flags;
765 /* synchronize data cache */
767 md_dcacheflush(pv + disp, sizeof(s4));
773 /* patcher_checkcast_instanceof_interface **************************************
777 <patched call position>
779 8c79001c lw t9,28(v1)
780 27390000 addiu t9,t9,0
781 1b200082 blez t9,zero,0x000000001051843c
785 *******************************************************************************/
787 bool patcher_checkcast_instanceof_interface(u1 *sp)
790 #if SIZEOF_VOID_P == 8
795 constant_classref *cr;
798 /* get stuff from the stack */
800 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
801 #if SIZEOF_VOID_P == 8
802 mcode = *((u8 *) (sp + 3 * 8));
804 mcode[0] = *((u4 *) (sp + 3 * 8));
805 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
807 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
809 /* get the fieldinfo */
811 if (!(c = resolve_classref_eager(cr)))
814 /* patch back original code */
816 #if SIZEOF_VOID_P == 8
817 *((u4 *) (ra + 0 * 4)) = mcode;
818 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
820 *((u4 *) (ra + 0 * 4)) = mcode[0];
821 *((u4 *) (ra + 1 * 4)) = mcode[1];
824 /* if we show disassembly, we have to skip the nop's */
826 if (opt_showdisassemble)
829 /* patch super class index */
831 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
833 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
834 c->index * sizeof(methodptr*)) & 0x0000ffff);
836 /* synchronize instruction cache */
838 if (opt_showdisassemble)
839 md_icacheflush(ra - 2 * 4, 8 * 4);
841 md_icacheflush(ra, 6 * 4);
847 /* patcher_checkcast_instanceof_class ******************************************
851 <patched call position>
853 dfd9ff18 ld t9,-232(s8)
855 *******************************************************************************/
857 bool patcher_checkcast_instanceof_class(u1 *sp)
860 #if SIZEOF_VOID_P == 8
865 constant_classref *cr;
870 /* get stuff from the stack */
872 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
873 #if SIZEOF_VOID_P == 8
874 mcode = *((u8 *) (sp + 3 * 8));
876 mcode[0] = *((u4 *) (sp + 3 * 8));
877 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
879 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
880 disp = *((s4 *) (sp + 1 * 8));
881 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
883 /* get the fieldinfo */
885 if (!(c = resolve_classref_eager(cr)))
888 /* patch back original code */
890 #if SIZEOF_VOID_P == 8
891 *((u4 *) (ra + 0 * 4)) = mcode;
892 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
894 *((u4 *) (ra + 0 * 4)) = mcode[0];
895 *((u4 *) (ra + 1 * 4)) = mcode[1];
898 /* synchronize instruction cache */
900 md_icacheflush(ra, 2 * 4);
902 /* patch super class' vftbl */
904 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
906 /* synchronize data cache */
908 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
914 /* patcher_clinit **************************************************************
916 No special machine code.
918 *******************************************************************************/
920 bool patcher_clinit(u1 *sp)
923 #if SIZEOF_VOID_P == 8
930 /* get stuff from the stack */
932 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
933 #if SIZEOF_VOID_P == 8
934 mcode = *((u8 *) (sp + 3 * 8));
936 mcode[0] = *((u4 *) (sp + 3 * 8));
937 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
939 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
941 /* check if the class is initialized */
943 if (!(c->state & CLASS_INITIALIZED))
944 if (!initialize_class(c))
947 /* patch back original code */
949 #if SIZEOF_VOID_P == 8
950 *((u4 *) (ra + 0 * 4)) = mcode;
951 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
953 *((u4 *) (ra + 0 * 4)) = mcode[0];
954 *((u4 *) (ra + 1 * 4)) = mcode[1];
957 /* synchronize instruction cache */
959 md_icacheflush(ra, 2 * 4);
965 /* patcher_athrow_areturn ******************************************************
969 <patched call position>
971 *******************************************************************************/
973 #ifdef ENABLE_VERIFIER
974 bool patcher_athrow_areturn(u1 *sp)
977 #if SIZEOF_VOID_P == 8
982 unresolved_class *uc;
985 /* get stuff from the stack */
987 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
988 #if SIZEOF_VOID_P == 8
989 mcode = *((u8 *) (sp + 3 * 8));
991 mcode[0] = *((u4 *) (sp + 3 * 8));
992 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
994 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
996 /* resolve the class */
998 if (!resolve_class(uc, resolveEager, false, &c))
1001 /* patch back original code */
1003 #if SIZEOF_VOID_P == 8
1004 *((u4 *) (ra + 0 * 4)) = mcode;
1005 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1007 *((u4 *) (ra + 0 * 4)) = mcode[0];
1008 *((u4 *) (ra + 1 * 4)) = mcode[1];
1011 /* synchronize instruction cache */
1013 md_icacheflush(ra, 2 * 4);
1017 #endif /* ENABLE_VERIFIER */
1020 /* patcher_resolve_native ******************************************************
1024 *******************************************************************************/
1026 #if !defined(WITH_STATIC_CLASSPATH)
1027 bool patcher_resolve_native(u1 *sp)
1030 #if SIZEOF_VOID_P == 8
1040 /* get stuff from the stack */
1042 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1043 #if SIZEOF_VOID_P == 8
1044 mcode = *((u8 *) (sp + 3 * 8));
1046 mcode[0] = *((u4 *) (sp + 3 * 8));
1047 mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
1049 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1050 disp = *((s4 *) (sp + 1 * 8));
1051 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1053 /* calculate and set the new return address */
1056 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1058 /* resolve native function */
1060 if (!(f = native_resolve_function(m)))
1063 /* patch back original code */
1065 #if SIZEOF_VOID_P == 8
1066 *((u4 *) (ra + 0 * 4)) = mcode;
1067 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1069 *((u4 *) (ra + 0 * 4)) = mcode[0];
1070 *((u4 *) (ra + 1 * 4)) = mcode[1];
1073 /* synchronize instruction cache */
1075 md_icacheflush(ra, 2 * 4);
1077 /* patch native function pointer */
1079 *((ptrint *) (pv + disp)) = (ptrint) f;
1081 /* synchronize data cache */
1083 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
1087 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1091 * These are local overrides for various environment variables in Emacs.
1092 * Please do not remove this and leave it at the end of the file, where
1093 * Emacs will automagically detect them.
1094 * ---------------------------------------------------------------------
1097 * indent-tabs-mode: t
1101 * vim:noexpandtab:sw=4:ts=4: