replace helper_* calls in the pathers with calls to resolve_*_eager
[cacao.git] / src / vm / jit / alpha / patcher.c
1 /* src/vm/jit/alpha/patcher.c - Alpha 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 3461 2005-10-20 09:53:00Z edwin $
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/field.h"
43 #include "vm/initialize.h"
44 #include "vm/options.h"
45 #include "vm/references.h"
46 #include "vm/jit/asmpart.h"
47 #include "vm/jit/helper.h"
48 #include "vm/jit/patcher.h"
49
50
51 /* patcher_get_putstatic *******************************************************
52
53    Machine code:
54
55    <patched call position>
56    a73bff98    ldq     t11,-104(pv)
57    a2590000    ldl     a2,0(t11)
58
59 *******************************************************************************/
60
61 bool patcher_get_putstatic(u1 *sp)
62 {
63         u1                *ra;
64         java_objectheader *o;
65         u4                 mcode;
66         unresolved_field  *uf;
67         s4                 disp;
68         u1                *pv;
69         fieldinfo         *fi;
70
71         /* get stuff from the stack */
72
73         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
74         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
75         mcode =                       *((u4 *)     (sp + 3 * 8));
76         uf    = (unresolved_field *)  *((ptrint *) (sp + 2 * 8));
77         disp  =                       *((s4 *)     (sp + 1 * 8));
78         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
79
80         /* calculate and set the new return address */
81
82         ra = ra - 1 * 4;
83         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
84
85         PATCHER_MONITORENTER;
86
87         /* get the fieldinfo */
88
89         if (!(fi = resolve_field_eager(uf))) {
90                 PATCHER_MONITOREXIT;
91
92                 return false;
93         }
94
95         /* check if the field's class is initialized */
96
97         if (!fi->class->initialized) {
98                 if (!initialize_class(fi->class)) {
99                         PATCHER_MONITOREXIT;
100
101                         return false;
102                 }
103         }
104
105         /* patch back original code */
106
107         *((u4 *) ra) = mcode;
108
109         /* synchronize instruction cache */
110
111         asm_sync_instruction_cache();
112
113         /* patch the field value's address */
114
115         *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
116
117         PATCHER_MARK_PATCHED_MONITOREXIT;
118
119         return true;
120 }
121
122
123 /* patcher_get_putfield ********************************************************
124
125    Machine code:
126
127    <patched call position>
128    a2af0020    ldl     a5,32(s6)
129
130 *******************************************************************************/
131
132 bool patcher_get_putfield(u1 *sp)
133 {
134         u1                *ra;
135         java_objectheader *o;
136         u4                 mcode;
137         unresolved_field  *uf;
138         fieldinfo         *fi;
139
140         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
141         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
142         mcode =                       *((u4 *)     (sp + 3 * 8));
143         uf    = (unresolved_field *)  *((ptrint *) (sp + 2 * 8));
144
145         /* calculate and set the new return address */
146
147         ra = ra - 1 * 4;
148         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
149
150         PATCHER_MONITORENTER;
151
152         /* get the fieldinfo */
153
154         if (!(fi = resolve_field_eager(uf))) {
155                 PATCHER_MONITOREXIT;
156
157                 return false;
158         }
159
160         /* patch back original code */
161
162         *((u4 *) ra) = mcode;
163
164         /* if we show disassembly, we have to skip the nop */
165
166         if (opt_showdisassemble)
167                 ra = ra + 4;
168
169         /* patch the field's offset */
170
171         *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
172
173         /* synchronize instruction cache */
174
175         asm_sync_instruction_cache();
176
177         PATCHER_MARK_PATCHED_MONITOREXIT;
178
179         return true;
180 }
181
182
183 /* patcher_builtin_new *********************************************************
184
185    Machine code:
186
187    a61bff80    ldq     a0,-128(pv)
188    <patched call postition>
189    a77bff78    ldq     pv,-136(pv)
190    6b5b4000    jsr     (pv)
191
192    NOTICE: Only the displacement for the function address is passed,
193    but the address of the classinfo pointer is one below (above, in
194    addresses speaking). This is for sure.
195
196 *******************************************************************************/
197
198 bool patcher_builtin_new(u1 *sp)
199 {
200         u1                *ra;
201         java_objectheader *o;
202         u4                 mcode;
203         constant_classref *cr;
204         s4                 disp;
205         u1                *pv;
206         classinfo         *c;
207
208         /* get stuff from the stack */
209
210         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
211         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
212         mcode =                       *((u4 *)     (sp + 3 * 8));
213         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
214         disp  =                       *((s4 *)     (sp + 1 * 8));
215         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
216
217         /* calculate and set the new return address */
218
219         ra = ra - 2 * 4;
220         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
221
222         PATCHER_MONITORENTER;
223
224         /* get the classinfo */
225
226         if (!(c = resolve_classref_eager_nonabstract(cr))) {
227                 PATCHER_MONITOREXIT;
228
229                 return false;
230         }
231
232         /* patch back original code */
233
234         *((u4 *) (ra + 4)) = mcode;
235
236         /* synchronize instruction cache */
237
238         asm_sync_instruction_cache();
239
240         /* patch the classinfo pointer */
241
242         *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c;
243
244         /* patch new function address */
245
246         *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_new;
247
248         PATCHER_MARK_PATCHED_MONITOREXIT;
249
250         return true;
251 }
252
253
254 /* patcher_builtin_newarray ****************************************************
255
256    Machine code:
257
258    a63bff88    ldq     a1,-120(pv)
259    <patched call position>
260    a77bff80    ldq     pv,-128(pv)
261    6b5b4000    jsr     (pv)
262
263    NOTICE: Only the displacement for the function address is passed,
264    but the address of the classinfo pointer is one below (above, in
265    addresses speaking). This is for sure.
266
267 *******************************************************************************/
268
269 bool patcher_builtin_newarray(u1 *sp)
270 {
271         u1                *ra;
272         java_objectheader *o;
273         u4                 mcode;
274         constant_classref *cr;
275         s4                 disp;
276         u1                *pv;
277         classinfo         *c;
278
279         /* get stuff from the stack */
280
281         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
282         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
283         mcode =                       *((u4 *)     (sp + 3 * 8));
284         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
285         disp  =                       *((s4 *)     (sp + 1 * 8));
286         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
287
288         /* calculate and set the new return address */
289
290         ra = ra - 2 * 4;
291         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
292
293         PATCHER_MONITORENTER;
294
295         /* get the classinfo */
296
297         if (!(c = resolve_classref_eager(cr))) {
298                 PATCHER_MONITOREXIT;
299
300                 return false;
301         }
302
303         /* patch back original code */
304
305         *((u4 *) (ra + 4)) = mcode;
306
307         /* synchronize instruction cache */
308
309         asm_sync_instruction_cache();
310
311         /* patch the class' vftbl pointer */
312
313         *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
314
315         /* patch new function address */
316
317         *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_newarray;
318
319         PATCHER_MARK_PATCHED_MONITOREXIT;
320
321         return true;
322 }
323
324
325 /* patcher_builtin_multianewarray **********************************************
326
327    Machine code:
328
329    <patched call position>
330    a63bff80    ldq     a1,-128(pv)
331    47de0412    mov     sp,a2
332    a77bff78    ldq     pv,-136(pv)
333    6b5b4000    jsr     (pv)
334
335 *******************************************************************************/
336
337 bool patcher_builtin_multianewarray(u1 *sp)
338 {
339         u1                *ra;
340         java_objectheader *o;
341         u4                 mcode;
342         constant_classref *cr;
343         s4                 disp;
344         u1                *pv;
345         classinfo         *c;
346
347         /* get stuff from the stack */
348
349         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
350         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
351         mcode =                       *((u4 *)     (sp + 3 * 8));
352         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
353         disp  =                       *((s4 *)     (sp + 1 * 8));
354         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
355
356         /* calculate and set the new return address */
357
358         ra = ra - 1 * 4;
359         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
360
361         PATCHER_MONITORENTER;
362
363         /* get the classinfo */
364
365         if (!(c = resolve_classref_eager(cr))) {
366                 PATCHER_MONITOREXIT;
367
368                 return false;
369         }
370
371         /* patch back original code */
372
373         *((u4 *) ra) = mcode;
374
375         /* synchronize instruction cache */
376
377         asm_sync_instruction_cache();
378
379         /* patch the class' vftbl pointer */
380
381         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
382
383         PATCHER_MARK_PATCHED_MONITOREXIT;
384
385         return true;
386 }
387
388
389 /* patcher_builtin_arraycheckcast **********************************************
390
391    Machine code:
392
393    <patched call position>
394    a63bfe60    ldq     a1,-416(pv)
395    a77bfe58    ldq     pv,-424(pv)
396    6b5b4000    jsr     (pv)
397
398    NOTICE: Only the displacement of the vftbl pointer address is
399    passed, but the address of the function pointer is one above
400    (below, in addresses speaking). This is for sure.
401
402 *******************************************************************************/
403
404 bool patcher_builtin_arraycheckcast(u1 *sp)
405 {
406         u1                *ra;
407         java_objectheader *o;
408         u4                 mcode;
409         constant_classref *cr;
410         s4                 disp;
411         u1                *pv;
412         classinfo         *c;
413
414         /* get stuff from the stack */
415
416         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
417         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
418         mcode =                       *((u4 *)     (sp + 3 * 8));
419         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
420         disp  =                       *((s4 *)     (sp + 1 * 8));
421         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
422
423         /* calculate and set the new return address */
424
425         ra = ra - 1 * 4;
426         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
427
428         PATCHER_MONITORENTER;
429
430         /* get the classinfo */
431
432         if (!(c = resolve_classref_eager(cr))) {
433                 PATCHER_MONITOREXIT;
434
435                 return false;
436         }
437
438         /* patch back original code */
439
440         *((u4 *) ra) = mcode;
441
442         /* synchronize instruction cache */
443
444         asm_sync_instruction_cache();
445
446         /* patch the class' vftbl pointer */
447
448         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
449
450         /* patch new function address */
451
452         *((ptrint *) (pv + (disp - SIZEOF_VOID_P))) =
453                 (ptrint) BUILTIN_arraycheckcast;
454
455         PATCHER_MARK_PATCHED_MONITOREXIT;
456
457         return true;
458 }
459
460
461 /* patcher_builtin_arrayinstanceof *********************************************
462
463    Machine code:
464
465    a63bfeb0    ldq     a1,-336(pv)
466    <patched call position>
467    a77bfea8    ldq     pv,-344(pv)
468    6b5b4000    jsr     (pv)
469
470    NOTICE: Only the displacement for the function address is passed,
471    but the address of the vftbl pointer is one below (above, in
472    addresses speaking). This is for sure.
473
474 *******************************************************************************/
475
476 bool patcher_builtin_arrayinstanceof(u1 *sp)
477 {
478         u1                *ra;
479         java_objectheader *o;
480         u4                 mcode;
481         constant_classref *cr;
482         s4                 disp;
483         u1                *pv;
484         classinfo         *c;
485
486         /* get stuff from the stack */
487
488         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
489         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
490         mcode =                       *((u4 *)     (sp + 3 * 8));
491         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
492         disp  =                       *((s4 *)     (sp + 1 * 8));
493         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
494
495         /* calculate and set the new return address */
496
497         ra = ra - 2 * 4;
498         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
499
500         PATCHER_MONITORENTER;
501
502         /* get the classinfo */
503
504         if (!(c = resolve_classref_eager(cr))) {
505                 PATCHER_MONITOREXIT;
506
507                 return false;
508         }
509
510         /* patch back original code */
511
512         *((u4 *) (ra + 4)) = mcode;
513
514         /* synchronize instruction cache */
515
516         asm_sync_instruction_cache();
517
518         /* patch the class' vftbl pointer */
519         
520         *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
521
522         /* patch new function address */
523
524         *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_arrayinstanceof;
525
526         PATCHER_MARK_PATCHED_MONITOREXIT;
527
528         return true;
529 }
530
531
532 /* patcher_invokestatic_special ************************************************
533
534    Machine code:
535
536    <patched call position>
537    a77bffa8    ldq     pv,-88(pv)
538    6b5b4000    jsr     (pv)
539
540 ******************************************************************************/
541
542 bool patcher_invokestatic_special(u1 *sp)
543 {
544         u1                *ra;
545         java_objectheader *o;
546         u4                 mcode;
547         unresolved_method *um;
548         s4                 disp;
549         u1                *pv;
550         methodinfo        *m;
551
552         /* get stuff from the stack */
553
554         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
555         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
556         mcode =                       *((u4 *)     (sp + 3 * 8));
557         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
558         disp  =                       *((s4 *)     (sp + 1 * 8));
559         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
560
561         /* calculate and set the new return address */
562
563         ra = ra - 1 * 4;
564         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
565
566         PATCHER_MONITORENTER;
567
568         /* get the fieldinfo */
569
570         if (!(m = resolve_method_eager(um))) {
571                 PATCHER_MONITOREXIT;
572
573                 return false;
574         }
575
576         /* patch back original code */
577
578         *((u4 *) ra) = mcode;
579
580         /* synchronize instruction cache */
581
582         asm_sync_instruction_cache();
583
584         /* patch stubroutine */
585
586         *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
587
588         PATCHER_MARK_PATCHED_MONITOREXIT;
589
590         return true;
591 }
592
593
594 /* patcher_invokevirtual *******************************************************
595
596    Machine code:
597
598    <patched call position>
599    a7900000    ldq     at,0(a0)
600    a77c0100    ldq     pv,256(at)
601    6b5b4000    jsr     (pv)
602
603 *******************************************************************************/
604
605 bool patcher_invokevirtual(u1 *sp)
606 {
607         u1                *ra;
608         java_objectheader *o;
609         u4                 mcode;
610         unresolved_method *um;
611         methodinfo        *m;
612
613         /* get stuff from the stack */
614
615         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
616         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
617         mcode =                       *((u4 *)     (sp + 3 * 8));
618         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
619
620         /* calculate and set the new return address */
621
622         ra = ra - 1 * 4;
623         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
624
625         PATCHER_MONITORENTER;
626
627         /* get the fieldinfo */
628
629         if (!(m = resolve_method_eager(um))) {
630                 PATCHER_MONITOREXIT;
631
632                 return false;
633         }
634
635         /* patch back original code */
636
637         *((u4 *) ra) = mcode;
638
639         /* if we show disassembly, we have to skip the nop */
640
641         if (opt_showdisassemble)
642                 ra = ra + 4;
643
644         /* patch vftbl index */
645
646         *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
647                                                                  sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
648
649         /* synchronize instruction cache */
650
651         asm_sync_instruction_cache();
652
653         PATCHER_MARK_PATCHED_MONITOREXIT;
654
655         return true;
656 }
657
658
659 /* patcher_invokeinterface *****************************************************
660
661    Machine code:
662
663    <patched call position>
664    a7900000    ldq     at,0(a0)
665    a79cffa0    ldq     at,-96(at)
666    a77c0018    ldq     pv,24(at)
667    6b5b4000    jsr     (pv)
668
669 *******************************************************************************/
670
671 bool patcher_invokeinterface(u1 *sp)
672 {
673         u1                *ra;
674         java_objectheader *o;
675         u4                 mcode;
676         unresolved_method *um;
677         methodinfo        *m;
678
679         /* get stuff from the stack */
680
681         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
682         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
683         mcode =                       *((u4 *)     (sp + 3 * 8));
684         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
685
686         /* calculate and set the new return address */
687
688         ra = ra - 1 * 4;
689         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
690
691         PATCHER_MONITORENTER;
692
693         /* get the fieldinfo */
694
695         if (!(m = resolve_method_eager(um))) {
696                 PATCHER_MONITOREXIT;
697
698                 return false;
699         }
700
701         /* patch back original code */
702
703         *((u4 *) ra) = mcode;
704
705         /* if we show disassembly, we have to skip the nop */
706
707         if (opt_showdisassemble)
708                 ra = ra + 4;
709
710         /* patch interfacetable index */
711
712         *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
713                                                                  sizeof(methodptr*) * m->class->index) & 0x0000ffff);
714
715         /* patch method offset */
716
717         *((s4 *) (ra + 4 + 4)) |=
718                 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
719
720         /* synchronize instruction cache */
721
722         asm_sync_instruction_cache();
723
724         PATCHER_MARK_PATCHED_MONITOREXIT;
725
726         return true;
727 }
728
729
730 /* patcher_checkcast_instanceof_flags ******************************************
731
732    Machine code:
733
734    <patched call position>
735
736 *******************************************************************************/
737
738 bool patcher_checkcast_instanceof_flags(u1 *sp)
739 {
740         u1                *ra;
741         java_objectheader *o;
742         u4                 mcode;
743         constant_classref *cr;
744         s4                 disp;
745         u1                *pv;
746         classinfo         *c;
747
748         /* get stuff from the stack */
749
750         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
751         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
752         mcode =                       *((u4 *)     (sp + 3 * 8));
753         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
754         disp  =                       *((s4 *)     (sp + 1 * 8));
755         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
756
757         /* calculate and set the new return address */
758
759         ra = ra - 1 * 4;
760         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
761
762         PATCHER_MONITORENTER;
763
764         /* get the fieldinfo */
765
766         if (!(c = resolve_classref_eager(cr))) {
767                 PATCHER_MONITOREXIT;
768
769                 return false;
770         }
771
772         /* patch back original code */
773
774         *((u4 *) ra) = mcode;
775
776         /* synchronize instruction cache */
777
778         asm_sync_instruction_cache();
779
780         /* patch class flags */
781
782         *((s4 *) (pv + disp)) = (s4) c->flags;
783
784         PATCHER_MARK_PATCHED_MONITOREXIT;
785
786         return true;
787 }
788
789
790 /* patcher_checkcast_instanceof_interface **************************************
791
792    Machine code:
793
794    <patched call position>
795    a78e0000    ldq     at,0(s5)
796    a3bc001c    ldl     gp,28(at)
797    23bdfffd    lda     gp,-3(gp)
798    efa0002e    ble     gp,0x00000200002bf6b0
799    a7bcffe8    ldq     gp,-24(at)
800
801 *******************************************************************************/
802
803 bool patcher_checkcast_instanceof_interface(u1 *sp)
804 {
805         u1                *ra;
806         java_objectheader *o;
807         u4                 mcode;
808         constant_classref *cr;
809         classinfo         *c;
810
811         /* get stuff from the stack */
812
813         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
814         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
815         mcode =                       *((u4 *)     (sp + 3 * 8));
816         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
817
818         /* calculate and set the new return address */
819
820         ra = ra - 1 * 4;
821         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
822
823         PATCHER_MONITORENTER;
824
825         /* get the fieldinfo */
826
827         if (!(c = resolve_classref_eager(cr))) {
828                 PATCHER_MONITOREXIT;
829
830                 return false;
831         }
832
833         /* patch back original code */
834
835         *((u4 *) ra) = mcode;
836
837         /* if we show disassembly, we have to skip the nop */
838
839         if (opt_showdisassemble)
840                 ra = ra + 4;
841
842         /* patch super class index */
843
844         *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
845
846         *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
847                                                                          c->index * sizeof(methodptr*)) & 0x0000ffff);
848
849         /* synchronize instruction cache */
850
851         asm_sync_instruction_cache();
852
853         PATCHER_MARK_PATCHED_MONITOREXIT;
854
855         return true;
856 }
857
858
859 /* patcher_checkcast_instanceof_class ******************************************
860
861    Machine code:
862
863    <patched call position>
864    a7940000    ldq     at,0(a4)
865    a7bbff28    ldq     gp,-216(pv)
866
867 *******************************************************************************/
868
869 bool patcher_checkcast_instanceof_class(u1 *sp)
870 {
871         u1                *ra;
872         java_objectheader *o;
873         u4                 mcode;
874         constant_classref *cr;
875         s4                 disp;
876         u1                *pv;
877         classinfo         *c;
878
879         /* get stuff from the stack */
880
881         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
882         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
883         mcode =                       *((u4 *)     (sp + 3 * 8));
884         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
885         disp  =                       *((s4 *)     (sp + 1 * 8));
886         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
887
888         /* calculate and set the new return address */
889
890         ra = ra - 1 * 4;
891         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
892
893         PATCHER_MONITORENTER;
894
895         /* get the fieldinfo */
896
897         if (!(c = resolve_classref_eager(cr))) {
898                 PATCHER_MONITOREXIT;
899
900                 return false;
901         }
902
903         /* patch back original code */
904
905         *((u4 *) ra) = mcode;
906
907         /* synchronize instruction cache */
908
909         asm_sync_instruction_cache();
910
911         /* patch super class' vftbl */
912
913         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
914
915         PATCHER_MARK_PATCHED_MONITOREXIT;
916
917         return true;
918 }
919
920
921 /* patcher_clinit **************************************************************
922
923    XXX
924
925 *******************************************************************************/
926
927 bool patcher_clinit(u1 *sp)
928 {
929         u1                *ra;
930         java_objectheader *o;
931         u4                 mcode;
932         classinfo         *c;
933
934         /* get stuff from the stack */
935
936         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
937         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
938         mcode =                       *((u4 *)     (sp + 3 * 8));
939         c     = (classinfo *)         *((ptrint *) (sp + 2 * 8));
940
941         /* calculate and set the new return address */
942
943         ra = ra - 1 * 4;
944         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
945
946         PATCHER_MONITORENTER;
947
948         /* check if the class is initialized */
949
950         if (!c->initialized) {
951                 if (!initialize_class(c)) {
952                         PATCHER_MONITOREXIT;
953
954                         return false;
955                 }
956         }
957
958         /* patch back original code */
959
960         *((u4 *) ra) = mcode;
961
962         /* synchronize instruction cache */
963
964         asm_sync_instruction_cache();
965
966         PATCHER_MARK_PATCHED_MONITOREXIT;
967
968         return true;
969 }
970
971
972 /* patcher_resolve_native ******************************************************
973
974    XXX
975
976 *******************************************************************************/
977
978 #if !defined(ENABLE_STATICVM)
979 bool patcher_resolve_native(u1 *sp)
980 {
981         u1                *ra;
982         java_objectheader *o;
983         u4                 mcode;
984         methodinfo        *m;
985         s4                 disp;
986         u1                *pv;
987         functionptr        f;
988
989         /* get stuff from the stack */
990
991         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
992         o     = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
993         mcode =                       *((u4 *)     (sp + 3 * 8));
994         m     = (methodinfo *)        *((ptrint *) (sp + 2 * 8));
995         disp  =                       *((s4 *)     (sp + 1 * 8));
996         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
997
998         /* calculate and set the new return address */
999
1000         ra = ra - 1 * 4;
1001         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1002
1003         PATCHER_MONITORENTER;
1004
1005         /* resolve native function */
1006
1007         if (!(f = native_resolve_function(m))) {
1008                 PATCHER_MONITOREXIT;
1009
1010                 return false;
1011         }
1012
1013         /* patch back original code */
1014
1015         *((u4 *) ra) = mcode;
1016
1017         /* synchronize instruction cache */
1018
1019         asm_sync_instruction_cache();
1020
1021         /* patch native function pointer */
1022
1023         *((ptrint *) (pv + disp)) = (ptrint) f;
1024
1025         PATCHER_MARK_PATCHED_MONITOREXIT;
1026
1027         return true;
1028 }
1029 #endif /* !defined(ENABLE_STATICVM) */
1030
1031
1032 /*
1033  * These are local overrides for various environment variables in Emacs.
1034  * Please do not remove this and leave it at the end of the file, where
1035  * Emacs will automagically detect them.
1036  * ---------------------------------------------------------------------
1037  * Local variables:
1038  * mode: c
1039  * indent-tabs-mode: t
1040  * c-basic-offset: 4
1041  * tab-width: 4
1042  * End:
1043  * vim:noexpandtab:sw=4:ts=4:
1044  */