* src/mm/cacao-gc/gc.h: Added GC_EXECUTIONSTATE and GC_SOURCESTATE defines.
[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 7483 2007-03-08 13:17:40Z michi $
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 "vm/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(N_VALID_DISP(off));
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                 N_DISP_MAX;
634
635         ASSERT_VALID_DISP(idx);
636
637         /* get method offset */
638
639         off =
640                 (s4) (sizeof(methodptr) * (m - m->class->methods));
641         ASSERT_VALID_DISP(off);
642
643         /* patch them */
644
645         *((s4 *)(ra + 4 + 4)) |= idx;
646         *((s4 *)(ra + 4 + 4 + 4)) |= off;
647
648         return true;
649 }
650
651
652 /* patcher_resolve_classref_to_flags *******************************************
653
654    CHECKCAST/INSTANCEOF:
655
656    <patched call position>
657
658 *******************************************************************************/
659
660 __PORTED__ bool patcher_resolve_classref_to_flags(u1 *sp)
661 {
662         constant_classref *cr;
663         s4                 disp;
664         u1                *pv;
665         classinfo         *c;
666         u4                 mcode;
667         u1                *ra;
668
669         /* get stuff from the stack */
670
671         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
672         mcode =                       *((u4 *)     (sp + 3 * 4));
673         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
674         disp  =                       *((s4 *)     (sp + 1 * 4));
675         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
676
677         /* get the fieldinfo */
678
679         if (!(c = resolve_classref_eager(cr)))
680                 return false;
681
682         /* patch class flags */
683
684         *((s4 *) (pv + disp)) = (s4) c->flags;
685
686         /* patch back original code */
687
688         *((u4 *) ra) = mcode;
689
690         return true;
691 }
692
693 /* patcher_resolve_classref_to_classinfo ***************************************
694
695    ACONST:
696    MULTIANEWARRAY:
697    ARRAYCHECKCAST:
698
699 *******************************************************************************/
700
701 __PORTED__ bool patcher_resolve_classref_to_classinfo(u1 *sp)
702 {
703         constant_classref *cr;
704         s4                 disp;
705         u1                *pv;
706         classinfo         *c;
707         u4                 mcode;
708         u1                *ra;
709
710         /* get stuff from the stack */
711
712         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
713         mcode =                       *((u4 *)     (sp + 3 * 4));
714         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
715         disp  =                       *((s4 *)     (sp + 1 * 4));
716         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
717
718         /* get the classinfo */
719
720         if (!(c = resolve_classref_eager(cr)))
721                 return false;
722
723         /* patch the classinfo pointer */
724
725         *((ptrint *) (pv + disp)) = (ptrint) c;
726
727         /* patch back original code */
728
729         *((u4 *) ra) = mcode;
730
731         return true;
732 }
733
734 /* patcher_resolve_classref_to_vftbl *******************************************
735
736    CHECKCAST (class):
737    INSTANCEOF (class):
738
739 *******************************************************************************/
740
741 bool patcher_resolve_classref_to_vftbl(u1 *sp)
742 {
743         constant_classref *cr;
744         s4                 disp;
745         u1                *pv;
746         classinfo         *c;
747         u4                 mcode;
748         u1                *ra;
749
750         /* get stuff from the stack */
751
752         ra    = (u1 *)                *((ptrint *) (sp + 5 * 4));
753         mcode =                       *((u4 *)     (sp + 3 * 4));
754         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 4));
755         disp  =                       *((s4 *)     (sp + 1 * 4));
756         pv    = (u1 *)                *((ptrint *) (sp + 0 * 4));
757
758         /* get the fieldinfo */
759
760         if (!(c = resolve_classref_eager(cr)))
761                 return false;
762
763         /* patch super class' vftbl */
764
765         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
766
767         /* patch back original code */
768
769         *((u4 *) ra) = mcode;
770
771         return true;
772 }
773
774 /* patcher_checkcast_instanceof_interface **************************************
775
776    Machine code:
777
778    <patched call position>
779    45 8b 9a 1c 00 00 00             mov    0x1c(%r10),%r11d
780    49 81 eb 00 00 00 00             sub    $0x0,%r11
781    4d 85 db                         test   %r11,%r11
782    0f 8e 94 04 00 00                jle    0x00002aaaaab018f8
783    4d 8b 9a 00 00 00 00             mov    0x0(%r10),%r11
784
785 *******************************************************************************/
786
787 bool patcher_checkcast_instanceof_interface(u1 *sp)
788 {
789         OOPS();
790         u1                *ra;
791         u8                 mcode;
792         constant_classref *cr;
793         classinfo         *c;
794
795         /* get stuff from the stack */
796
797         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
798         mcode =                       *((u8 *)     (sp + 3 * 8));
799         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
800
801         /* get the fieldinfo */
802
803         if (!(c = resolve_classref_eager(cr)))
804                 return false;
805
806         /* patch back original code */
807
808         *((u8 *) ra) = mcode;
809
810         /* if we show disassembly, we have to skip the nop's */
811
812         if (opt_shownops)
813                 ra = ra + 5;
814
815         /* patch super class index */
816
817         *((s4 *) (ra + 7 + 3)) = (s4) c->index;
818
819         *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
820                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
821                           c->index * sizeof(methodptr*));
822
823         return true;
824 }
825
826
827 /* patcher_checkcast_class *****************************************************
828
829    Machine code:
830
831    <patched call position>
832    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
833    45 8b 92 20 00 00 00             mov    0x20(%r10),%r10d
834    45 8b 9b 20 00 00 00             mov    0x20(%r11),%r11d
835    4d 29 da                         sub    %r11,%r10
836    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
837
838 *******************************************************************************/
839
840 bool patcher_checkcast_class(u1 *sp)
841 {
842         OOPS();
843         u1                *ra;
844         u8                 mcode;
845         constant_classref *cr;
846         classinfo         *c;
847
848         /* get stuff from the stack */
849
850         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
851         mcode =                       *((u8 *)     (sp + 3 * 8));
852         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
853
854         /* get the fieldinfo */
855
856         if (!(c = resolve_classref_eager(cr)))
857                 return false;
858
859         /* patch back original code */
860
861         *((u8 *) ra) = mcode;
862
863         /* if we show disassembly, we have to skip the nop's */
864
865         if (opt_shownops)
866                 ra = ra + 5;
867
868         /* patch super class' vftbl */
869
870         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
871         *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
872
873         return true;
874 }
875
876
877 /* patcher_instanceof_class ****************************************************
878
879    Machine code:
880
881    <patched call position>
882    49 ba 00 00 00 00 00 00 00 00    mov    $0x0,%r10
883
884 *******************************************************************************/
885
886 bool patcher_instanceof_class(u1 *sp)
887 {
888         OOPS();
889         u1                *ra;
890         u8                 mcode;
891         constant_classref *cr;
892         classinfo         *c;
893
894         /* get stuff from the stack */
895
896         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
897         mcode =                       *((u8 *)     (sp + 3 * 8));
898         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
899
900         /* get the fieldinfo */
901
902         if (!(c = resolve_classref_eager(cr)))
903                 return false;
904
905         /* patch back original code */
906
907         *((u8 *) ra) = mcode;
908
909         /* if we show disassembly, we have to skip the nop's */
910
911         if (opt_shownops)
912                 ra = ra + 5;
913
914         /* patch super class' vftbl */
915
916         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
917
918         return true;
919 }
920
921
922 /* patcher_clinit **************************************************************
923
924    May be used for GET/PUTSTATIC and in native stub.
925
926    Machine code:
927
928 *******************************************************************************/
929
930 __PORTED__ bool patcher_clinit(u1 *sp)
931 {
932         u1        *ra;
933         u4         mcode;
934         classinfo *c;
935
936         /* get stuff from the stack */
937
938         ra    = (u1 *)        *((ptrint *) (sp + 5 * 4));
939         mcode =               *((u4 *)     (sp + 3 * 4));
940         c     = (classinfo *) *((ptrint *) (sp + 2 * 4));
941
942         /* check if the class is initialized */
943
944         if (!(c->state & CLASS_INITIALIZED))
945                 if (!initialize_class(c))
946                         return false;
947
948         /* patch back original code */
949
950         *((u4 *) ra) = mcode;
951
952         return true;
953 }
954
955
956 /* patcher_athrow_areturn ******************************************************
957
958    Machine code:
959
960    <patched call position>
961
962 *******************************************************************************/
963
964 #ifdef ENABLE_VERIFIER
965 __PORTED__ bool patcher_athrow_areturn(u1 *sp)
966 {
967         u1               *ra;
968         u4                mcode;
969         unresolved_class *uc;
970
971         /* get stuff from the stack */
972
973         ra    = (u1 *)               *((ptrint *) (sp + 5 * 4));
974         mcode =                      *((u4 *)     (sp + 3 * 4));
975         uc    = (unresolved_class *) *((ptrint *) (sp + 2 * 4));
976
977         /* resolve the class and check subtype constraints */
978
979         if (!resolve_class_eager_no_access_check(uc))
980                 return false;
981
982         /* patch back original code */
983
984         *((u4 *) ra) = mcode;
985
986         return true;
987 }
988 #endif /* ENABLE_VERIFIER */
989
990
991 /* patcher_resolve_native ******************************************************
992
993 *******************************************************************************/
994
995 #if !defined(WITH_STATIC_CLASSPATH)
996 __PORTED__ bool patcher_resolve_native(u1 *sp)
997 {
998         u1          *ra;
999         u4           mcode;
1000         methodinfo  *m;
1001         functionptr  f;
1002         s4           disp;
1003         u1          *pv;
1004
1005         /* get stuff from the stack */
1006
1007         ra    = (u1 *)         *((ptrint *) (sp + 5 * 4));
1008         mcode =                *((u4 *)     (sp + 3 * 4));
1009         disp  =                *((s4 *)     (sp + 1 * 4));
1010         m     = (methodinfo *) *((ptrint *) (sp + 2 * 4));
1011         pv    = (u1 *)         *((ptrint *) (sp + 0 * 4));
1012
1013         /* resolve native function */
1014
1015         if (!(f = native_resolve_function(m)))
1016                 return false;
1017
1018         /* patch native function pointer */
1019
1020         *((ptrint *) (pv + disp)) = (ptrint) f;
1021
1022         /* patch back original code */
1023
1024         *((u4 *) ra) = mcode;
1025
1026         return true;
1027 }
1028 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1029
1030
1031 /*
1032  * These are local overrides for various environment variables in Emacs.
1033  * Please do not remove this and leave it at the end of the file, where
1034  * Emacs will automagically detect them.
1035  * ---------------------------------------------------------------------
1036  * Local variables:
1037  * mode: c
1038  * indent-tabs-mode: t
1039  * c-basic-offset: 4
1040  * tab-width: 4
1041  * End:
1042  * vim:noexpandtab:sw=4:ts=4:
1043  */