* src/vm/jit/s390/md-abi.h,
[cacao.git] / src / vm / jit / mips / patcher.c
1 /* src/vm/jit/mips/patcher.c - MIPS code patching functions
2
3    Copyright (C) 1996-2005, 2006, 2007 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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25    $Id: patcher.c 7431 2007-03-01 13:49:14Z edwin $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33
34 #include "vm/types.h"
35
36 #include "vm/jit/mips/codegen.h"
37
38 #include "mm/memory.h"
39
40 #include "native/native.h"
41
42 #include "vm/builtin.h"
43 #include "vm/exceptions.h"
44 #include "vm/initialize.h"
45
46 #include "vm/jit/asmpart.h"
47 #include "vm/jit/md.h"
48 #include "vm/jit/patcher.h"
49
50 #include "vmcore/class.h"
51 #include "vmcore/field.h"
52 #include "vmcore/options.h"
53 #include "vmcore/resolve.h"
54 #include "vmcore/references.h"
55
56
57 /* patcher_wrapper *************************************************************
58
59    Wrapper for all patchers.  It also creates the stackframe info
60    structure.
61
62    If the return value of the patcher function is false, it gets the
63    exception object, clears the exception pointer and returns the
64    exception.
65
66 *******************************************************************************/
67
68 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
69 {
70         stackframeinfo     sfi;
71         u1                *xpc;
72         java_objectheader *o;
73         u4                 mcode[5];
74         functionptr        f;
75         bool               result;
76         java_objectheader *e;
77
78         /* define the patcher function */
79
80         bool (*patcher_function)(u1 *);
81
82         assert(pv != NULL);
83
84         /* get stuff from the stack */
85
86         xpc = (u1 *)                *((ptrint *) (sp + 7 * 8));
87         o   = (java_objectheader *) *((ptrint *) (sp + 6 * 8));
88         f   = (functionptr)         *((ptrint *) (sp + 0 * 8));
89
90         /* store PV into the patcher function position */
91
92         *((ptrint *) (sp + 0 * 8)) = (ptrint) pv;
93
94         /* cast the passed function to a patcher function */
95
96         patcher_function = (bool (*)(u1 *)) (ptrint) f;
97
98         /* enter a monitor on the patching position */
99
100         PATCHER_MONITORENTER;
101
102         /* create the stackframeinfo */
103
104         stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 8 * 8, ra, xpc);
105
106         /* call the proper patcher function */
107
108         result = (patcher_function)(sp);
109
110         /* remove the stackframeinfo */
111
112         stacktrace_remove_stackframeinfo(&sfi);
113
114         /* check for return value and exit accordingly */
115
116         if (result == false) {
117                 e = exceptions_get_and_clear_exception();
118
119                 PATCHER_MONITOREXIT;
120
121                 return e;
122         }
123
124         /* patch back original code */
125
126         mcode[0] = *((u4 *) (sp + 3 * 8 + 0));
127         mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
128
129         mcode[2] = *((u4 *) (sp + 4 * 8 + 0));
130         mcode[3] = *((u4 *) (sp + 4 * 8 + 4));
131         mcode[4] = *((u4 *) (sp + 5 * 8 + 0));
132
133         *((u4 *) (xpc + 0 * 4)) = mcode[0];
134         *((u4 *) (xpc + 1 * 4)) = mcode[1];
135
136         *((u4 *) (xpc + 2 * 4)) = mcode[2];
137         *((u4 *) (xpc + 3 * 4)) = mcode[3];
138         *((u4 *) (xpc + 4 * 4)) = mcode[4];
139
140         /* synchronize instruction cache */
141
142         md_icacheflush(xpc, PATCHER_CALL_SIZE);
143
144         PATCHER_MARK_PATCHED_MONITOREXIT;
145
146         return NULL;
147 }
148
149
150 /* patcher_get_putstatic *******************************************************
151
152    Machine code:
153
154    <patched call position>
155    dfc1ffb8    ld       at,-72(s8)
156    fc250000    sd       a1,0(at)
157
158 *******************************************************************************/
159
160 bool patcher_get_putstatic(u1 *sp)
161 {
162         unresolved_field *uf;
163         s4                disp;
164         u1               *pv;
165         fieldinfo        *fi;
166
167         /* get stuff from the stack */
168
169         uf   = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
170         disp =                      *((s4 *)     (sp + 1 * 8));
171         pv   = (u1 *)               *((ptrint *) (sp + 0 * 8));
172
173         /* get the fieldinfo */
174
175         if (!(fi = resolve_field_eager(uf)))
176                 return false;
177
178         /* check if the field's class is initialized */
179
180         if (!(fi->class->state & CLASS_INITIALIZED))
181                 if (!initialize_class(fi->class))
182                         return false;
183
184         /* patch the field value's address */
185
186         *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
187
188         /* synchronize data cache */
189
190         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
191
192         return true;
193 }
194
195
196 /* patcher_get_putfield ********************************************************
197
198    Machine code:
199
200    <patched call position>
201    8ee90020    lw       a5,32(s7)
202
203 *******************************************************************************/
204
205 bool patcher_get_putfield(u1 *sp)
206 {
207         u1               *ra;
208         unresolved_field *uf;
209         fieldinfo        *fi;
210
211         /* get stuff from the stack */
212
213         ra = (u1 *)               *((ptrint *) (sp + 7 * 8));
214         uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
215
216         /* get the fieldinfo */
217
218         if (!(fi = resolve_field_eager(uf)))
219                 return false;
220
221         /* if we show disassembly, we have to skip the nop's */
222
223         if (opt_shownops) {
224                 ra = ra + PATCHER_CALL_SIZE;
225
226 #if SIZEOF_VOID_P == 4
227                 if (IS_LNG_TYPE(fi->type)) {
228 # if WORDS_BIGENDIAN == 1
229                         /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
230                         *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
231                         *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
232 # else
233                         /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
234                         *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
235                         *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
236 # endif
237                 }
238                 else
239 #endif
240                         *((u4 *) (ra + 0 * 4)) |= (s2) (fi->offset & 0x0000ffff);
241
242                 /* synchronize instruction cache */
243
244                 md_icacheflush(ra, 2 * 4);
245         }
246         else {
247 #if SIZEOF_VOID_P == 4
248                 if (IS_LNG_TYPE(fi->type)) {
249 # if WORDS_BIGENDIAN == 1
250                         /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
251                         *((u4 *) (sp + 3 * 8 + 0)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
252                         *((u4 *) (sp + 3 * 8 + 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
253 # else
254                         /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
255                         *((u4 *) (sp + 3 * 8 + 0)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
256                         *((u4 *) (sp + 3 * 8 + 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
257 # endif
258                 }
259                 else
260 #endif
261                         *((u4 *) (sp + 3 * 8 + 0)) |= (s2) (fi->offset & 0x0000ffff);
262         }
263
264         return true;
265 }
266
267
268 /* patcher_aconst **************************************************************
269
270    Machine code:
271
272    <patched call postition>
273    dfc4ff98    ld       a0,-104(s8)
274
275 *******************************************************************************/
276
277 bool patcher_aconst(u1 *sp)
278 {
279         constant_classref *cr;
280         s4                 disp;
281         u1                *pv;
282         classinfo         *c;
283
284         /* get stuff from the stack */
285
286         cr   = (constant_classref *) *((ptrint *) (sp + 2 * 8));
287         disp =                       *((s4 *)     (sp + 1 * 8));
288         pv   = (u1 *)                *((ptrint *) (sp + 0 * 8));
289
290         /* get the classinfo */
291
292         if (!(c = resolve_classref_eager(cr)))
293                 return false;
294
295         /* patch the classinfo pointer */
296
297         *((ptrint *) (pv + disp)) = (ptrint) c;
298
299         /* synchronize data cache */
300
301         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
302
303         return true;
304 }
305
306
307 /* patcher_builtin_multianewarray **********************************************
308
309    Machine code:
310
311    <patched call position>
312    dfc5ff90    ld       a1,-112(s8)
313    03a03025    move     a2,sp
314    dfd9ff88    ld       t9,-120(s8)
315    0320f809    jalr     t9
316    00000000    nop
317
318 *******************************************************************************/
319
320 bool patcher_builtin_multianewarray(u1 *sp)
321 {
322         constant_classref *cr;
323         s4                 disp;
324         u1                *pv;
325         classinfo         *c;
326
327         /* get stuff from the stack */
328
329         cr   = (constant_classref *) *((ptrint *) (sp + 2 * 8));
330         disp =                       *((s4 *)     (sp + 1 * 8));
331         pv   = (u1 *)                *((ptrint *) (sp + 0 * 8));
332
333         /* get the classinfo */
334
335         if (!(c = resolve_classref_eager(cr)))
336                 return false;
337
338         /* patch the classinfo pointer */
339
340         *((ptrint *) (pv + disp)) = (ptrint) c;
341
342         /* synchronize data cache */
343
344         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
345
346         return true;
347 }
348
349
350 /* patcher_builtin_arraycheckcast **********************************************
351
352    Machine code:
353
354    <patched call position>
355    dfc5ffc0    ld       a1,-64(s8)
356    dfd9ffb8    ld       t9,-72(s8)
357    0320f809    jalr     t9
358    00000000    nop
359
360 *******************************************************************************/
361
362 bool patcher_builtin_arraycheckcast(u1 *sp)
363 {
364         constant_classref *cr;
365         s4                 disp;
366         u1                *pv;
367         classinfo         *c;
368
369         /* get stuff from the stack */
370
371         cr   = (constant_classref *) *((ptrint *) (sp + 2 * 8));
372         disp =                       *((s4 *)     (sp + 1 * 8));
373         pv   = (u1 *)                *((ptrint *) (sp + 0 * 8));
374
375         /* get the classinfo */
376
377         if (!(c = resolve_classref_eager(cr)))
378                 return false;
379
380         /* patch the classinfo pointer */
381
382         *((ptrint *) (pv + disp)) = (ptrint) c;
383
384         /* synchronize data cache */
385
386         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
387
388         return true;
389 }
390
391
392 /* patcher_invokestatic_special ************************************************
393
394    Machine code:
395
396    <patched call position>
397    dfdeffc0    ld       s8,-64(s8)
398    03c0f809    jalr     s8
399    00000000    nop
400
401 ******************************************************************************/
402
403 bool patcher_invokestatic_special(u1 *sp)
404 {
405         unresolved_method *um;
406         s4                 disp;
407         u1                *pv;
408         methodinfo        *m;
409
410         /* get stuff from the stack */
411
412         um   = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
413         disp =                       *((s4 *)     (sp + 1 * 8));
414         pv   = (u1 *)                *((ptrint *) (sp + 0 * 8));
415
416         /* get the fieldinfo */
417
418         if (!(m = resolve_method_eager(um)))
419                 return false;
420
421         /* patch stubroutine */
422
423         *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
424
425         /* synchronize data cache */
426
427         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
428
429         return true;
430 }
431
432
433 /* patcher_invokevirtual *******************************************************
434
435    Machine code:
436
437    <patched call position>
438    dc990000    ld       t9,0(a0)
439    df3e0040    ld       s8,64(t9)
440    03c0f809    jalr     s8
441    00000000    nop
442
443 *******************************************************************************/
444
445 bool patcher_invokevirtual(u1 *sp)
446 {
447         u1                *ra;
448         unresolved_method *um;
449         methodinfo        *m;
450
451         /* get stuff from the stack */
452
453         ra = (u1 *)                *((ptrint *) (sp + 7 * 8));
454         um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
455
456         /* get the fieldinfo */
457
458         if (!(m = resolve_method_eager(um)))
459                 return false;
460
461         /* if we show disassembly, we have to skip the nop's */
462
463         if (opt_shownops) {
464                 ra = ra + PATCHER_CALL_SIZE;
465
466                 /* patch vftbl index */
467
468                 *((s4 *) (ra + 1 * 4)) |=
469                         (s4) ((OFFSET(vftbl_t, table[0]) +
470                                    sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
471
472                 /* synchronize instruction cache */
473
474                 md_icacheflush(ra + 1 * 4, 1 * 4);
475         }
476         else {
477                 /* patch vftbl index */
478
479                 *((s4 *) (sp + 3 * 8 + 4)) |=
480                         (s4) ((OFFSET(vftbl_t, table[0]) +
481                                    sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
482         }
483
484         return true;
485 }
486
487
488 /* patcher_invokeinterface *****************************************************
489
490    Machine code:
491
492    <patched call position>
493    dc990000    ld       t9,0(a0)
494    df39ffa0    ld       t9,-96(t9)
495    df3e0018    ld       s8,24(t9)
496    03c0f809    jalr     s8
497    00000000    nop
498
499 *******************************************************************************/
500
501 bool patcher_invokeinterface(u1 *sp)
502 {
503         u1                *ra;
504         unresolved_method *um;
505         methodinfo        *m;
506
507         /* get stuff from the stack */
508
509         ra = (u1 *)                *((ptrint *) (sp + 7 * 8));
510         um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
511
512         /* get the fieldinfo */
513
514         if (!(m = resolve_method_eager(um)))
515                 return false;
516
517         /* if we show disassembly, we have to skip the nop's */
518
519         if (opt_shownops) {
520                 ra = ra + PATCHER_CALL_SIZE;
521
522                 /* patch interfacetable index */
523
524                 *((s4 *) (ra + 1 * 4)) |=
525                         (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
526                                    sizeof(methodptr*) * m->class->index) & 0x0000ffff);
527
528                 /* patch method offset */
529
530                 *((s4 *) (ra + 2 * 4)) |=
531                         (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
532
533                 /* synchronize instruction cache */
534
535                 md_icacheflush(ra + 1 * 4, 2 * 4);
536         }
537         else {
538                 /* patch interfacetable index */
539
540                 *((s4 *) (sp + 3 * 8 + 4)) |=
541                         (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
542                                    sizeof(methodptr*) * m->class->index) & 0x0000ffff);
543
544                 /* patch method offset */
545
546                 *((s4 *) (sp + 4 * 8 + 0)) |=
547                         (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
548         }
549
550         return true;
551 }
552
553
554 /* patcher_checkcast_instanceof_flags ******************************************
555
556    Machine code:
557
558    <patched call position>
559    8fc3ff24    lw       v1,-220(s8)
560    30630200    andi     v1,v1,512
561    1060000d    beq      v1,zero,0x000000001051824c
562    00000000    nop
563
564 *******************************************************************************/
565
566 bool patcher_checkcast_instanceof_flags(u1 *sp)
567 {
568         constant_classref *cr;
569         s4                 disp;
570         u1                *pv;
571         classinfo         *c;
572
573         /* get stuff from the stack */
574
575         cr   = (constant_classref *) *((ptrint *) (sp + 2 * 8));
576         disp =                       *((s4 *)     (sp + 1 * 8));
577         pv   = (u1 *)                *((ptrint *) (sp + 0 * 8));
578
579         /* get the fieldinfo */
580
581         if (!(c = resolve_classref_eager(cr)))
582                 return false;
583
584         /* patch class flags */
585
586         *((s4 *) (pv + disp)) = (s4) c->flags;
587
588         /* synchronize data cache */
589
590         md_dcacheflush(pv + disp, sizeof(s4));
591
592         return true;
593 }
594
595
596 /* patcher_checkcast_instanceof_interface **************************************
597
598    Machine code:
599
600    <patched call position>
601    dd030000    ld       v1,0(a4)
602    8c79001c    lw       t9,28(v1)
603    27390000    addiu    t9,t9,0
604    1b200082    blez     t9,zero,0x000000001051843c
605    00000000    nop
606    dc790000    ld       t9,0(v1)
607
608 *******************************************************************************/
609
610 bool patcher_checkcast_interface(u1 *sp)
611 {
612         u1                *ra;
613         constant_classref *cr;
614         classinfo         *c;
615
616         /* get stuff from the stack */
617
618         ra = (u1 *)                *((ptrint *) (sp + 7 * 8));
619         cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
620
621         /* get the fieldinfo */
622
623         if (!(c = resolve_classref_eager(cr)))
624                 return false;
625
626         /* if we show disassembly, we have to skip the nop's */
627
628         if (opt_shownops) {
629                 ra = ra + PATCHER_CALL_SIZE;
630
631                 /* patch super class index */
632
633                 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
634                 /*      *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - */
635                 /*                                                                       c->index * sizeof(methodptr*)) & 0x0000ffff); */
636                 *((s4 *) (ra + 10 * 4)) |=
637                         (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
638                                    c->index * sizeof(methodptr*)) & 0x0000ffff);
639
640                 /* synchronize instruction cache */
641
642                 md_icacheflush(ra + 2 * 4, 7 * 4);
643         }
644         else {
645                 /* patch super class index */
646
647                 *((s4 *) (sp + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
648                 /*      *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - */
649                 /*                                                                       c->index * sizeof(methodptr*)) & 0x0000ffff); */
650                 *((s4 *) (ra + 10 * 4)) |=
651                         (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
652                                    c->index * sizeof(methodptr*)) & 0x0000ffff);
653
654                 /* synchronize instruction cache */
655
656                 md_icacheflush(ra + 10 * 4, 1 * 4);
657         }
658
659         return true;
660 }
661
662
663 /* patcher_instanceof_interface ************************************************
664
665    Machine code:
666
667    <patched call position>
668    dd030000    ld       v1,0(a4)
669    8c79001c    lw       t9,28(v1)
670    27390000    addiu    t9,t9,0
671    1b200082    blez     t9,zero,0x000000001051843c
672    00000000    nop
673    dc790000    ld       t9,0(v1)
674
675 *******************************************************************************/
676
677 bool patcher_instanceof_interface(u1 *sp)
678 {
679         u1                *ra;
680         constant_classref *cr;
681         classinfo         *c;
682
683         /* get stuff from the stack */
684
685         ra = (u1 *)                *((ptrint *) (sp + 7 * 8));
686         cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
687
688         /* get the fieldinfo */
689
690         if (!(c = resolve_classref_eager(cr)))
691                 return false;
692
693         /* if we show disassembly, we have to skip the nop's */
694
695         if (opt_shownops) {
696                 ra = ra + PATCHER_CALL_SIZE;
697
698                 /* patch super class index */
699
700                 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
701                 *((s4 *) (ra + 5 * 4)) |=
702                         (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
703                                    c->index * sizeof(methodptr*)) & 0x0000ffff);
704
705                 /* synchronize instruction cache */
706
707                 md_icacheflush(ra + 2 * 4, 4 * 4);
708         }
709         else {
710                 /* patch super class index */
711
712                 *((s4 *) (sp + 4 * 8 + 0)) |= (s4) (-(c->index) & 0x0000ffff);
713                 *((s4 *) (ra + 5 * 4)) |=
714                         (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
715                                    c->index * sizeof(methodptr*)) & 0x0000ffff);
716
717                 /* synchronize instruction cache */
718
719                 md_icacheflush(ra + 5 * 4, 1 * 4);
720         }
721
722         return true;
723 }
724
725
726 /* patcher_checkcast_instanceof_class ******************************************
727
728    Machine code:
729
730    <patched call position>
731    dd030000    ld       v1,0(a4)
732    dfd9ff18    ld       t9,-232(s8)
733
734 *******************************************************************************/
735
736 bool patcher_checkcast_instanceof_class(u1 *sp)
737 {
738         constant_classref *cr;
739         s4                 disp;
740         u1                *pv;
741         classinfo         *c;
742
743         /* get stuff from the stack */
744
745         cr   = (constant_classref *) *((ptrint *) (sp + 2 * 8));
746         disp =                       *((s4 *)     (sp + 1 * 8));
747         pv   = (u1 *)                *((ptrint *) (sp + 0 * 8));
748
749         /* get the fieldinfo */
750
751         if (!(c = resolve_classref_eager(cr)))
752                 return false;
753
754         /* patch super class' vftbl */
755
756         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
757
758         /* synchronize data cache */
759
760         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
761
762         return true;
763 }
764
765
766 /* patcher_clinit **************************************************************
767
768    No special machine code.
769
770 *******************************************************************************/
771
772 bool patcher_clinit(u1 *sp)
773 {
774         classinfo *c;
775
776         /* get stuff from the stack */
777
778         c = (classinfo *) *((ptrint *) (sp + 2 * 8));
779
780         /* check if the class is initialized */
781
782         if (!(c->state & CLASS_INITIALIZED))
783                 if (!initialize_class(c))
784                         return false;
785
786         return true;
787 }
788
789
790 /* patcher_athrow_areturn ******************************************************
791
792    Machine code:
793
794    <patched call position>
795
796 *******************************************************************************/
797
798 #ifdef ENABLE_VERIFIER
799 bool patcher_athrow_areturn(u1 *sp)
800 {
801         unresolved_class *uc;
802
803         /* get stuff from the stack */
804
805         uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
806
807         /* resolve the class and check subtype constraints */
808
809         if (!resolve_class_eager_no_access_check(uc))
810                 return false;
811
812         return true;
813 }
814 #endif /* ENABLE_VERIFIER */
815
816
817 /* patcher_resolve_native ******************************************************
818
819    XXX
820
821 *******************************************************************************/
822
823 #if !defined(WITH_STATIC_CLASSPATH)
824 bool patcher_resolve_native(u1 *sp)
825 {
826         methodinfo  *m;
827         s4           disp;
828         u1          *pv;
829         functionptr  f;
830
831         /* get stuff from the stack */
832
833         m    = (methodinfo *) *((ptrint *) (sp + 2 * 8));
834         disp =                *((s4 *)     (sp + 1 * 8));
835         pv   = (u1 *)         *((ptrint *) (sp + 0 * 8));
836
837         /* resolve native function */
838
839         if (!(f = native_resolve_function(m)))
840                 return false;
841
842         /* patch native function pointer */
843
844         *((ptrint *) (pv + disp)) = (ptrint) f;
845
846         /* synchronize data cache */
847
848         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
849
850         return true;
851 }
852 #endif /* !defined(WITH_STATIC_CLASSPATH) */
853
854
855 /*
856  * These are local overrides for various environment variables in Emacs.
857  * Please do not remove this and leave it at the end of the file, where
858  * Emacs will automagically detect them.
859  * ---------------------------------------------------------------------
860  * Local variables:
861  * mode: c
862  * indent-tabs-mode: t
863  * c-basic-offset: 4
864  * tab-width: 4
865  * End:
866  * vim:noexpandtab:sw=4:ts=4:
867  */