7f40104deac872ffb8dbab5b7126c4147c597363
[cacao.git] / src / vm / jit / powerpc / patcher.c
1 /* src/vm/jit/powerpc/patcher.c - PowerPC code patching functions
2
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
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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: patcher.c 3869 2005-12-03 16:09:05Z twisti $
32
33 */
34
35
36 #include "config.h"
37 #include "vm/types.h"
38
39 #include "mm/memory.h"
40 #include "native/native.h"
41 #include "vm/builtin.h"
42 #include "vm/class.h"
43 #include "vm/field.h"
44 #include "vm/initialize.h"
45 #include "vm/options.h"
46 #include "vm/resolve.h"
47 #include "vm/references.h"
48 #include "vm/jit/asmpart.h"
49 #include "vm/jit/patcher.h"
50
51
52 /* patcher_get_putstatic *******************************************************
53
54    Machine code:
55
56    <patched call position>
57    816dffc8    lwz   r11,-56(r13)
58    80ab0000    lwz   r5,0(r11)
59
60 *******************************************************************************/
61
62 bool patcher_get_putstatic(u1 *sp)
63 {
64         u1                *ra;
65         java_objectheader *o;
66         u4                 mcode;
67         unresolved_field  *uf;
68         s4                 disp;
69         u1                *pv;
70         fieldinfo         *fi;
71
72         /* get stuff from the stack */
73
74         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
75         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
76         mcode =                       *((u4 *)     (sp + 3 * 4));
77         uf    = (unresolved_field *)  *((ptrint *) (sp + 2 * 4));
78         disp  =                       *((s4 *)     (sp + 1 * 4));
79         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
80
81         PATCHER_MONITORENTER;
82
83         /* get the fieldinfo */
84
85         if (!(fi = resolve_field_eager(uf))) {
86                 PATCHER_MONITOREXIT;
87
88                 return false;
89         }
90
91         /* check if the field's class is initialized */
92
93         if (!(fi->class->state & CLASS_INITIALIZED)) {
94                 if (!initialize_class(fi->class)) {
95                         PATCHER_MONITOREXIT;
96
97                         return false;
98                 }
99         }
100
101         /* patch back original code */
102
103         *((u4 *) ra) = mcode;
104
105         /* synchronize instruction cache */
106
107         asm_cacheflush(ra, 4);
108
109         /* patch the field value's address */
110
111         *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
112
113         PATCHER_MARK_PATCHED_MONITOREXIT;
114
115         return true;
116 }
117
118
119 /* patcher_get_putfield ********************************************************
120
121    Machine code:
122
123    <patched call position>
124    811f0014    lwz   r8,20(r31)
125
126 *******************************************************************************/
127
128 bool patcher_get_putfield(u1 *sp)
129 {
130         u1                *ra;
131         java_objectheader *o;
132         u4                 mcode;
133         unresolved_field  *uf;
134         u1                *pv;
135         fieldinfo         *fi;
136
137         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
138         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
139         mcode =                       *((u4 *)     (sp + 3 * 4));
140         uf    = (unresolved_field *)  *((ptrint *) (sp + 2 * 4));
141         pv    = (u1 *)                *((ptrint *) (sp + 1 * 4));
142
143         PATCHER_MONITORENTER;
144
145         /* get the fieldinfo */
146
147         if (!(fi = resolve_field_eager(uf))) {
148                 PATCHER_MONITOREXIT;
149
150                 return false;
151         }
152
153         /* patch back original code */
154
155         *((u4 *) ra) = mcode;
156
157         /* if we show disassembly, we have to skip the nop */
158
159         if (opt_showdisassemble)
160                 ra = ra + 4;
161
162         /* patch the field's offset */
163
164         if (fi->type == TYPE_LNG) {
165                 /* if the field has type long, we have to patch two instructions */
166
167                 *((u4 *) ra) |= (s2) ((fi->offset + 4) & 0x0000ffff);
168                 *((u4 *) (ra + 4)) |= (s2) (fi->offset & 0x0000ffff);
169
170         } else {
171                 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
172         }
173
174         /* synchronize instruction cache */
175
176         asm_cacheflush(ra, 8);
177
178         PATCHER_MARK_PATCHED_MONITOREXIT;
179
180         return true;
181 }
182
183
184 /* patcher_aconst **************************************************************
185
186    Machine code:
187
188    <patched call postition>
189    806dffc4    lwz   r3,-60(r13)
190    81adffc0    lwz   r13,-64(r13)
191    7da903a6    mtctr r13
192    4e800421    bctrl
193
194 *******************************************************************************/
195
196 bool patcher_aconst(u1 *sp)
197 {
198         u1                *ra;
199         java_objectheader *o;
200         u4                 mcode;
201         constant_classref *cr;
202         s4                 disp;
203         u1                *pv;
204         classinfo         *c;
205
206         /* get stuff from the stack */
207
208         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
209         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
210         mcode =                       *((u4 *)     (sp + 3 * 4));
211         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
212         disp  =                       *((s4 *)     (sp + 1 * 4));
213         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
214
215         PATCHER_MONITORENTER;
216
217         /* get the classinfo */
218
219         if (!(c = resolve_classref_eager(cr))) {
220                 PATCHER_MONITOREXIT;
221
222                 return false;
223         }
224
225         /* patch back original code */
226
227         *((u4 *) ra) = mcode;
228
229         /* synchronize instruction cache */
230
231         asm_cacheflush(ra, 4);
232
233         /* patch the classinfo pointer */
234
235         *((ptrint *) (pv + disp)) = (ptrint) c;
236
237         PATCHER_MARK_PATCHED_MONITOREXIT;
238
239         return true;
240 }
241
242
243 /* patcher_builtin_multianewarray **********************************************
244
245    Machine code:
246
247    <patched call position>
248    808dffc0    lwz   r4,-64(r13)
249    38a10038    addi  r5,r1,56
250    81adffbc    lwz   r13,-68(r13)
251    7da903a6    mtctr r13
252    4e800421    bctrl
253
254 *******************************************************************************/
255
256 bool patcher_builtin_multianewarray(u1 *sp)
257 {
258         u1                *ra;
259         java_objectheader *o;
260         u4                 mcode;
261         constant_classref *cr;
262         s4                 disp;
263         u1                *pv;
264         classinfo         *c;
265
266         /* get stuff from the stack */
267
268         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
269         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
270         mcode =                       *((u4 *)     (sp + 3 * 4));
271         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
272         disp  =                       *((s4 *)     (sp + 1 * 4));
273         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
274
275         PATCHER_MONITORENTER;
276
277         /* get the classinfo */
278
279         if (!(c = resolve_classref_eager(cr))) {
280                 PATCHER_MONITOREXIT;
281
282                 return false;
283         }
284
285         /* patch back original code */
286
287         *((u4 *) ra) = mcode;
288
289         /* synchronize instruction cache */
290
291         asm_cacheflush(ra, 4);
292
293         /* patch the classinfo pointer */
294
295         *((ptrint *) (pv + disp)) = (ptrint) c;
296
297         PATCHER_MARK_PATCHED_MONITOREXIT;
298
299         return true;
300 }
301
302
303 /* patcher_builtin_arraycheckcast **********************************************
304
305    Machine code:
306
307    <patched call position>
308    808dffd8    lwz   r4,-40(r13)
309    81adffd4    lwz   r13,-44(r13)
310    7da903a6    mtctr r13
311    4e800421    bctrl
312
313 *******************************************************************************/
314
315 bool patcher_builtin_arraycheckcast(u1 *sp)
316 {
317         u1                *ra;
318         java_objectheader *o;
319         u4                 mcode;
320         constant_classref *cr;
321         s4                 disp;
322         u1                *pv;
323         classinfo         *c;
324
325         /* get stuff from the stack */
326
327         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
328         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
329         mcode =                       *((u4 *)     (sp + 3 * 4));
330         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
331         disp  =                       *((s4 *)     (sp + 1 * 4));
332         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
333
334         PATCHER_MONITORENTER;
335
336         /* get the classinfo */
337
338         if (!(c = resolve_classref_eager(cr))) {
339                 PATCHER_MONITOREXIT;
340
341                 return false;
342         }
343
344         /* patch back original code */
345
346         *((u4 *) ra) = mcode;
347
348         /* synchronize instruction cache */
349
350         asm_cacheflush(ra, 4);
351
352         /* patch the classinfo pointer */
353
354         *((ptrint *) (pv + disp)) = (ptrint) c;
355
356         PATCHER_MARK_PATCHED_MONITOREXIT;
357
358         return true;
359 }
360
361
362 /* patcher_invokestatic_special ************************************************
363
364    Machine code:
365
366    <patched call position>
367    81adffd8    lwz   r13,-40(r13)
368    7da903a6    mtctr r13
369    4e800421    bctrl
370
371 ******************************************************************************/
372
373 bool patcher_invokestatic_special(u1 *sp)
374 {
375         u1                *ra;
376         java_objectheader *o;
377         u4                 mcode;
378         unresolved_method *um;
379         s4                 disp;
380         u1                *pv;
381         methodinfo        *m;
382
383         /* get stuff from the stack */
384
385         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
386         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
387         mcode =                       *((u4 *)     (sp + 3 * 4));
388         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
389         disp  =                       *((s4 *)     (sp + 1 * 4));
390         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
391
392         PATCHER_MONITORENTER;
393
394         /* get the fieldinfo */
395
396         if (!(m = resolve_method_eager(um))) {
397                 PATCHER_MONITOREXIT;
398
399                 return false;
400         }
401
402         /* patch back original code */
403
404         *((u4 *) ra) = mcode;
405
406         /* synchronize instruction cache */
407
408         asm_cacheflush(ra, 4);
409
410         /* patch stubroutine */
411
412         *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
413
414         PATCHER_MARK_PATCHED_MONITOREXIT;
415
416         return true;
417 }
418
419
420 /* patcher_invokevirtual *******************************************************
421
422    Machine code:
423
424    <patched call position>
425    81830000    lwz   r12,0(r3)
426    81ac0088    lwz   r13,136(r12)
427    7da903a6    mtctr r13
428    4e800421    bctrl
429
430 *******************************************************************************/
431
432 bool patcher_invokevirtual(u1 *sp)
433 {
434         u1                *ra;
435         java_objectheader *o;
436         u4                 mcode;
437         unresolved_method *um;
438         methodinfo        *m;
439
440         /* get stuff from the stack */
441
442         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
443         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
444         mcode =                       *((u4 *)     (sp + 3 * 4));
445         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
446
447         PATCHER_MONITORENTER;
448
449         /* get the fieldinfo */
450
451         if (!(m = resolve_method_eager(um))) {
452                 PATCHER_MONITOREXIT;
453
454                 return false;
455         }
456
457         /* patch back original code */
458
459         *((u4 *) ra) = mcode;
460
461         /* if we show disassembly, we have to skip the nop */
462
463         if (opt_showdisassemble)
464                 ra = ra + 4;
465
466         /* patch vftbl index */
467
468         *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
469                                                                  sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
470
471         /* synchronize instruction cache */
472
473         asm_cacheflush(ra, 2 * 4);
474
475         PATCHER_MARK_PATCHED_MONITOREXIT;
476
477         return true;
478 }
479
480
481 /* patcher_invokeinterface *****************************************************
482
483    Machine code:
484
485    <patched call position>
486    81830000    lwz   r12,0(r3)
487    818cffd0    lwz   r12,-48(r12)
488    81ac000c    lwz   r13,12(r12)
489    7da903a6    mtctr r13
490    4e800421    bctrl
491
492 *******************************************************************************/
493
494 bool patcher_invokeinterface(u1 *sp)
495 {
496         u1                *ra;
497         java_objectheader *o;
498         u4                 mcode;
499         unresolved_method *um;
500         methodinfo        *m;
501
502         /* get stuff from the stack */
503
504         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
505         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
506         mcode =                       *((u4 *)     (sp + 3 * 4));
507         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
508
509         PATCHER_MONITORENTER;
510
511         /* get the fieldinfo */
512
513         if (!(m = resolve_method_eager(um))) {
514                 PATCHER_MONITOREXIT;
515
516                 return false;
517         }
518
519         /* patch back original code */
520
521         *((u4 *) ra) = mcode;
522
523         /* if we show disassembly, we have to skip the nop */
524
525         if (opt_showdisassemble)
526                 ra = ra + 4;
527
528         /* patch interfacetable index */
529
530         *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
531                                                                  sizeof(methodptr*) * m->class->index) & 0x0000ffff);
532
533         /* patch method offset */
534
535         *((s4 *) (ra + 2 * 4)) |=
536                 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
537
538         /* synchronize instruction cache */
539
540         asm_cacheflush(ra, 3 * 4);
541
542         PATCHER_MARK_PATCHED_MONITOREXIT;
543
544         return true;
545 }
546
547
548 /* patcher_checkcast_instanceof_flags ******************************************
549
550    Machine code:
551
552    <patched call position>
553    818dff7c    lwz   r12,-132(r13)
554
555 *******************************************************************************/
556
557 bool patcher_checkcast_instanceof_flags(u1 *sp)
558 {
559         u1                *ra;
560         java_objectheader *o;
561         u4                 mcode;
562         constant_classref *cr;
563         s4                 disp;
564         u1                *pv;
565         classinfo         *c;
566
567         /* get stuff from the stack */
568
569         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
570         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
571         mcode =                       *((u4 *)     (sp + 3 * 4));
572         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
573         disp  =                       *((s4 *)     (sp + 1 * 4));
574         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
575
576         PATCHER_MONITORENTER;
577
578         /* get the fieldinfo */
579
580         if (!(c = resolve_classref_eager(cr))) {
581                 PATCHER_MONITOREXIT;
582
583                 return false;
584         }
585
586         /* patch back original code */
587
588         *((u4 *) ra) = mcode;
589
590         /* synchronize instruction cache */
591
592         asm_cacheflush(ra, 4);
593
594         /* patch class flags */
595
596         *((s4 *) (pv + disp)) = (s4) c->flags;
597
598         PATCHER_MARK_PATCHED_MONITOREXIT;
599
600         return true;
601 }
602
603
604 /* patcher_checkcast_instanceof_interface **************************************
605
606    Machine code:
607
608    <patched call position>
609    81870000    lwz   r12,0(r7)
610    800c0010    lwz   r0,16(r12)
611    34000000    addic.        r0,r0,0
612    408101fc    ble-  0x3002e518
613    800c0000    lwz   r0,0(r12)
614
615 *******************************************************************************/
616
617 bool patcher_checkcast_instanceof_interface(u1 *sp)
618 {
619         u1                *ra;
620         java_objectheader *o;
621         u4                 mcode;
622         constant_classref *cr;
623         classinfo         *c;
624
625         /* get stuff from the stack */
626
627         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
628         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
629         mcode =                       *((u4 *)     (sp + 3 * 4));
630         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
631
632         PATCHER_MONITORENTER;
633
634         /* get the fieldinfo */
635
636         if (!(c = resolve_classref_eager(cr))) {
637                 PATCHER_MONITOREXIT;
638
639                 return false;
640         }
641
642         /* patch back original code */
643
644         *((u4 *) ra) = mcode;
645
646         /* if we show disassembly, we have to skip the nop */
647
648         if (opt_showdisassemble)
649                 ra = ra + 4;
650
651         /* patch super class index */
652
653         *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
654
655         *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
656                                                                          c->index * sizeof(methodptr*)) & 0x0000ffff);
657
658         /* synchronize instruction cache */
659
660         asm_cacheflush(ra, 5 * 4);
661
662         PATCHER_MARK_PATCHED_MONITOREXIT;
663
664         return true;
665 }
666
667
668 /* patcher_checkcast_class *****************************************************
669
670    Machine code:
671
672    <patched call position>
673    81870000    lwz   r12,0(r7)
674    800c0014    lwz   r0,20(r12)
675    818dff78    lwz   r12,-136(r13)
676
677 *******************************************************************************/
678
679 bool patcher_checkcast_class(u1 *sp)
680 {
681         u1                *ra;
682         java_objectheader *o;
683         u4                 mcode;
684         constant_classref *cr;
685         s4                 disp;
686         u1                *pv;
687         classinfo         *c;
688
689         /* get stuff from the stack */
690
691         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
692         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
693         mcode =                       *((u4 *)     (sp + 3 * 4));
694         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
695         disp  =                       *((s4 *)     (sp + 1 * 4));
696         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
697
698         PATCHER_MONITORENTER;
699
700         /* get the fieldinfo */
701
702         if (!(c = resolve_classref_eager(cr))) {
703                 PATCHER_MONITOREXIT;
704
705                 return false;
706         }
707
708         /* patch back original code */
709
710         *((u4 *) ra) = mcode;
711
712         /* synchronize instruction cache */
713
714         asm_cacheflush(ra, 4);
715
716         /* patch super class' vftbl */
717
718         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
719
720         PATCHER_MARK_PATCHED_MONITOREXIT;
721
722         return true;
723 }
724
725
726 /* patcher_instanceof_class ****************************************************
727
728    Machine code:
729
730    <patched call position>
731    817d0000    lwz   r11,0(r29)
732    818dff8c    lwz   r12,-116(r13)
733
734 *******************************************************************************/
735
736 bool patcher_instanceof_class(u1 *sp)
737 {
738         u1                *ra;
739         java_objectheader *o;
740         u4                 mcode;
741         constant_classref *cr;
742         s4                 disp;
743         u1                *pv;
744         classinfo         *c;
745
746         /* get stuff from the stack */
747
748         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
749         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
750         mcode =                       *((u4 *)     (sp + 3 * 4));
751         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
752         disp  =                       *((s4 *)     (sp + 1 * 4));
753         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
754
755         PATCHER_MONITORENTER;
756
757         /* get the fieldinfo */
758
759         if (!(c = resolve_classref_eager(cr))) {
760                 PATCHER_MONITOREXIT;
761
762                 return false;
763         }
764
765         /* patch back original code */
766
767         *((u4 *) ra) = mcode;
768
769         /* synchronize instruction cache */
770
771         asm_cacheflush(ra, 4);
772
773         /* patch super class' vftbl */
774
775         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
776
777         PATCHER_MARK_PATCHED_MONITOREXIT;
778
779         return true;
780 }
781
782
783 /* patcher_clinit **************************************************************
784
785    XXX
786
787 *******************************************************************************/
788
789 bool patcher_clinit(u1 *sp)
790 {
791         u1                *ra;
792         java_objectheader *o;
793         u4                 mcode;
794         classinfo         *c;
795
796         /* get stuff from the stack */
797
798         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
799         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
800         mcode =                       *((u4 *)     (sp + 3 * 4));
801         c     = (classinfo *)         *((ptrint *) (sp + 2 * 4));
802
803         PATCHER_MONITORENTER;
804
805         /* check if the class is initialized */
806
807         if (!(c->state & CLASS_INITIALIZED)) {
808                 if (!initialize_class(c)) {
809                         PATCHER_MONITOREXIT;
810
811                         return false;
812                 }
813         }
814
815         /* patch back original code */
816
817         *((u4 *) ra) = mcode;
818
819         /* synchronize instruction cache */
820
821         asm_cacheflush(ra, 4);
822
823         PATCHER_MARK_PATCHED_MONITOREXIT;
824
825         return true;
826 }
827
828
829 /* patcher_athrow_areturn ******************************************************
830
831    Machine code:
832
833    <patched call position>
834
835 *******************************************************************************/
836
837 #ifdef ENABLE_VERIFIER
838 bool patcher_athrow_areturn(u1 *sp)
839 {
840         u1                *ra;
841         java_objectheader *o;
842         u4                 mcode;
843         unresolved_class  *uc;
844         classinfo         *c;
845
846         /* get stuff from the stack */
847
848         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
849         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
850         mcode =                       *((u4 *)     (sp + 3 * 4));
851         uc    = (unresolved_class *)  *((ptrint *) (sp + 2 * 4));
852
853         PATCHER_MONITORENTER;
854
855         /* resolve the class */
856
857         if (!resolve_class(uc, resolveEager, false, &c)) {
858                 PATCHER_MONITOREXIT;
859
860                 return false;
861         }
862
863         /* patch back original code */
864
865         *((u4 *) ra) = mcode;
866
867         /* synchronize instruction cache */
868
869         asm_cacheflush(ra, 4);
870
871         PATCHER_MARK_PATCHED_MONITOREXIT;
872
873         return true;
874 }
875 #endif /* ENABLE_VERIFIER */
876
877
878 /* patcher_resolve_native ******************************************************
879
880    XXX
881
882 *******************************************************************************/
883
884 #if !defined(ENABLE_STATICVM)
885 bool patcher_resolve_native(u1 *sp)
886 {
887         u1                *ra;
888         java_objectheader *o;
889         u4                 mcode;
890         methodinfo        *m;
891         s4                 disp;
892         u1                *pv;
893         functionptr        f;
894
895         /* get stuff from the stack */
896
897         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
898         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
899         mcode =                       *((u4 *)     (sp + 3 * 4));
900         m     = (methodinfo *)        *((ptrint *) (sp + 2 * 4));
901         disp  =                       *((s4 *)     (sp + 1 * 4));
902         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
903
904         /* calculate and set the new return address */
905
906         ra = ra - 1 * 4;
907         *((ptrint *) (sp + 5 * 4)) = (ptrint) ra;
908
909         PATCHER_MONITORENTER;
910
911         /* resolve native function */
912
913         if (!(f = native_resolve_function(m))) {
914                 PATCHER_MONITOREXIT;
915
916                 return false;
917         }
918
919         /* patch back original code */
920
921         *((u4 *) ra) = mcode;
922
923         /* synchronize instruction cache */
924
925         asm_cacheflush(ra, 4);
926
927         /* patch native function pointer */
928
929         *((ptrint *) (pv + disp)) = (ptrint) f;
930
931         PATCHER_MARK_PATCHED_MONITOREXIT;
932
933         return true;
934 }
935 #endif /* !defined(ENABLE_STATICVM) */
936
937
938 /*
939  * These are local overrides for various environment variables in Emacs.
940  * Please do not remove this and leave it at the end of the file, where
941  * Emacs will automagically detect them.
942  * ---------------------------------------------------------------------
943  * Local variables:
944  * mode: c
945  * indent-tabs-mode: t
946  * c-basic-offset: 4
947  * tab-width: 4
948  * End:
949  * vim:noexpandtab:sw=4:ts=4:
950  */