1 /* src/vm/jit/i386/patcher.c - i386 code patching functions
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
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
31 $Id: patcher.c 2475 2005-05-13 14:02:57Z twisti $
36 #include "vm/jit/i386/types.h"
37 #include "vm/builtin.h"
39 #include "vm/initialize.h"
40 #include "vm/options.h"
41 #include "vm/references.h"
42 #include "vm/jit/helper.h"
45 /* patcher_get_putstatic *******************************************************
49 <patched call position>
50 b8 00 00 00 00 mov $0x00000000,%eax
52 *******************************************************************************/
54 bool patcher_get_putstatic(u1 *sp)
62 /* get stuff from the stack */
64 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
65 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
66 mcode = *((u8 *) (sp + 1 * 4));
67 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
69 /* calculate and set the new return address */
72 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
74 #if defined(USE_THREADS)
75 /* enter a monitor on the patching position */
77 builtin_monitorenter(o);
79 /* check if the position has already been patched */
82 builtin_monitorexit(o);
88 /* get the fieldinfo */
90 if (!(fi = helper_resolve_fieldinfo(uf)))
93 /* check if the field's class is initialized */
95 if (!fi->class->initialized)
96 if (!initialize_class(fi->class))
99 /* patch back original code */
101 *((u8 *) ra) = mcode;
103 /* if we show disassembly, we have to skip the nop's */
108 /* patch the field value's address */
110 *((ptrint *) (ra + 1)) = (ptrint) &(fi->value);
112 #if defined(USE_THREADS)
113 /* this position has been patched */
115 o->vftbl = (vftbl_t *) 1;
117 /* leave the monitor on the patching position */
119 builtin_monitorexit(o);
126 /* patcher_getfield ************************************************************
130 <patched call position>
131 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
133 *******************************************************************************/
135 bool patcher_getfield(u1 *sp)
138 java_objectheader *o;
140 unresolved_field *uf;
143 /* get stuff from the stack */
145 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
146 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
147 mcode = *((u8 *) (sp + 1 * 4));
148 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
150 /* calculate and set the new return address */
153 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
155 #if defined(USE_THREADS)
156 /* enter a monitor on the patching position */
158 builtin_monitorenter(o);
160 /* check if the position has already been patched */
163 builtin_monitorexit(o);
169 /* get the fieldinfo */
171 if (!(fi = helper_resolve_fieldinfo(uf)))
174 /* patch back original code */
176 *((u8 *) ra) = mcode;
178 /* if we show disassembly, we have to skip the nop's */
183 /* patch the field's offset */
185 *((u4 *) (ra + 2)) = (u4) (fi->offset);
187 /* if the field has type long, we need to patch the second move too */
189 if (fi->type == TYPE_LNG)
190 *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
192 #if defined(USE_THREADS)
193 /* this position has been patched */
195 o->vftbl = (vftbl_t *) 1;
197 /* leave the monitor on the patching position */
199 builtin_monitorexit(o);
206 /* patcher_putfield ************************************************************
210 <patched call position>
211 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
213 *******************************************************************************/
215 bool patcher_putfield(u1 *sp)
218 java_objectheader *o;
220 unresolved_field *uf;
223 /* get stuff from the stack */
225 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
226 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
227 mcode = *((u8 *) (sp + 1 * 4));
228 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
230 /* calculate and set the new return address */
233 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
235 #if defined(USE_THREADS)
236 /* enter a monitor on the patching position */
238 builtin_monitorenter(o);
240 /* check if the position has already been patched */
243 builtin_monitorexit(o);
249 /* get the fieldinfo */
251 if (!(fi = helper_resolve_fieldinfo(uf)))
254 /* patch back original code */
256 *((u8 *) ra) = mcode;
258 /* if we show disassembly, we have to skip the nop's */
263 /* patch the field's offset */
265 if (fi->type != TYPE_LNG) {
266 *((u4 *) (ra + 2)) = (u4) (fi->offset);
269 /* long code is very special:
271 * 8b 8c 24 00 00 00 00 mov 0x00000000(%esp),%ecx
272 * 8b 94 24 00 00 00 00 mov 0x00000000(%esp),%edx
273 * 89 8d 00 00 00 00 mov %ecx,0x00000000(%ebp)
274 * 89 95 00 00 00 00 mov %edx,0x00000000(%ebp)
277 *((u4 *) (ra + 7 + 7 + 2)) = (u4) (fi->offset);
278 *((u4 *) (ra + 7 + 7 + 6 + 2)) = (u4) (fi->offset + 4);
281 #if defined(USE_THREADS)
282 /* this position has been patched */
284 o->vftbl = (vftbl_t *) 1;
286 /* leave the monitor on the patching position */
288 builtin_monitorexit(o);
295 /* patcher_putfieldconst *******************************************************
299 <patched call position>
300 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%ebp)
302 *******************************************************************************/
304 bool patcher_putfieldconst(u1 *sp)
307 java_objectheader *o;
309 unresolved_field *uf;
312 /* get stuff from the stack */
314 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
315 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
316 mcode = *((u8 *) (sp + 1 * 4));
317 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
319 /* calculate and set the new return address */
322 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
324 #if defined(USE_THREADS)
325 /* enter a monitor on the patching position */
327 builtin_monitorenter(o);
329 /* check if the position has already been patched */
332 builtin_monitorexit(o);
338 /* get the fieldinfo */
340 if (!(fi = helper_resolve_fieldinfo(uf)))
343 /* patch back original code */
345 *((u8 *) ra) = mcode;
347 /* if we show disassembly, we have to skip the nop's */
352 /* patch the field's offset */
354 if (!IS_2_WORD_TYPE(fi->type)) {
355 *((u4 *) (ra + 2)) = (u4) (fi->offset);
358 /* long/double code is different:
360 * c7 80 00 00 00 00 c8 01 00 00 movl $0x1c8,0x0(%eax)
361 * c7 80 04 00 00 00 00 00 00 00 movl $0x0,0x4(%eax)
364 *((u4 *) (ra + 2)) = (u4) (fi->offset);
365 *((u4 *) (ra + 10 + 2)) = (u4) (fi->offset + 4);
368 #if defined(USE_THREADS)
369 /* this position has been patched */
371 o->vftbl = (vftbl_t *) 1;
373 /* leave the monitor on the patching position */
375 builtin_monitorexit(o);
382 /* patcher_builtin_new *********************************************************
386 c7 04 24 00 00 00 00 movl $0x0000000,(%esp)
387 <patched call postition>
388 b8 00 00 00 00 mov $0x0000000,%eax
391 *******************************************************************************/
393 bool patcher_builtin_new(u1 *sp)
396 java_objectheader *o;
398 constant_classref *cr;
401 /* get stuff from the stack */
403 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
404 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
405 mcode = *((u8 *) (sp + 1 * 4));
406 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
408 /* calculate and set the new return address */
411 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
413 #if defined(USE_THREADS)
414 /* enter a monitor on the patching position */
416 builtin_monitorenter(o);
418 /* check if the position has already been patched */
421 builtin_monitorexit(o);
427 /* get the classinfo */
429 if (!(c = helper_resolve_classinfo(cr)))
432 /* patch back original code */
434 *((u8 *) (ra + 7)) = mcode;
436 /* patch the classinfo pointer */
438 *((ptrint *) (ra + 3)) = (ptrint) c;
440 /* if we show disassembly, we have to skip the nop's */
445 /* patch new function address */
447 *((ptrint *) (ra + 7 + 1)) = (ptrint) BUILTIN_new;
449 #if defined(USE_THREADS)
450 /* this position has been patched */
452 o->vftbl = (vftbl_t *) 1;
454 /* leave the monitor on the patching position */
456 builtin_monitorexit(o);
463 /* patcher_builtin_newarray ****************************************************
467 c7 44 24 08 00 00 00 00 movl $0x00000000,0x8(%esp)
468 <patched call position>
469 b8 00 00 00 00 mov $0x00000000,%eax
472 *******************************************************************************/
474 bool patcher_builtin_newarray(u1 *sp)
477 java_objectheader *o;
479 constant_classref *cr;
482 /* get stuff from the stack */
484 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
485 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
486 mcode = *((u8 *) (sp + 1 * 4));
487 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
489 /* calculate and set the new return address */
492 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
494 #if defined(USE_THREADS)
495 /* enter a monitor on the patching position */
497 builtin_monitorenter(o);
499 /* check if the position has already been patched */
502 builtin_monitorexit(o);
508 /* get the classinfo */
510 if (!(c = helper_resolve_classinfo(cr)))
513 /* patch back original code */
515 *((u8 *) (ra + 8)) = mcode;
517 /* patch the class' vftbl pointer */
519 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
521 /* if we show disassembly, we have to skip the nop's */
526 /* patch new function address */
528 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_newarray;
530 #if defined(USE_THREADS)
531 /* this position has been patched */
533 o->vftbl = (vftbl_t *) 1;
535 /* leave the monitor on the patching position */
537 builtin_monitorexit(o);
544 /* patcher_builtin_multianewarray **********************************************
548 <patched call position>
549 c7 04 24 02 00 00 00 movl $0x2,(%esp)
550 c7 44 24 04 00 00 00 00 movl $0x00000000,0x4(%esp)
552 83 c0 0c add $0xc,%eax
553 89 44 24 08 mov %eax,0x8(%esp)
554 b8 00 00 00 00 mov $0x00000000,%eax
557 *******************************************************************************/
559 bool patcher_builtin_multianewarray(u1 *sp)
562 java_objectheader *o;
564 constant_classref *cr;
567 /* get stuff from the stack */
569 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
570 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
571 mcode = *((u8 *) (sp + 1 * 4));
572 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
574 /* calculate and set the new return address */
577 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
579 #if defined(USE_THREADS)
580 /* enter a monitor on the patching position */
582 builtin_monitorenter(o);
584 /* check if the position has already been patched */
587 builtin_monitorexit(o);
593 /* get the classinfo */
595 if (!(c = helper_resolve_classinfo(cr)))
598 /* patch back original code */
600 *((u8 *) ra) = mcode;
602 /* if we show disassembly, we have to skip the nop's */
607 /* patch the class' vftbl pointer */
609 *((ptrint *) (ra + 7 + 4)) = (ptrint) c->vftbl;
611 /* patch new function address */
613 *((ptrint *) (ra + 7 + 8 + 2 + 3 + 4 + 1)) = (ptrint) BUILTIN_multianewarray;
615 #if defined(USE_THREADS)
616 /* this position has been patched */
618 o->vftbl = (vftbl_t *) 1;
620 /* leave the monitor on the patching position */
622 builtin_monitorexit(o);
629 /* patcher_builtin_arraycheckcast **********************************************
633 c7 44 24 08 00 00 00 00 movl $0x00000000,0x8(%esp)
634 <patched call position>
635 b8 00 00 00 00 mov $0x00000000,%eax
638 *******************************************************************************/
640 bool patcher_builtin_arraycheckcast(u1 *sp)
643 java_objectheader *o;
645 constant_classref *cr;
648 /* get stuff from the stack */
650 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
651 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
652 mcode = *((u8 *) (sp + 1 * 4));
653 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
655 /* calculate and set the new return address */
658 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
660 #if defined(USE_THREADS)
661 /* enter a monitor on the patching position */
663 builtin_monitorenter(o);
665 /* check if the position has already been patched */
668 builtin_monitorexit(o);
674 /* get the classinfo */
676 if (!(c = helper_resolve_classinfo(cr)))
679 /* patch back original code */
681 *((u8 *) (ra + 8)) = mcode;
683 /* patch the class' vftbl pointer */
685 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
687 /* if we show disassembly, we have to skip the nop's */
692 /* patch new function address */
694 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arraycheckcast;
696 #if defined(USE_THREADS)
697 /* this position has been patched */
699 o->vftbl = (vftbl_t *) 1;
701 /* leave the monitor on the patching position */
703 builtin_monitorexit(o);
710 /* patcher_builtin_arrayinstanceof *********************************************
714 c7 44 24 08 00 00 00 00 movl $0x00000000,0x8(%esp)
715 <patched call position>
716 b8 00 00 00 00 mov $0x00000000,%eax
719 *******************************************************************************/
721 bool patcher_builtin_arrayinstanceof(u1 *sp)
724 java_objectheader *o;
726 constant_classref *cr;
729 /* get stuff from the stack */
731 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
732 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
733 mcode = *((u8 *) (sp + 1 * 4));
734 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
736 /* calculate and set the new return address */
739 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
741 #if defined(USE_THREADS)
742 /* enter a monitor on the patching position */
744 builtin_monitorenter(o);
746 /* check if the position has already been patched */
749 builtin_monitorexit(o);
755 /* get the classinfo */
757 if (!(c = helper_resolve_classinfo(cr)))
760 /* patch back original code */
762 *((u8 *) (ra + 8)) = mcode;
764 /* patch the class' vftbl pointer */
766 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
768 /* if we show disassembly, we have to skip the nop's */
773 /* patch new function address */
775 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arrayinstanceof;
777 #if defined(USE_THREADS)
778 /* this position has been patched */
780 o->vftbl = (vftbl_t *) 1;
782 /* leave the monitor on the patching position */
784 builtin_monitorexit(o);
791 /* patcher_invokestatic_special ************************************************
795 <patched call position>
796 b9 00 00 00 00 mov $0x00000000,%ecx
799 *******************************************************************************/
801 bool patcher_invokestatic_special(u1 *sp)
804 java_objectheader *o;
806 unresolved_method *um;
809 /* get stuff from the stack */
811 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
812 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
813 mcode = *((u8 *) (sp + 1 * 4));
814 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
816 /* calculate and set the new return address */
819 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
821 #if defined(USE_THREADS)
822 /* enter a monitor on the patching position */
824 builtin_monitorenter(o);
826 /* check if the position has already been patched */
829 builtin_monitorexit(o);
835 /* get the fieldinfo */
837 if (!(m = helper_resolve_methodinfo(um)))
840 /* patch back original code */
842 *((u8 *) ra) = mcode;
844 /* if we show disassembly, we have to skip the nop's */
849 /* patch stubroutine */
851 *((ptrint *) (ra + 1)) = (ptrint) m->stubroutine;
853 #if defined(USE_THREADS)
854 /* this position has been patched */
856 o->vftbl = (vftbl_t *) 1;
858 /* leave the monitor on the patching position */
860 builtin_monitorexit(o);
867 /* patcher_invokevirtual *******************************************************
871 <patched call position>
872 8b 08 mov (%eax),%ecx
873 8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
876 *******************************************************************************/
878 bool patcher_invokevirtual(u1 *sp)
881 java_objectheader *o;
883 unresolved_method *um;
886 /* get stuff from the stack */
888 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
889 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
890 mcode = *((u8 *) (sp + 1 * 4));
891 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
893 /* calculate and set the new return address */
896 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
898 #if defined(USE_THREADS)
899 /* enter a monitor on the patching position */
901 builtin_monitorenter(o);
903 /* check if the position has already been patched */
906 builtin_monitorexit(o);
912 /* get the fieldinfo */
914 if (!(m = helper_resolve_methodinfo(um)))
917 /* patch back original code */
919 *((u8 *) ra) = mcode;
921 /* if we show disassembly, we have to skip the nop's */
926 /* patch vftbl index */
928 *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, table[0]) +
929 sizeof(methodptr) * m->vftblindex);
931 #if defined(USE_THREADS)
932 /* this position has been patched */
934 o->vftbl = (vftbl_t *) 1;
936 /* leave the monitor on the patching position */
938 builtin_monitorexit(o);
945 /* patcher_invokeinterface *****************************************************
949 <patched call position>
950 8b 00 mov (%eax),%eax
951 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
952 8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
955 *******************************************************************************/
957 bool patcher_invokeinterface(u1 *sp)
960 java_objectheader *o;
962 unresolved_method *um;
965 /* get stuff from the stack */
967 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
968 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
969 mcode = *((u8 *) (sp + 1 * 4));
970 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
972 /* calculate and set the new return address */
975 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
977 #if defined(USE_THREADS)
978 /* enter a monitor on the patching position */
980 builtin_monitorenter(o);
982 /* check if the position has already been patched */
985 builtin_monitorexit(o);
991 /* get the fieldinfo */
993 if (!(m = helper_resolve_methodinfo(um)))
996 /* patch back original code */
998 *((u8 *) ra) = mcode;
1000 /* if we show disassembly, we have to skip the nop's */
1002 if (showdisassemble)
1005 /* patch interfacetable index */
1007 *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1008 sizeof(methodptr) * m->class->index);
1010 /* patch method offset */
1012 *((s4 *) (ra + 2 + 6 + 2)) =
1013 (s4) (sizeof(methodptr) * (m - m->class->methods));
1015 #if defined(USE_THREADS)
1016 /* this position has been patched */
1018 o->vftbl = (vftbl_t *) 1;
1020 /* leave the monitor on the patching position */
1022 builtin_monitorexit(o);
1029 /* patcher_checkcast_instanceof_flags ******************************************
1033 <patched call position>
1034 b9 00 00 00 00 mov $0x00000000,%ecx
1036 *******************************************************************************/
1038 bool patcher_checkcast_instanceof_flags(u1 *sp)
1041 java_objectheader *o;
1043 constant_classref *cr;
1046 /* get stuff from the stack */
1048 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1049 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1050 mcode = *((u8 *) (sp + 1 * 4));
1051 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
1053 /* calculate and set the new return address */
1056 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1058 #if defined(USE_THREADS)
1059 /* enter a monitor on the patching position */
1061 builtin_monitorenter(o);
1063 /* check if the position has already been patched */
1066 builtin_monitorexit(o);
1072 /* get the fieldinfo */
1074 if (!(c = helper_resolve_classinfo(cr)))
1077 /* patch back original code */
1079 *((u8 *) ra) = mcode;
1081 /* if we show disassembly, we have to skip the nop's */
1083 if (showdisassemble)
1086 /* patch class flags */
1088 *((s4 *) (ra + 1)) = (s4) c->flags;
1090 #if defined(USE_THREADS)
1091 /* this position has been patched */
1093 o->vftbl = (vftbl_t *) 1;
1095 /* leave the monitor on the patching position */
1097 builtin_monitorexit(o);
1104 /* patcher_checkcast_instanceof_interface **************************************
1108 <patched call position>
1109 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
1110 81 ea 00 00 00 00 sub $0x00000000,%edx
1111 85 d2 test %edx,%edx
1112 0f 8e 00 00 00 00 jle 0x00000000
1113 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
1115 *******************************************************************************/
1117 bool patcher_checkcast_instanceof_interface(u1 *sp)
1120 java_objectheader *o;
1122 constant_classref *cr;
1125 /* get stuff from the stack */
1127 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1128 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1129 mcode = *((u8 *) (sp + 1 * 4));
1130 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
1132 /* calculate and set the new return address */
1135 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1137 #if defined(USE_THREADS)
1138 /* enter a monitor on the patching position */
1140 builtin_monitorenter(o);
1142 /* check if the position has already been patched */
1145 builtin_monitorexit(o);
1151 /* get the fieldinfo */
1153 if (!(c = helper_resolve_classinfo(cr)))
1156 /* patch back original code */
1158 *((u8 *) ra) = mcode;
1160 /* if we show disassembly, we have to skip the nop's */
1162 if (showdisassemble)
1165 /* patch super class index */
1167 *((s4 *) (ra + 6 + 2)) = (s4) c->index;
1169 *((s4 *) (ra + 6 + 6 + 2 + 6 + 2)) =
1170 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1171 c->index * sizeof(methodptr*));
1173 #if defined(USE_THREADS)
1174 /* this position has been patched */
1176 o->vftbl = (vftbl_t *) 1;
1178 /* leave the monitor on the patching position */
1180 builtin_monitorexit(o);
1187 /* patcher_checkcast_class *****************************************************
1191 <patched call position>
1192 ba 00 00 00 00 mov $0x00000000,%edx
1193 8b 89 00 00 00 00 mov 0x00000000(%ecx),%ecx
1194 8b 92 00 00 00 00 mov 0x00000000(%edx),%edx
1196 ba 00 00 00 00 mov $0x00000000,%edx
1198 *******************************************************************************/
1200 bool patcher_checkcast_class(u1 *sp)
1203 java_objectheader *o;
1205 constant_classref *cr;
1208 /* get stuff from the stack */
1210 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1211 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1212 mcode = *((u8 *) (sp + 1 * 4));
1213 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
1215 /* calculate and set the new return address */
1218 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1220 #if defined(USE_THREADS)
1221 /* enter a monitor on the patching position */
1223 builtin_monitorenter(o);
1225 /* check if the position has already been patched */
1228 builtin_monitorexit(o);
1234 /* get the fieldinfo */
1236 if (!(c = helper_resolve_classinfo(cr)))
1239 /* patch back original code */
1241 *((u8 *) ra) = mcode;
1243 /* if we show disassembly, we have to skip the nop's */
1245 if (showdisassemble)
1248 /* patch super class' vftbl */
1250 *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
1251 *((ptrint *) (ra + 5 + 6 + 6 + 2 + 1)) = (ptrint) c->vftbl;
1253 #if defined(USE_THREADS)
1254 /* this position has been patched */
1256 o->vftbl = (vftbl_t *) 1;
1258 /* leave the monitor on the patching position */
1260 builtin_monitorexit(o);
1267 /* patcher_instanceof_class ****************************************************
1271 *******************************************************************************/
1273 bool patcher_instanceof_class(u1 *sp)
1276 java_objectheader *o;
1278 constant_classref *cr;
1281 /* get stuff from the stack */
1283 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1284 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1285 mcode = *((u8 *) (sp + 1 * 4));
1286 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
1288 /* calculate and set the new return address */
1291 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1293 #if defined(USE_THREADS)
1294 /* enter a monitor on the patching position */
1296 builtin_monitorenter(o);
1298 /* check if the position has already been patched */
1301 builtin_monitorexit(o);
1307 /* get the fieldinfo */
1309 if (!(c = helper_resolve_classinfo(cr)))
1312 /* patch back original code */
1314 *((u8 *) ra) = mcode;
1316 /* if we show disassembly, we have to skip the nop's */
1318 if (showdisassemble)
1321 /* patch super class' vftbl */
1323 *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
1325 #if defined(USE_THREADS)
1326 /* this position has been patched */
1328 o->vftbl = (vftbl_t *) 1;
1330 /* leave the monitor on the patching position */
1332 builtin_monitorexit(o);
1339 /* patcher_clinit **************************************************************
1343 *******************************************************************************/
1345 bool patcher_clinit(u1 *sp)
1348 java_objectheader *o;
1352 /* get stuff from the stack */
1354 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1355 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1356 mcode = *((u8 *) (sp + 1 * 4));
1357 c = (classinfo *) *((ptrint *) (sp + 0 * 4));
1359 /* calculate and set the new return address */
1362 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1364 #if defined(USE_THREADS)
1365 /* enter a monitor on the patching position */
1367 builtin_monitorenter(o);
1369 /* check if the position has already been patched */
1372 builtin_monitorexit(o);
1378 /* check if the class is initialized */
1380 if (!c->initialized)
1381 if (!initialize_class(c))
1384 /* patch back original code */
1386 *((u8 *) ra) = mcode;
1388 #if defined(USE_THREADS)
1389 /* this position has been patched */
1391 o->vftbl = (vftbl_t *) 1;
1393 /* leave the monitor on the patching position */
1395 builtin_monitorexit(o);
1403 * These are local overrides for various environment variables in Emacs.
1404 * Please do not remove this and leave it at the end of the file, where
1405 * Emacs will automagically detect them.
1406 * ---------------------------------------------------------------------
1409 * indent-tabs-mode: t
1413 * vim:noexpandtab:sw=4:ts=4: