* src/vm/jit/s390/emit.c,
[cacao.git] / src / vm / jit / s390 / patcher.c
1 /* src/vm/jit/x86_64/patcher.c - x86_64 code patching functions
2
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
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    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: patcher.c 7442 2007-03-02 23:28:37Z pm $
32
33 */
34
35
36 #include "config.h"
37 #include "vm/types.h"
38
39 #include "vm/jit/s390/codegen.h"
40
41 #include "mm/memory.h"
42 #include "native/native.h"
43 #include "vm/builtin.h"
44 #include "vmcore/class.h"
45 #include "vm/exceptions.h"
46 #include "vmcore/field.h"
47 #include "vm/initialize.h"
48 #include "vmcore/options.h"
49 #include "vmcore/references.h"
50 #include "vmcore/resolve.h"
51 #include "vm/jit/patcher.h"
52 #include "vm/jit/stacktrace.h"
53
54 #include <assert.h>
55 #define OOPS() assert(0);
56 #define __PORTED__
57
58 /* patcher_wrapper *************************************************************
59
60    Wrapper for all patchers.  It also creates the stackframe info
61    structure.
62
63    If the return value of the patcher function is false, it gets the
64    exception object, clears the exception pointer and returns the
65    exception.
66
67 *******************************************************************************/
68
69 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
70 {
71 #if 1
72         stackframeinfo     sfi;
73         u1                *xpc;
74         java_objectheader *o;
75         functionptr        f;
76         bool               result;
77         java_objectheader *e;
78
79         /* define the patcher function */
80
81         bool (*patcher_function)(u1 *);
82
83         /* get stuff from the stack */
84
85         xpc = (u1 *)                *((ptrint *) (sp + 5 * 4));
86         o   = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
87         f   = (functionptr)         *((ptrint *) (sp + 0 * 4));
88         
89         /* TODO here was PATCHER_CALL_SIZE previously ! */
90         xpc = xpc - 4; /* the patch position is 4 bytes before the RA */
91
92         *((ptrint *) (sp + 5 * 4)) = (ptrint) xpc;
93
94         /* store PV into the patcher function position */
95
96         *((ptrint *) (sp + 0 * 4)) = (ptrint) pv;
97
98         /* cast the passed function to a patcher function */
99
100         patcher_function = (bool (*)(u1 *)) (ptrint) f;
101
102         /* enter a monitor on the patching position */
103
104         PATCHER_MONITORENTER;
105
106         /* create the stackframeinfo */
107
108         /* RA is passed as NULL, but the XPC is correct and can be used in
109            stacktrace_create_extern_stackframeinfo for
110            md_codegen_get_pv_from_pc. */
111
112         stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + (6 * 4), ra, xpc);
113
114         /* call the proper patcher function */
115
116         result = (patcher_function)(sp);
117
118         /* remove the stackframeinfo */
119
120         stacktrace_remove_stackframeinfo(&sfi);
121
122         /* check for return value and exit accordingly */
123
124         if (result == false) {
125                 e = exceptions_get_and_clear_exception();
126
127                 PATCHER_MONITOREXIT;
128
129                 return e;
130         }
131
132         PATCHER_MARK_PATCHED_MONITOREXIT;
133
134         return NULL;
135 #else
136
137         stackframeinfo     sfi;
138         u1                *xpc;
139         java_objectheader *o;
140         u4                 mcode;
141         functionptr        f;
142         bool               result;
143         java_objectheader *e;
144
145         /* define the patcher function */
146
147         bool (*patcher_function)(u1 *);
148
149         assert(pv != NULL);
150
151         /* get stuff from the stack */
152
153         xpc = (u1 *)                *((ptrint *) (sp + 5 * 4));
154         o   = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
155         f   = (functionptr)         *((ptrint *) (sp + 0 * 4));
156
157         /* Correct RA is calculated in codegen.c and stored in the patcher
158            stub stack.  There's no need to adjust xpc. */
159
160         /* store PV into the patcher function position */
161
162         *((ptrint *) (sp + 0 * 4)) = (ptrint) pv;
163
164         /* cast the passed function to a patcher function */
165
166         patcher_function = (bool (*)(u1 *)) (ptrint) f;
167
168         /* enter a monitor on the patching position */
169
170         PATCHER_MONITORENTER;
171
172         /* create the stackframeinfo */
173
174         stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 8 * 4, ra, xpc);
175
176         /* call the proper patcher function */
177
178         result = (patcher_function)(sp);
179
180         /* remove the stackframeinfo */
181
182         stacktrace_remove_stackframeinfo(&sfi);
183
184         /* check for return value and exit accordingly */
185
186         if (result == false) {
187                 e = exceptions_get_and_clear_exception();
188
189                 PATCHER_MONITOREXIT;
190
191                 return e;
192         }
193
194         PATCHER_MARK_PATCHED_MONITOREXIT;
195
196         return NULL;
197 #endif
198 }
199
200
201 /* patcher_get_putstatic *******************************************************
202
203    Machine code:
204
205 *******************************************************************************/
206
207 bool patcher_get_putstatic(u1 *sp)
208 {
209         u1               *ra;
210         u4                mcode;
211         unresolved_field *uf;
212         s4                disp;
213         fieldinfo        *fi;
214         u1               *pv;
215
216         /* get stuff from the stack */
217
218         ra    = (u1 *)               *((ptrint *) (sp + 5 * 4));
219         mcode =                      *((u4 *)     (sp + 3 * 4));
220         uf    = (unresolved_field *) *((ptrint *) (sp + 2 * 4));
221         disp  =                      *((s4 *)     (sp + 1 * 4));
222         pv    = (u1 *)               *((ptrint *) (sp + 0 * 4));
223
224         /* get the fieldinfo */
225
226         if (!(fi = resolve_field_eager(uf)))
227                 return false;
228
229         /* check if the field's class is initialized */
230
231         if (!(fi->class->state & CLASS_INITIALIZED))
232                 if (!initialize_class(fi->class))
233                         return false;
234
235         *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
236
237         /* patch back original code */
238
239         *((u4 *) ra) = mcode;
240
241         return true;
242 }
243
244
245 /* patcher_get_putfield ********************************************************
246
247    Machine code:
248
249    <patched call position>
250    45 8b 8f 00 00 00 00             mov    0x0(%r15),%r9d
251
252 *******************************************************************************/
253
254 bool patcher_get_putfield(u1 *sp)
255 {
256         OOPS();
257         u1               *ra;
258         u8                mcode;
259         unresolved_field *uf;
260         fieldinfo        *fi;
261         u1                byte;
262
263         /* get stuff from the stack */
264
265         ra    = (u1 *)               *((ptrint *) (sp + 5 * 8));
266         mcode =                      *((u8 *)     (sp + 3 * 8));
267         uf    = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
268
269         /* get the fieldinfo */
270
271         if (!(fi = resolve_field_eager(uf)))
272                 return false;
273
274         /* patch back original code (instruction code is smaller than 8 bytes) */
275
276         *((u4 *) (ra + 0)) = (u4) mcode;
277         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
278
279         /* if we show disassembly, we have to skip the nop's */
280
281         if (opt_shownops)
282                 ra = ra + 5;
283
284         /* patch the field's offset: we check for the field type, because the     */
285         /* instructions have different lengths                                    */
286
287         if (IS_INT_LNG_TYPE(fi->type)) {
288                 /* check for special case: %rsp or %r12 as base register */
289
290                 byte = *(ra + 3);
291
292                 if (byte == 0x24)
293                         *((u4 *) (ra + 4)) = (u4) (fi->offset);
294                 else
295                         *((u4 *) (ra + 3)) = (u4) (fi->offset);
296         }
297         else {
298                 /* check for special case: %rsp or %r12 as base register */
299
300                 byte = *(ra + 5);
301
302                 if (byte == 0x24)
303                         *((u4 *) (ra + 6)) = (u4) (fi->offset);
304                 else
305                         *((u4 *) (ra + 5)) = (u4) (fi->offset);
306         }
307
308         return true;
309 }
310
311
312 /* patcher_putfieldconst *******************************************************
313
314    Machine code:
315
316    <patched call position>
317    41 c7 85 00 00 00 00 7b 00 00 00    movl   $0x7b,0x0(%r13)
318
319 *******************************************************************************/
320
321 bool patcher_putfieldconst(u1 *sp)
322 {
323         OOPS();
324         u1               *ra;
325         u8                mcode;
326         unresolved_field *uf;
327         fieldinfo        *fi;
328
329         /* get stuff from the stack */
330
331         ra    = (u1 *)               *((ptrint *) (sp + 5 * 8));
332         mcode =                      *((u8 *)     (sp + 3 * 8));
333         uf    = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
334
335         /* get the fieldinfo */
336
337         if (!(fi = resolve_field_eager(uf)))
338                 return false;
339
340         /* patch back original code */
341
342         *((u8 *) ra) = mcode;
343
344         /* if we show disassembly, we have to skip the nop's */
345
346         if (opt_shownops)
347                 ra = ra + 5;
348
349         /* patch the field's offset */
350
351         if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
352                 /* handle special case when the base register is %r12 */
353
354                 if (*(ra + 2) == 0x84) {
355                         *((u4 *) (ra + 4))      = (u4) (fi->offset);
356                         *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4);
357                 }
358                 else {
359                         *((u4 *) (ra + 3))      = (u4) (fi->offset);
360                         *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
361                 }
362         }
363         else {
364                 /* handle special case when the base register is %r12 */
365
366                 if (*(ra + 2) == 0x84)
367                         *((u4 *) (ra + 4)) = (u4) (fi->offset);
368                 else
369                         *((u4 *) (ra + 3)) = (u4) (fi->offset);
370         }
371
372         return true;
373 }
374
375
376 /* patcher_aconst **************************************************************
377
378    Machine code:
379
380    <patched call position>
381    48 bf a0 f0 92 00 00 00 00 00    mov    $0x92f0a0,%rdi
382
383 *******************************************************************************/
384
385 bool patcher_aconst(u1 *sp)
386 {
387         OOPS();
388         u1                *ra;
389         u8                 mcode;
390         constant_classref *cr;
391         classinfo         *c;
392
393         /* get stuff from the stack */
394
395         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
396         mcode =                       *((u8 *)     (sp + 3 * 8));
397         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
398
399         /* get the classinfo */
400
401         if (!(c = resolve_classref_eager(cr)))
402                 return false;
403
404         /* patch back original code */
405
406         *((u8 *) ra) = mcode;
407
408         /* if we show disassembly, we have to skip the nop's */
409
410         if (opt_shownops)
411                 ra = ra + 5;
412
413         /* patch the classinfo pointer */
414
415         *((ptrint *) (ra + 2)) = (ptrint) c;
416
417         return true;
418 }
419
420
421 /* patcher_builtin_multianewarray **********************************************
422
423    Machine code:
424
425    <patched call position>
426    48 bf 02 00 00 00 00 00 00 00    mov    $0x2,%rdi
427    48 be 30 40 b2 00 00 00 00 00    mov    $0xb24030,%rsi
428    48 89 e2                         mov    %rsp,%rdx
429    48 b8 7c 96 4b 00 00 00 00 00    mov    $0x4b967c,%rax
430    48 ff d0                         callq  *%rax
431
432 *******************************************************************************/
433
434 bool patcher_builtin_multianewarray(u1 *sp)
435 {
436         OOPS();
437         u1                *ra;
438         u8                 mcode;
439         constant_classref *cr;
440         classinfo         *c;
441
442         /* get stuff from the stack */
443
444         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
445         mcode =                       *((u8 *)     (sp + 3 * 8));
446         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
447
448         /* get the classinfo */
449
450         if (!(c = resolve_classref_eager(cr)))
451                 return false;
452
453         /* patch back original code */
454
455         *((u8 *) ra) = mcode;
456
457         /* if we show disassembly, we have to skip the nop's */
458
459         if (opt_shownops)
460                 ra = ra + 5;
461
462         /* patch the classinfo pointer */
463
464         *((ptrint *) (ra + 10 + 2)) = (ptrint) c;
465
466         return true;
467 }
468
469
470 /* patcher_builtin_arraycheckcast **********************************************
471
472    Machine code:
473
474    <patched call position>
475    48 be b8 3f b2 00 00 00 00 00    mov    $0xb23fb8,%rsi
476    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
477    48 ff d0                         callq  *%rax
478
479 *******************************************************************************/
480
481 bool patcher_builtin_arraycheckcast(u1 *sp)
482 {
483         OOPS();
484         u1                *ra;
485         u8                 mcode;
486         constant_classref *cr;
487         classinfo         *c;
488
489         /* get stuff from the stack */
490
491         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
492         mcode =                       *((u8 *)     (sp + 3 * 8));
493         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
494
495         /* get the classinfo */
496
497         if (!(c = resolve_classref_eager(cr)))
498                 return false;
499
500         /* patch back original code */
501
502         *((u8 *) ra) = mcode;
503
504         /* if we show disassembly, we have to skip the nop's */
505
506         if (opt_shownops)
507                 ra = ra + 5;
508
509         /* patch the classinfo pointer */
510
511         *((ptrint *) (ra + 2)) = (ptrint) c;
512
513         return true;
514 }
515
516
517 /* patcher_invokestatic_special ************************************************
518
519    Machine code:
520
521 *******************************************************************************/
522
523 __PORTED__ bool patcher_invokestatic_special(u1 *sp)
524 {
525         u1                *ra;
526         u4                 mcode;
527         unresolved_method *um;
528         s4                 disp;
529         u1                *pv;
530         methodinfo        *m;
531
532         /* get stuff from the stack */
533
534         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
535         mcode =                       *((u4 *)     (sp + 3 * 4));
536         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
537         disp  =                       *((s4 *)     (sp + 1 * 4));
538         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
539
540         /* get the fieldinfo */
541
542         if (!(m = resolve_method_eager(um)))
543                 return false;
544
545         *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
546
547         /* patch back original code */
548
549         *((u4 *) ra) = mcode;
550
551         /* patch stubroutine */
552
553         return true;
554 }
555
556
557 /* patcher_invokevirtual *******************************************************
558
559    Machine code:
560
561 *******************************************************************************/
562
563 bool patcher_invokevirtual(u1 *sp)
564 {
565         u1                *ra;
566         u4                 mcode;
567         unresolved_method *um;
568         methodinfo        *m;
569         s4                off;
570
571         /* get stuff from the stack */
572
573         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
574         mcode =                       *((u4 *)     (sp + 3 * 4));
575         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
576
577         /* get the fieldinfo */
578
579         if (!(m = resolve_method_eager(um)))
580                 return false;
581
582         /* patch back original code */
583
584         *((u4 *) ra) = mcode;
585
586         /* patch vftbl index */
587
588
589         off = (s4) (OFFSET(vftbl_t, table[0]) +
590                                                                    sizeof(methodptr) * m->vftblindex);
591
592         assert((off >= 0) && (off <= 0xFFF));
593
594         *((s4 *)(ra + 4 + 4)) |= off;
595
596         return true;
597 }
598
599
600 /* patcher_invokeinterface *****************************************************
601
602    Machine code:
603
604 *******************************************************************************/
605
606 bool patcher_invokeinterface(u1 *sp)
607 {
608         u1                *ra;
609         u4                 mcode;
610         unresolved_method *um;
611         methodinfo        *m;
612         s4                 idx, off;
613
614         /* get stuff from the stack */
615
616         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
617         mcode =                       *((u4 *)     (sp + 3 * 4));
618         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
619
620         /* get the fieldinfo */
621
622         if (!(m = resolve_method_eager(um)))
623                 return false;
624
625         /* patch back original code */
626
627         *((u4 *) ra) = mcode;
628
629         /* get interfacetable index */
630
631         idx = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
632                 sizeof(methodptr) * m->class->index) + 
633                 0xFFF;
634         assert((idx >= 0) && (idx <= 0xFFF));
635
636         /* get method offset */
637
638         off =
639                 (s4) (sizeof(methodptr) * (m - m->class->methods));
640         assert((off >= 0) && (off <= 0xFFF));
641
642         /* patch them */
643
644         *((s4 *)(ra + 4 + 4)) |= idx;
645         *((s4 *)(ra + 4 + 4 + 4)) |= off;
646
647         return true;
648 }
649
650
651 /* patcher_resolve_classref_to_flags *******************************************
652
653    CHECKCAST/INSTANCEOF:
654
655    <patched call position>
656
657 *******************************************************************************/
658
659 __PORTED__ bool patcher_resolve_classref_to_flags(u1 *sp)
660 {
661         constant_classref *cr;
662         s4                 disp;
663         u1                *pv;
664         classinfo         *c;
665         u4                 mcode;
666         u1                *ra;
667
668         /* get stuff from the stack */
669
670         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
671         mcode =                       *((u4 *)     (sp + 3 * 4));
672         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
673         disp  =                       *((s4 *)     (sp + 1 * 4));
674         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
675
676         /* get the fieldinfo */
677
678         if (!(c = resolve_classref_eager(cr)))
679                 return false;
680
681         /* patch class flags */
682
683         *((s4 *) (pv + disp)) = (s4) c->flags;
684
685         /* patch back original code */
686
687         *((u4 *) ra) = mcode;
688
689         return true;
690 }
691
692 /* patcher_resolve_classref_to_classinfo ***************************************
693
694    ACONST:
695    MULTIANEWARRAY:
696    ARRAYCHECKCAST:
697
698 *******************************************************************************/
699
700 __PORTED__ bool patcher_resolve_classref_to_classinfo(u1 *sp)
701 {
702         constant_classref *cr;
703         s4                 disp;
704         u1                *pv;
705         classinfo         *c;
706         u4                 mcode;
707         u1                *ra;
708
709         /* get stuff from the stack */
710
711         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
712         mcode =                       *((u4 *)     (sp + 3 * 4));
713         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
714         disp  =                       *((s4 *)     (sp + 1 * 4));
715         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
716
717         /* get the classinfo */
718
719         if (!(c = resolve_classref_eager(cr)))
720                 return false;
721
722         /* patch the classinfo pointer */
723
724         *((ptrint *) (pv + disp)) = (ptrint) c;
725
726         /* patch back original code */
727
728         *((u4 *) ra) = mcode;
729
730         return true;
731 }
732
733 /* patcher_resolve_classref_to_vftbl *******************************************
734
735    CHECKCAST (class):
736    INSTANCEOF (class):
737
738 *******************************************************************************/
739
740 bool patcher_resolve_classref_to_vftbl(u1 *sp)
741 {
742         constant_classref *cr;
743         s4                 disp;
744         u1                *pv;
745         classinfo         *c;
746         u4                 mcode;
747         u1                *ra;
748
749         /* get stuff from the stack */
750
751         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
752         mcode =                       *((u4 *)     (sp + 3 * 4));
753         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
754         disp  =                       *((s4 *)     (sp + 1 * 4));
755         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
756
757         /* get the fieldinfo */
758
759         if (!(c = resolve_classref_eager(cr)))
760                 return false;
761
762         /* patch super class' vftbl */
763
764         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
765
766         /* patch back original code */
767
768         *((u4 *) ra) = mcode;
769
770         return true;
771 }
772
773 /* patcher_checkcast_instanceof_interface **************************************
774
775    Machine code:
776
777    <patched call position>
778    45 8b 9a 1c 00 00 00             mov    0x1c(%r10),%r11d
779    49 81 eb 00 00 00 00             sub    $0x0,%r11
780    4d 85 db                         test   %r11,%r11
781    0f 8e 94 04 00 00                jle    0x00002aaaaab018f8
782    4d 8b 9a 00 00 00 00             mov    0x0(%r10),%r11
783
784 *******************************************************************************/
785
786 bool patcher_checkcast_instanceof_interface(u1 *sp)
787 {
788         OOPS();
789         u1                *ra;
790         u8                 mcode;
791         constant_classref *cr;
792         classinfo         *c;
793
794         /* get stuff from the stack */
795
796         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
797         mcode =                       *((u8 *)     (sp + 3 * 8));
798         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
799
800         /* get the fieldinfo */
801
802         if (!(c = resolve_classref_eager(cr)))
803                 return false;
804
805         /* patch back original code */
806
807         *((u8 *) ra) = mcode;
808
809         /* if we show disassembly, we have to skip the nop's */
810
811         if (opt_shownops)
812                 ra = ra + 5;
813
814         /* patch super class index */
815
816         *((s4 *) (ra + 7 + 3)) = (s4) c->index;
817
818         *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
819                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
820                           c->index * sizeof(methodptr*));
821
822         return true;
823 }
824
825
826 /* patcher_checkcast_class *****************************************************
827
828    Machine code:
829
830    <patched call position>
831    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
832    45 8b 92 20 00 00 00             mov    0x20(%r10),%r10d
833    45 8b 9b 20 00 00 00             mov    0x20(%r11),%r11d
834    4d 29 da                         sub    %r11,%r10
835    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
836
837 *******************************************************************************/
838
839 bool patcher_checkcast_class(u1 *sp)
840 {
841         OOPS();
842         u1                *ra;
843         u8                 mcode;
844         constant_classref *cr;
845         classinfo         *c;
846
847         /* get stuff from the stack */
848
849         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
850         mcode =                       *((u8 *)     (sp + 3 * 8));
851         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
852
853         /* get the fieldinfo */
854
855         if (!(c = resolve_classref_eager(cr)))
856                 return false;
857
858         /* patch back original code */
859
860         *((u8 *) ra) = mcode;
861
862         /* if we show disassembly, we have to skip the nop's */
863
864         if (opt_shownops)
865                 ra = ra + 5;
866
867         /* patch super class' vftbl */
868
869         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
870         *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
871
872         return true;
873 }
874
875
876 /* patcher_instanceof_class ****************************************************
877
878    Machine code:
879
880    <patched call position>
881    49 ba 00 00 00 00 00 00 00 00    mov    $0x0,%r10
882
883 *******************************************************************************/
884
885 bool patcher_instanceof_class(u1 *sp)
886 {
887         OOPS();
888         u1                *ra;
889         u8                 mcode;
890         constant_classref *cr;
891         classinfo         *c;
892
893         /* get stuff from the stack */
894
895         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
896         mcode =                       *((u8 *)     (sp + 3 * 8));
897         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
898
899         /* get the fieldinfo */
900
901         if (!(c = resolve_classref_eager(cr)))
902                 return false;
903
904         /* patch back original code */
905
906         *((u8 *) ra) = mcode;
907
908         /* if we show disassembly, we have to skip the nop's */
909
910         if (opt_shownops)
911                 ra = ra + 5;
912
913         /* patch super class' vftbl */
914
915         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
916
917         return true;
918 }
919
920
921 /* patcher_clinit **************************************************************
922
923    May be used for GET/PUTSTATIC and in native stub.
924
925    Machine code:
926
927 *******************************************************************************/
928
929 __PORTED__ bool patcher_clinit(u1 *sp)
930 {
931         u1        *ra;
932         u4         mcode;
933         classinfo *c;
934
935         /* get stuff from the stack */
936
937         ra    = (u1 *)        *((ptrint *) (sp + 5 * 4));
938         mcode =               *((u4 *)     (sp + 3 * 4));
939         c     = (classinfo *) *((ptrint *) (sp + 2 * 4));
940
941         /* check if the class is initialized */
942
943         if (!(c->state & CLASS_INITIALIZED))
944                 if (!initialize_class(c))
945                         return false;
946
947         /* patch back original code */
948
949         *((u4 *) ra) = mcode;
950
951         return true;
952 }
953
954
955 /* patcher_athrow_areturn ******************************************************
956
957    Machine code:
958
959    <patched call position>
960
961 *******************************************************************************/
962
963 #ifdef ENABLE_VERIFIER
964 __PORTED__ bool patcher_athrow_areturn(u1 *sp)
965 {
966         u1               *ra;
967         u4                mcode;
968         unresolved_class *uc;
969
970         /* get stuff from the stack */
971
972         ra    = (u1 *)               *((ptrint *) (sp + 5 * 4));
973         mcode =                      *((u4 *)     (sp + 3 * 4));
974         uc    = (unresolved_class *) *((ptrint *) (sp + 2 * 4));
975
976         /* resolve the class and check subtype constraints */
977
978         if (!resolve_class_eager_no_access_check(uc))
979                 return false;
980
981         /* patch back original code */
982
983         *((u4 *) ra) = mcode;
984
985         return true;
986 }
987 #endif /* ENABLE_VERIFIER */
988
989
990 /* patcher_resolve_native ******************************************************
991
992 *******************************************************************************/
993
994 #if !defined(WITH_STATIC_CLASSPATH)
995 __PORTED__ bool patcher_resolve_native(u1 *sp)
996 {
997         u1          *ra;
998         u4           mcode;
999         methodinfo  *m;
1000         functionptr  f;
1001         s4           disp;
1002         u1          *pv;
1003
1004         /* get stuff from the stack */
1005
1006         ra    = (u1 *)         *((ptrint *) (sp + 5 * 4));
1007         mcode =                *((u4 *)     (sp + 3 * 4));
1008         disp  =                *((s4 *)     (sp + 1 * 4));
1009         m     = (methodinfo *) *((ptrint *) (sp + 2 * 4));
1010         pv    = (u1 *)         *((ptrint *) (sp + 0 * 4));
1011
1012         /* resolve native function */
1013
1014         if (!(f = native_resolve_function(m)))
1015                 return false;
1016
1017         /* patch native function pointer */
1018
1019         *((ptrint *) (pv + disp)) = (ptrint) f;
1020
1021         /* patch back original code */
1022
1023         *((u4 *) ra) = mcode;
1024
1025         return true;
1026 }
1027 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1028
1029
1030 /*
1031  * These are local overrides for various environment variables in Emacs.
1032  * Please do not remove this and leave it at the end of the file, where
1033  * Emacs will automagically detect them.
1034  * ---------------------------------------------------------------------
1035  * Local variables:
1036  * mode: c
1037  * indent-tabs-mode: t
1038  * c-basic-offset: 4
1039  * tab-width: 4
1040  * End:
1041  * vim:noexpandtab:sw=4:ts=4:
1042  */