1 /* src/vm/jit/x86_64/patcher.c - x86_64 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 2412 2005-04-29 15:22:08Z twisti $
36 #include "vm/jit/x86_64/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"
43 #include "vm/exceptions.h"
46 /* patcher_get_putstatic *******************************************************
50 <patched call position>
51 4d 8b 15 86 fe ff ff mov -378(%rip),%r10
53 *******************************************************************************/
55 bool patcher_get_putstatic(u1 *sp)
65 /* get stuff from the stack */
67 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
68 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
69 mcode = *((u8 *) (sp + 1 * 8));
70 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
72 beginJavaStack= (void*)(sp + 3 * 8);
74 *dontfillinexceptionstacktrace=true;
76 /* calculate and set the new return address */
79 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
81 #if defined(USE_THREADS)
82 /* enter a monitor on the patching position */
84 printf("monitorenter before: %p\n", THREADOBJECT);
85 builtin_monitorenter(o);
86 printf("monitorenter after : %p\n", THREADOBJECT);
88 /* check if the position has already been patched */
91 builtin_monitorexit(o);
97 /* get the fieldinfo */
99 if (!(fi = helper_resolve_fieldinfo(uf))) {
100 *dontfillinexceptionstacktrace=false;
104 /* check if the field's class is initialized */
106 *dontfillinexceptionstacktrace=false;
107 if (!fi->class->initialized) {
110 /*struct native_stackframeinfo {
111 void *oldThreadspecificHeadValue;
112 void **addressOfThreadspecificHead;
114 void *beginOfJavaStackframe; only used if != 0
115 void *returnToFromNative;
117 /* more or less the same as the above sfi setup is done in the assembler code by the prepare/remove functions*/
118 native_stackframeinfo sfi;
119 sfi.returnToFromNative=(void*)ra;
120 sfi.beginOfJavaStackframe=beginJavaStack;
121 sfi.method=0; /*internal*/
122 sfi.addressOfThreadspecificHead=builtin_asm_get_stackframeinfo();
123 sfi.oldThreadspecificHeadValue=*(sfi.addressOfThreadspecificHead);
124 *(sfi.addressOfThreadspecificHead)=&sfi;
126 init=initialize_class(fi->class);
128 *(sfi.addressOfThreadspecificHead)=sfi.oldThreadspecificHeadValue;
136 *dontfillinexceptionstacktrace=false;
138 /* patch back original code */
140 *((u8 *) ra) = mcode;
142 /* if we show disassembly, we have to skip the nop's */
147 /* get RIP offset from machine instruction */
149 offset = *((u4 *) (ra + 3));
151 /* patch the field value's address (+ 7: is the size of the RIP move) */
153 *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
155 #if defined(USE_THREADS)
156 /* leave the monitor on the patching position */
158 builtin_monitorexit(o);
160 /* this position has been patched */
162 o->vftbl = (vftbl_t *) 1;
169 /* patcher_get_putfield ********************************************************
173 <patched call position>
174 45 8b 8f 00 00 00 00 mov 0x0(%r15),%r9d
176 *******************************************************************************/
178 bool patcher_get_putfield(u1 *sp)
181 java_objectheader *o;
183 unresolved_field *uf;
186 /* get stuff from the stack */
188 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
189 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
190 mcode = *((u8 *) (sp + 1 * 8));
191 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
193 /* calculate and set the new return address */
196 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
198 *dontfillinexceptionstacktrace=true;
200 #if defined(USE_THREADS)
201 /* enter a monitor on the patching position */
203 builtin_monitorenter(o);
205 /* check if the position has already been patched */
208 builtin_monitorexit(o);
214 /* get the fieldinfo */
216 if (!(fi = helper_resolve_fieldinfo(uf))) {
217 *dontfillinexceptionstacktrace=false;
221 /* patch back original code */
223 *((u8 *) ra) = mcode;
225 /* if we show disassembly, we have to skip the nop's */
230 /* patch the field's offset: we check for the field type, because the */
231 /* instructions have different lengths */
233 if (IS_FLT_DBL_TYPE(fi->type)) {
234 *((u4 *) (ra + 5)) = (u4) (fi->offset);
239 /* check for special case: %rsp or %r12 as base register */
244 *((u4 *) (ra + 4)) = (u4) (fi->offset);
246 *((u4 *) (ra + 3)) = (u4) (fi->offset);
249 *dontfillinexceptionstacktrace=false;
251 #if defined(USE_THREADS)
252 /* leave the monitor on the patching position */
254 builtin_monitorexit(o);
256 /* this position has been patched */
258 o->vftbl = (vftbl_t *) 1;
265 /* patcher_builtin_new *********************************************************
269 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
270 <patched call position>
271 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
274 *******************************************************************************/
276 bool patcher_builtin_new(u1 *sp)
279 java_objectheader *o;
281 constant_classref *cr;
284 /* get stuff from the stack */
286 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
287 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
288 mcode = *((u8 *) (sp + 1 * 8));
289 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
291 /* calculate and set the new return address */
294 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
296 *dontfillinexceptionstacktrace=true;
298 #if defined(USE_THREADS)
299 /* enter a monitor on the patching position */
301 builtin_monitorenter(o);
303 /* check if the position has already been patched */
306 builtin_monitorexit(o);
312 /* get the classinfo */
314 if (!(c = helper_resolve_classinfo(cr))) {
315 *dontfillinexceptionstacktrace=false;
319 /* patch back original code */
321 *((u8 *) (ra + 10)) = mcode;
323 /* patch the classinfo pointer */
325 *((ptrint *) (ra + 2)) = (ptrint) c;
327 /* if we show disassembly, we have to skip the nop's */
332 /* patch new function address */
334 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_new;
336 *dontfillinexceptionstacktrace=false;
338 #if defined(USE_THREADS)
339 /* leave the monitor on the patching position */
341 builtin_monitorexit(o);
343 /* this position has been patched */
345 o->vftbl = (vftbl_t *) 1;
352 /* patcher_builtin_newarray ****************************************************
356 48 be 88 13 9b 00 00 00 00 00 mov $0x9b1388,%rsi
357 <patched call position>
358 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
361 *******************************************************************************/
363 bool patcher_builtin_newarray(u1 *sp)
366 java_objectheader *o;
368 constant_classref *cr;
371 /* get stuff from the stack */
373 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
374 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
375 mcode = *((u8 *) (sp + 1 * 8));
376 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
378 /* calculate and set the new return address */
381 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
383 *dontfillinexceptionstacktrace=true;
385 #if defined(USE_THREADS)
386 /* enter a monitor on the patching position */
388 builtin_monitorenter(o);
390 /* check if the position has already been patched */
393 builtin_monitorexit(o);
399 /* get the classinfo */
401 if (!(c = helper_resolve_classinfo(cr))) {
402 *dontfillinexceptionstacktrace=false;
406 /* patch back original code */
408 *((u8 *) (ra + 10)) = mcode;
410 /* patch the class' vftbl pointer */
412 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
414 /* if we show disassembly, we have to skip the nop's */
419 /* patch new function address */
421 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_newarray;
423 *dontfillinexceptionstacktrace=false;
425 #if defined(USE_THREADS)
426 /* leave the monitor on the patching position */
428 builtin_monitorexit(o);
430 /* this position has been patched */
432 o->vftbl = (vftbl_t *) 1;
439 /* patcher_builtin_multianewarray **********************************************
443 <patched call position>
444 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
445 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
446 48 89 e2 mov %rsp,%rdx
447 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
450 *******************************************************************************/
452 bool patcher_builtin_multianewarray(u1 *sp)
455 java_objectheader *o;
457 constant_classref *cr;
460 /* get stuff from the stack */
462 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
463 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
464 mcode = *((u8 *) (sp + 1 * 8));
465 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
467 /* calculate and set the new return address */
470 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
472 *dontfillinexceptionstacktrace=true;
474 #if defined(USE_THREADS)
475 /* enter a monitor on the patching position */
477 builtin_monitorenter(o);
479 /* check if the position has already been patched */
482 builtin_monitorexit(o);
488 /* get the classinfo */
490 if (!(c = helper_resolve_classinfo(cr))) {
491 *dontfillinexceptionstacktrace=false;
495 /* patch back original code */
497 *((u8 *) ra) = mcode;
499 /* if we show disassembly, we have to skip the nop's */
504 /* patch the class' vftbl pointer */
506 *((ptrint *) (ra + 10 + 2)) = (ptrint) c->vftbl;
508 /* patch new function address */
510 *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
512 *dontfillinexceptionstacktrace=false;
514 #if defined(USE_THREADS)
515 /* leave the monitor on the patching position */
517 builtin_monitorexit(o);
519 /* this position has been patched */
521 o->vftbl = (vftbl_t *) 1;
528 /* patcher_builtin_checkarraycast **********************************************
532 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
533 <patched call position>
534 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
537 *******************************************************************************/
539 bool patcher_builtin_checkarraycast(u1 *sp)
542 java_objectheader *o;
544 constant_classref *cr;
547 /* get stuff from the stack */
549 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
550 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
551 mcode = *((u8 *) (sp + 1 * 8));
552 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
554 /* calculate and set the new return address */
557 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
559 *dontfillinexceptionstacktrace=true;
561 #if defined(USE_THREADS)
562 /* enter a monitor on the patching position */
564 builtin_monitorenter(o);
566 /* check if the position has already been patched */
569 builtin_monitorexit(o);
575 /* get the classinfo */
577 if (!(c = helper_resolve_classinfo(cr))) {
578 *dontfillinexceptionstacktrace=false;
582 /* patch back original code */
584 *((u8 *) (ra + 10)) = mcode;
586 /* patch the class' vftbl pointer */
588 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
590 /* if we show disassembly, we have to skip the nop's */
595 /* patch new function address */
597 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_checkarraycast;
599 *dontfillinexceptionstacktrace=false;
601 #if defined(USE_THREADS)
602 /* leave the monitor on the patching position */
604 builtin_monitorexit(o);
606 /* this position has been patched */
608 o->vftbl = (vftbl_t *) 1;
615 /* patcher_builtin_arrayinstanceof *********************************************
619 48 be 30 3c b2 00 00 00 00 00 mov $0xb23c30,%rsi
620 <patched call position>
621 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
624 *******************************************************************************/
626 bool patcher_builtin_arrayinstanceof(u1 *sp)
629 java_objectheader *o;
631 constant_classref *cr;
634 /* get stuff from the stack */
636 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
637 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
638 mcode = *((u8 *) (sp + 1 * 8));
639 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
641 /* calculate and set the new return address */
644 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
646 *dontfillinexceptionstacktrace=true;
648 #if defined(USE_THREADS)
649 /* enter a monitor on the patching position */
651 builtin_monitorenter(o);
653 /* check if the position has already been patched */
656 builtin_monitorexit(o);
662 /* get the classinfo */
664 if (!(c = helper_resolve_classinfo(cr))) {
665 *dontfillinexceptionstacktrace=false;
669 /* patch back original code */
671 *((u8 *) (ra + 10)) = mcode;
673 /* patch the class' vftbl pointer */
675 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
677 /* if we show disassembly, we have to skip the nop's */
682 /* patch new function address */
684 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arrayinstanceof;
686 *dontfillinexceptionstacktrace=false;
688 #if defined(USE_THREADS)
689 /* leave the monitor on the patching position */
691 builtin_monitorexit(o);
693 /* this position has been patched */
695 o->vftbl = (vftbl_t *) 1;
702 /* patcher_invokestatic_special ************************************************
706 *******************************************************************************/
708 bool patcher_invokestatic_special(u1 *sp)
711 java_objectheader *o;
713 unresolved_method *um;
716 /* get stuff from the stack */
718 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
719 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
720 mcode = *((u8 *) (sp + 1 * 8));
721 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
723 /* calculate and set the new return address */
726 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
728 *dontfillinexceptionstacktrace=true;
730 #if defined(USE_THREADS)
731 /* enter a monitor on the patching position */
733 builtin_monitorenter(o);
735 /* check if the position has already been patched */
738 builtin_monitorexit(o);
744 /* get the fieldinfo */
746 if (!(m = helper_resolve_methodinfo(um))) {
747 *dontfillinexceptionstacktrace=false;
750 /* patch back original code */
752 *((u8 *) ra) = mcode;
754 /* if we show disassembly, we have to skip the nop's */
759 /* patch stubroutine */
761 *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
763 *dontfillinexceptionstacktrace=false;
765 #if defined(USE_THREADS)
766 /* leave the monitor on the patching position */
768 builtin_monitorexit(o);
770 /* this position has been patched */
772 o->vftbl = (vftbl_t *) 1;
779 /* patcher_invokevirtual *******************************************************
783 *******************************************************************************/
785 bool patcher_invokevirtual(u1 *sp)
788 java_objectheader *o;
790 unresolved_method *um;
793 /* get stuff from the stack */
795 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
796 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
797 mcode = *((u8 *) (sp + 1 * 8));
798 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
800 /* calculate and set the new return address */
803 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
805 *dontfillinexceptionstacktrace=true;
807 #if defined(USE_THREADS)
808 /* enter a monitor on the patching position */
810 builtin_monitorenter(o);
812 /* check if the position has already been patched */
815 builtin_monitorexit(o);
821 /* get the fieldinfo */
823 if (!(m = helper_resolve_methodinfo(um))) {
824 *dontfillinexceptionstacktrace=false;
828 /* patch back original code */
830 *((u8 *) ra) = mcode;
832 /* if we show disassembly, we have to skip the nop's */
837 /* patch vftbl index */
839 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
840 sizeof(methodptr) * m->vftblindex);
842 *dontfillinexceptionstacktrace=false;
844 #if defined(USE_THREADS)
845 /* leave the monitor on the patching position */
847 builtin_monitorexit(o);
849 /* this position has been patched */
851 o->vftbl = (vftbl_t *) 1;
858 /* patcher_invokeinterface *****************************************************
862 *******************************************************************************/
864 bool patcher_invokeinterface(u1 *sp)
867 java_objectheader *o;
869 unresolved_method *um;
872 /* get stuff from the stack */
874 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
875 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
876 mcode = *((u8 *) (sp + 1 * 8));
877 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
879 /* calculate and set the new return address */
882 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
884 *dontfillinexceptionstacktrace=true;
886 #if defined(USE_THREADS)
887 /* enter a monitor on the patching position */
889 builtin_monitorenter(o);
891 /* check if the position has already been patched */
894 builtin_monitorexit(o);
900 /* get the fieldinfo */
902 if (!(m = helper_resolve_methodinfo(um))) {
903 *dontfillinexceptionstacktrace=false;
907 /* patch back original code */
909 *((u8 *) ra) = mcode;
911 /* if we show disassembly, we have to skip the nop's */
916 /* patch interfacetable index */
918 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
919 sizeof(methodptr) * m->class->index);
921 /* patch method offset */
923 *((s4 *) (ra + 3 + 7 + 3)) =
924 (s4) (sizeof(methodptr) * (m - m->class->methods));
926 *dontfillinexceptionstacktrace=false;
928 #if defined(USE_THREADS)
929 /* leave the monitor on the patching position */
931 builtin_monitorexit(o);
933 /* this position has been patched */
935 o->vftbl = (vftbl_t *) 1;
942 /* patcher_checkcast_instanceof_flags ******************************************
946 *******************************************************************************/
948 bool patcher_checkcast_instanceof_flags(u1 *sp)
951 java_objectheader *o;
953 constant_classref *cr;
956 /* get stuff from the stack */
958 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
959 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
960 mcode = *((u8 *) (sp + 1 * 8));
961 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
963 /* calculate and set the new return address */
966 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
968 *dontfillinexceptionstacktrace=true;
970 #if defined(USE_THREADS)
971 /* enter a monitor on the patching position */
973 builtin_monitorenter(o);
975 /* check if the position has already been patched */
978 builtin_monitorexit(o);
984 /* get the fieldinfo */
986 if (!(c = helper_resolve_classinfo(cr))) {
987 *dontfillinexceptionstacktrace=false;
991 /* patch back original code */
993 *((u8 *) ra) = mcode;
995 /* if we show disassembly, we have to skip the nop's */
1000 /* patch class flags */
1002 *((s4 *) (ra + 2)) = (s4) c->flags;
1004 *dontfillinexceptionstacktrace=false;
1006 #if defined(USE_THREADS)
1007 /* leave the monitor on the patching position */
1009 builtin_monitorexit(o);
1011 /* this position has been patched */
1013 o->vftbl = (vftbl_t *) 1;
1020 /* patcher_checkcast_instanceof_interface **************************************
1024 *******************************************************************************/
1026 bool patcher_checkcast_instanceof_interface(u1 *sp)
1029 java_objectheader *o;
1031 constant_classref *cr;
1034 /* get stuff from the stack */
1036 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1037 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1038 mcode = *((u8 *) (sp + 1 * 8));
1039 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1041 /* calculate and set the new return address */
1044 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1046 *dontfillinexceptionstacktrace=true;
1048 #if defined(USE_THREADS)
1049 /* enter a monitor on the patching position */
1051 builtin_monitorenter(o);
1053 /* check if the position has already been patched */
1056 builtin_monitorexit(o);
1062 /* get the fieldinfo */
1064 if (!(c = helper_resolve_classinfo(cr))) {
1065 *dontfillinexceptionstacktrace=false;
1069 /* patch back original code */
1071 *((u8 *) ra) = mcode;
1073 /* if we show disassembly, we have to skip the nop's */
1075 if (showdisassemble)
1078 /* patch super class index */
1080 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
1082 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
1083 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1084 c->index * sizeof(methodptr*));
1086 *dontfillinexceptionstacktrace=false;
1088 #if defined(USE_THREADS)
1089 /* leave the monitor on the patching position */
1091 builtin_monitorexit(o);
1093 /* this position has been patched */
1095 o->vftbl = (vftbl_t *) 1;
1102 /* patcher_checkcast_class *****************************************************
1106 *******************************************************************************/
1108 bool patcher_checkcast_class(u1 *sp)
1111 java_objectheader *o;
1113 constant_classref *cr;
1116 /* get stuff from the stack */
1118 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1119 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1120 mcode = *((u8 *) (sp + 1 * 8));
1121 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1123 /* calculate and set the new return address */
1126 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1128 *dontfillinexceptionstacktrace=true;
1130 #if defined(USE_THREADS)
1131 /* enter a monitor on the patching position */
1133 builtin_monitorenter(o);
1135 /* check if the position has already been patched */
1138 builtin_monitorexit(o);
1144 /* get the fieldinfo */
1146 if (!(c = helper_resolve_classinfo(cr))) {
1147 *dontfillinexceptionstacktrace=false;
1151 /* patch back original code */
1153 *((u8 *) ra) = mcode;
1155 /* if we show disassembly, we have to skip the nop's */
1157 if (showdisassemble)
1160 /* patch super class' vftbl */
1162 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1163 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
1165 *dontfillinexceptionstacktrace=false;
1167 #if defined(USE_THREADS)
1168 /* leave the monitor on the patching position */
1170 builtin_monitorexit(o);
1172 /* this position has been patched */
1174 o->vftbl = (vftbl_t *) 1;
1181 /* patcher_instanceof_class ****************************************************
1185 *******************************************************************************/
1187 bool patcher_instanceof_class(u1 *sp)
1190 java_objectheader *o;
1192 constant_classref *cr;
1195 /* get stuff from the stack */
1197 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1198 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1199 mcode = *((u8 *) (sp + 1 * 8));
1200 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1202 /* calculate and set the new return address */
1205 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1207 *dontfillinexceptionstacktrace=true;
1209 #if defined(USE_THREADS)
1210 /* enter a monitor on the patching position */
1212 builtin_monitorenter(o);
1214 /* check if the position has already been patched */
1217 builtin_monitorexit(o);
1223 /* get the fieldinfo */
1225 if (!(c = helper_resolve_classinfo(cr))) {
1226 *dontfillinexceptionstacktrace=false;
1230 /* patch back original code */
1232 *((u8 *) ra) = mcode;
1234 /* if we show disassembly, we have to skip the nop's */
1236 if (showdisassemble)
1239 /* patch super class' vftbl */
1241 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1243 *dontfillinexceptionstacktrace=false;
1245 #if defined(USE_THREADS)
1246 /* leave the monitor on the patching position */
1248 builtin_monitorexit(o);
1250 /* this position has been patched */
1252 o->vftbl = (vftbl_t *) 1;
1259 /* patcher_clinit **************************************************************
1263 *******************************************************************************/
1265 bool patcher_clinit(u1 *sp)
1268 java_objectheader *o;
1271 void *beginJavaStack;
1273 /* get stuff from the stack */
1275 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1276 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1277 mcode = *((u8 *) (sp + 1 * 8));
1278 c = (classinfo *) *((ptrint *) (sp + 0 * 8));
1280 beginJavaStack = (void*) (sp + 3 * 8);
1282 /*printf("beginJavaStack: %p, ra %p\n",beginJavaStack,ra);*/
1283 /* calculate and set the new return address */
1286 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1288 #if defined(USE_THREADS)
1289 /* enter a monitor on the patching position */
1291 builtin_monitorenter(o);
1293 /* check if the position has already been patched */
1296 builtin_monitorexit(o);
1302 /* check if the class is initialized */
1304 if (!c->initialized) {
1307 /*struct native_stackframeinfo {
1308 void *oldThreadspecificHeadValue;
1309 void **addressOfThreadspecificHead;
1311 void *beginOfJavaStackframe; only used if != 0
1312 void *returnToFromNative;
1314 /* more or less the same as the above sfi setup is done in the assembler code by the prepare/remove functions*/
1315 native_stackframeinfo sfi;
1316 sfi.returnToFromNative=(void*)ra;
1317 sfi.beginOfJavaStackframe=beginJavaStack;
1318 sfi.method=0; /*internal*/
1319 sfi.addressOfThreadspecificHead=builtin_asm_get_stackframeinfo();
1320 sfi.oldThreadspecificHeadValue=*(sfi.addressOfThreadspecificHead);
1321 *(sfi.addressOfThreadspecificHead)=&sfi;
1323 init=initialize_class(c);
1325 *(sfi.addressOfThreadspecificHead)=sfi.oldThreadspecificHeadValue;
1333 /* patch back original code */
1335 *((u8 *) ra) = mcode;
1337 #if defined(USE_THREADS)
1338 /* leave the monitor on the patching position */
1340 builtin_monitorexit(o);
1342 /* this position has been patched */
1344 o->vftbl = (vftbl_t *) 1;
1352 * These are local overrides for various environment variables in Emacs.
1353 * Please do not remove this and leave it at the end of the file, where
1354 * Emacs will automagically detect them.
1355 * ---------------------------------------------------------------------
1358 * indent-tabs-mode: t
1362 * vim:noexpandtab:sw=4:ts=4: