1 /* vm/jit/i386/asmpart.S - Java-C interface functions for i386
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
32 $Id: asmpart.S 1623 2004-11-30 14:18:19Z twisti $
38 #include "vm/jit/i386/offsets.h"
41 /* data segment offsets */
43 #define MethodPointer -4
49 #define LineNumberTableSize -28
50 #define LineNumberTableStart -32
51 #define ExTableSize -36
52 #define ExTableStart -36
54 #define ExEntrySize -16
57 #define ExHandlerPC -12
58 #define ExCatchType -16
61 #define LineEntrySize -8
77 /********************* exported functions and variables ***********************/
79 .globl asm_calljavafunction
80 .globl calljava_xhandler
81 .globl asm_calljavafunction2
82 .globl asm_calljavafunction2long
83 .globl asm_calljavafunction2double
84 .globl calljava_xhandler2
86 .globl asm_call_jit_compiler
87 .globl asm_handle_builtin_exception
88 .globl asm_handle_nat_exception
89 .globl asm_handle_exception
90 .globl asm_check_clinit
91 .globl asm_builtin_checkcast
92 .globl asm_builtin_checkarraycast
93 .globl asm_builtin_newarray
94 .globl asm_builtin_anewarray
95 .globl asm_builtin_newarray_array
96 .globl asm_builtin_aastore
97 .globl asm_builtin_monitorenter
98 .globl asm_builtin_monitorexit
99 .globl asm_builtin_ldiv
100 .globl asm_builtin_lrem
101 .globl asm_builtin_f2i
102 .globl asm_builtin_f2l
103 .globl asm_builtin_d2i
104 .globl asm_builtin_d2l
105 .globl asm_builtin_arrayinstanceof
106 .globl asm_perform_threadswitch
107 .globl asm_initialize_thread_stack
108 .globl asm_switchstackandcall
109 .globl asm_getcallingmethod
110 .globl Java_java_lang_VMSecurityManager_getClassContext
111 .globl Java_java_lang_VMSecurityManager_currentClassLoader
112 .globl asm_builtin_new
113 .globl asm_get_stackTrace
114 .globl asm_criticalsections
115 .globl asm_getclassvalues_atomic
117 /*************************** imported functions *******************************/
120 .globl builtin_monitorexit
121 .globl builtin_throw_exception
122 .globl builtin_trace_exception
123 .globl class_java_lang_Object
124 .globl codegen_findmethod
125 /* .globl codegen_findmethod1*/
126 .globl builtin_asm_createclasscontextarray
127 .globl builtin_asm_getclassloader
128 .globl callgetexceptionptrptr
129 .globl asm_throw_and_handle_exception
130 .globl asm_throw_and_handle_hardware_arithmetic_exception
133 /********************* function asm_calljavafunction ***************************
135 * This function calls a Java-method (which possibly needs compilation) *
136 * with up to 4 address parameters. *
138 * This functions calls the JIT-compiler which eventually translates the *
139 * method into machine code. *
142 * javaobject_header *asm_calljavamethod (methodinfo *m, *
143 * void *arg1, void *arg2, void *arg3, void *arg4); *
145 *******************************************************************************/
148 .ascii "calljavafunction\0\0"
151 .long 0 /* catch type all */
152 .long calljava_xhandler /* handler pc */
153 .long calljava_xhandler /* end pc */
154 .long asm_calljavafunction /* start pc */
155 .long 1 /* extable size */
156 .long 0 /* line number table start */
157 .long 0 /* line number table size */
158 .long 0 /* fltsave */
159 .long 0 /* intsave */
162 .long 32 /* frame size */
163 .long 0 /* method pointer (pointer to name) */
165 asm_calljavafunction:
166 push %ebp /* allocate stack space */
169 push %ebx /* save registers */
173 sub $32,%esp /* pass the remaining parameters */
176 mov %edx,28(%esp) /* convert parms to 8 byte */
192 mov 8(%ebp),%eax /* move function pointer to %eax */
194 lea asm_call_jit_compiler,%edx
195 call *%edx /* call JIT compiler */
198 pop %edi /* restore registers */
205 push %eax /* pass exception pointer */
206 call builtin_throw_exception
210 pop %edi /* restore registers */
217 /********************* function asm_calljavafunction ***************************
219 * This function calls a Java-method (which possibly needs compilation) *
220 * with up to 4 address parameters. *
222 * This functions calls the JIT-compiler which eventually translates the *
223 * method into machine code. *
226 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
227 * u4 count, u4 size, void *callblock); *
229 *******************************************************************************/
232 .ascii "calljavafunction2\0\0"
235 .long 0 /* catch type all */
236 .long calljava_xhandler2 /* handler pc */
237 .long calljava_xhandler2 /* end pc */
238 .long asm_calljavafunction2 /* start pc */
239 .long 1 /* extable size */
240 .long 0 /* line number table start */
241 .long 0 /* line number table size */
242 .long 0 /* fltsave */
243 .long 0 /* intsave */
246 .long 32 /* frame size */
247 .long 0 /* method pointer (pointer to name) */
249 asm_calljavafunction2:
250 asm_calljavafunction2double:
251 asm_calljavafunction2long:
253 mov %esp,%ebp /* save stackptr */
255 push %ebx /* save registers */
259 mov 20(%ebp),%eax /* pointer to arg block */
260 mov 12(%ebp),%ecx /* arg count */
261 test %ecx,%ecx /* maybe we have no args */
262 jle calljava_copydone
264 mov %ecx,%edx /* calculate stack size */
266 mov %edx,%esi /* save in callee saved register */
267 sub %esi,%esp /* stack frame for arguments */
271 mov offjniitem(%eax),%edx
273 mov offjniitem+4(%eax),%edx
276 sub $1,%ecx /* are there any args left? */
278 jle calljava_copydone
280 add $sizejniblock,%eax /* goto next argument block */
281 add $8,%edi /* increase sp to next argument */
282 jmp calljava_copyloop
285 mov 8(%ebp),%eax /* move function pointer to %eax */
287 lea asm_call_jit_compiler,%edx
288 call *%edx /* call JIT compiler */
291 add %esi,%esp /* remove arg stack frame */
292 pop %edi /* restore registers */
299 push %eax /* pass exception pointer */
300 call builtin_throw_exception
303 add %esi,%esp /* remove arg stack frame */
304 pop %edi /* restore registers */
311 /****************** function asm_call_jit_compiler *****************************
313 * invokes the compiler for untranslated JavaVM methods. *
315 * Register R0 contains a pointer to the method info structure (prepared *
316 * by createcompilerstub). Using the return address in R26 and the *
317 * offset in the LDA instruction or using the value in methodptr R28 the *
318 * patching address for storing the method address can be computed: *
320 * method address was either loaded using *
322 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
323 * i386_call_reg(REG_ITMP2) *
327 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
328 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
329 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
330 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
331 * i386_call_reg(REG_ITMP1) *
333 * in the static case the method pointer can be computed using the *
334 * return address and the lda function following the jmp instruction *
336 *******************************************************************************/
338 asm_call_jit_compiler:
339 push %ebx /* save register */
342 mov 8(%esp),%ebp /* get return address (2 push) */
343 mov -1(%ebp),%bl /* get function code */
344 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
345 jne L_not_static_special
347 sub $6,%ebp /* calculate address of immediate */
348 jmp L_call_jit_compile
350 L_not_static_special:
351 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
352 jne L_not_virtual_interface
354 sub $6,%ebp /* calculate address of offset */
355 mov (%ebp),%ebp /* get offset */
356 add itmp2,%ebp /* add base address to get method address */
357 jmp L_call_jit_compile
359 L_not_virtual_interface: /* a call from asm_calljavafunction */
363 push %ebp /* save address for method pointer */
365 push %eax /* push methodpointer on stack */
369 pop %ebp /* restore address for method pointer */
371 test %eax,%eax /* check for exception */
374 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
377 mov %eax,(%ebp) /* and now save the new pointer */
380 pop %ebp /* restore registers */
383 jmp *%eax /* ...and now call the new method */
386 pop %ebp /* restore registers */
389 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
390 call builtin_asm_get_exceptionptrptr
392 mov (%ecx),%eax /* get the exception pointer */
393 movl $0,(%ecx) /* clear the exception pointer */
395 lea _exceptionptr,%ecx
396 mov (%ecx),%eax /* get the exception pointer */
397 movl $0,(%ecx) /* clear the exception pointer */
400 pop %ecx /* delete return address */
401 sub $2,%ecx /* faulting address is return adress - 2 */
403 L_refillinStacktrace:
404 push %ecx /* store fault adress */
405 push %eax /* temporarily save exception pointer*/
406 call builtin_asm_get_stackframeinfo
407 push %eax /* save location of thread specific stack info head pointer */
408 mov (%eax),%ecx /* save old value of pointer*/
410 mov %esp,(%eax) /*store pointer to this structure*/
411 mov 8(%esp),%eax /* get the exception pointer again*/
412 movl $0,8(%esp) /*mark this block as native*/
413 push $0 /*used for the jni_callblock structure*/
414 push %eax /*save eax for later */
415 /* get fillInStackTrace method*/
416 push utf_fillInStackTrace_desc
417 push utf_fillInStackTrace_name
418 mov offobjvftbl(%eax),%ecx
419 mov offclass(%ecx),%eax
421 call class_resolvemethod
429 call asm_calljavafunction2
432 /*remove native stack info */
441 jmp asm_handle_exception
444 /********************* function asm_handle_exception ***************************
446 * This function handles an exception. It does not use the usual calling *
447 * conventions. The exception pointer is passed in REG_ITMP1 and the *
448 * pc from the exception raising position is passed in REG_ITMP2. It searches *
449 * the local exception table for a handler. If no one is found, it unwinds *
450 * stacks and continues searching the callers. *
452 * void asm_handle_exception (exceptionptr, exceptionpc); *
454 *******************************************************************************/
456 asm_handle_nat_exception:
457 add $4,%esp /* clear return address of native stub */
459 asm_handle_exception:
463 push %eax /* exception pointer */
464 push %ecx /* excepiton pc */
466 call asm_get_stackTrace
472 asm_handle_exception_loop:
476 push %eax /* save exception pointer */
477 push %ecx /* save exception pc */
479 call codegen_findmethod /* get the data segment ptr */
483 mov -8(%ebp),%ecx /* could be changed in findmethod */
485 push %edx /* save data segment pointer */
492 mov %eax,(%esp) /* exception pointer */
493 mov MethodPointer(%edx),%eax /* method pointer */
495 mov %ecx,8(%esp) /* exception pc */
496 movl $0,12(%esp) /* line number */
497 movl $1,16(%esp) /* set no unwind flag */
498 call builtin_trace_exception
500 mov -12(%ebp),%esi /* %esi = data segment pointer */
501 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
502 test %ecx,%ecx /* if empty table skip */
505 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
506 mov -4(%ebp),%eax /* get xptr */
509 mov -8(%ebp),%edx /* get xpc */
511 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
512 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
513 jg ex_table_cont /* if (false) continue */
514 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
515 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
516 jge ex_table_cont /* if (false) continue */
517 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
518 test %ebx,%ebx /* NULL catches everything */
521 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
525 mov %eax,1*4(%esp) /* save not callee saved regs */
528 mov %ebx,0*4(%esp) /* exception class is argument */
537 cmpl $0,offclasslinked(%ebx)
541 mov %eax,1*4(%esp) /* save not callee saved regs */
544 mov %ebx,0*4(%esp) /* exception class is argument */
553 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
561 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
562 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
563 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
564 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
565 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
567 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
569 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
573 cmp %ebx,%esi /* xptr is instanceof catchtype */
577 mov ExHandlerPC(%edi),%edx
579 pop %edi /* restore registers */
582 add $8,%esp /* suck %ecx, %edx */
583 pop %eax /* restore xptr */
586 jmp *%edx /* jump to exception handler */
589 lea ExEntrySize(%edi),%edi
598 pop %edx /* restore data segment pointer */
603 push %eax /* save exception pointer */
606 mov IsSync(%edx),%eax /* %eax = SyncOffset */
607 test %eax,%eax /* if zero no monitorexit */
611 mov -4(%eax),%eax /* we have the xptr on the stack */
612 push %edx /* save regs */
614 call builtin_monitorexit
616 pop %edx /* restore regs */
620 add FrameSize(%edx),%eax /* %eax = frame size */
621 add $4,%eax /* we have the xptr on the stack */
623 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
645 shl $3,%ecx /* multiply by 8 bytes */
649 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
676 pop %eax /* restore exception pointer */
678 mov FrameSize(%edx),%ecx /* %ecx = frame size */
679 add %ecx,%esp /* unwind stack */
681 pop %ecx /* the new xpc is return address */
684 jmp asm_handle_exception_loop
687 /* asm_check_clinit ************************************************************
693 16 ra ; return address of patched call in java machine code
694 12 xmcode ; additional machine code (only for i386 and x86_64)
695 8 mcode ; machine code to patch back in
696 4 class ; pointer to class
697 0 sp ; stack pointer of java stack frame + return address
699 *******************************************************************************/
702 mov 4(%esp),%eax /* get fieldinfo's class pointer */
703 mov offclassinit(%eax),%eax /* get initialized flag */
708 sub $16,%esp /* build stack frame (4 * 4 bytes) */
709 mov %eax,(%esp) /* put classpointer on stack */
710 call builtin_asm_get_stackframeinfo
722 mov 4+4(%esp),itmp1 /* get class pointer */
723 mov itmp1,(%esp) /* store class pointer as a0 */
724 call class_init /* call class_init function */
735 test %eax,%eax /* we had an exception */
736 je L_initializererror
739 mov 16(%esp),itmp1 /* get return address */
740 sub $5,itmp1 /* remove size of `call rel32' */
742 mov 12(%esp),itmp2 /* get xmcode machine code */
743 movb itmp2b,(itmp1) /* patch back in 1 byte */
744 mov 8(%esp),itmp2 /* get mcode machine code */
745 mov itmp2,1(itmp1) /* patch back in 4 bytes */
747 add $(5*4),%esp /* remove stub stack frame incl. ra */
749 jmp *itmp1 /* jump to patched code an execute it */
752 add $(4*4),%esp /* remove stub stack frame */
754 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
755 call builtin_asm_get_exceptionptrptr
757 mov (%ecx),%eax /* get the exception pointer */
758 movl $0,(%ecx) /* clear the exception pointer */
760 lea _exceptionptr,%ecx
761 mov (%ecx),%eax /* get the exception pointer */
762 movl $0,(%ecx) /* clear the exception pointer */
765 pop itmp2 /* get and delete ra */
766 sub $5,itmp2 /* faulting address is ra - 5 */
768 jmp asm_handle_exception
771 /********************* function asm_builtin_monitorenter ***********************
773 * Does null check and calls monitorenter or throws an exception *
775 *******************************************************************************/
777 asm_builtin_monitorenter:
779 je nb_monitorenter /* if (null) throw exception */
780 jmp builtin_monitorenter /* else call builtin_monitorenter */
783 mov string_java_lang_NullPointerException,%eax
786 jmp asm_throw_and_handle_exception
789 push string_java_lang_NullPointerException
793 pop %ecx /* delete return address */
794 sub $2,%ecx /* faulting address is return adress - 2 */
795 jmp asm_handle_exception
798 /********************* function asm_builtin_monitorexit ************************
800 * Does null check and calls monitorexit or throws an exception *
802 *******************************************************************************/
804 asm_builtin_monitorexit:
807 je nb_monitorexit /* if (null) throw exception */
808 push %ecx /* save registers which could be used */
811 call builtin_monitorexit /* else call builtin_monitorenter */
813 pop %edx /* restore registers which could be used */
818 mov string_java_lang_NullPointerException,%eax
821 jmp asm_throw_and_handle_exception
824 push string_java_lang_NullPointerException
828 pop %ecx /* delete return address */
829 sub $2,%ecx /* faulting address is return adress - 2 */
830 jmp asm_handle_exception
833 /************************ function asm_builtin_ldiv ****************************
835 * Does null check and calls ldiv or throws an exception *
837 *******************************************************************************/
842 test %eax,%eax /* if (null) throw exception */
850 jmp asm_throw_and_handle_hardware_arithmetic_exception
852 push string_java_lang_ArithmeticException_message
853 push string_java_lang_ArithmeticException
854 call new_exception_message
857 pop %ecx /* delete return address */
858 sub $2,%ecx /* faulting address is return adress - 2 */
859 jmp asm_handle_exception
862 /************************ function asm_builtin_lrem ****************************
864 * Does null check and calls lrem or throws an exception *
866 *******************************************************************************/
871 test %eax,%eax /* if (null) throw exception */
879 jmp asm_throw_and_handle_hardware_arithmetic_exception
881 push string_java_lang_ArithmeticException_message
882 push string_java_lang_ArithmeticException
883 call new_exception_message
886 pop %ecx /* delete return address */
887 sub $2,%ecx /* faulting address is return adress - 2 */
888 jmp asm_handle_exception
891 /************************ function asm_builtin_x2x *****************************
893 * Wrapper functions for corner cases *
895 *******************************************************************************/
926 /******************* function asm_builtin_checkarraycast ***********************
928 * Does the cast check and eventually throws an exception *
930 *******************************************************************************/
932 asm_builtin_checkarraycast:
933 sub $8,%esp /* build stack frame (2 * 4 bytes) */
935 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
936 mov %eax,(%esp) /* save object pointer */
941 call builtin_checkarraycast /* builtin_checkarraycast */
943 test %eax,%eax /* if (false) throw exception */
946 mov 12(%esp),%eax /* return object pointer */
952 mov string_java_lang_ClassCastException,%eax
955 jmp asm_throw_and_handle_exception
957 push string_java_lang_ClassCastException
963 pop %ecx /* delete return address */
964 sub $2,%ecx /* faulting address is return adress - 2 */
965 jmp asm_handle_exception
968 /******************* function asm_builtin_newarray *****************************
970 * Does the cast check and eventually throws an exception *
972 *******************************************************************************/
974 asm_builtin_newarray:
975 sub $8,%esp /* build stack frame (2 * 4 bytes) */
983 call builtin_newarray
989 /******************* function asm_builtin_aastore ******************************
991 * Does the cast check and eventually throws an exception *
993 *******************************************************************************/
996 sub $12,%esp /* build stack frame (3 * 4 bytes) */
998 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
999 test %eax,%eax /* if null pointer throw exception */
1002 mov offarraysize(%eax),%edx /* load size */
1003 mov 24(%esp),%ecx /* index */
1004 cmp %edx,%ecx /* do bound check */
1005 jae nb_aastore_bound /* if out of bounds throw exception */
1007 shl $2,%ecx /* index * 4 */
1008 add %eax,%ecx /* add index * 4 to arrayref */
1010 mov %ecx,8(%esp) /* save store position */
1012 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
1015 mov 32(%esp),%eax /* object is second argument */
1018 call builtin_canstore /* builtin_canstore(arrayref,object) */
1020 test %eax,%eax /* if (false) throw exception */
1025 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
1032 mov string_java_lang_NullPointerException,%eax
1035 jmp asm_throw_and_handle_exception
1038 push string_java_lang_NullPointerException
1043 pop %ecx /* delete return address */
1044 sub $2,%ecx /* faulting address is return adress - 2 */
1045 jmp asm_handle_exception
1048 push %ecx /* itmp2 contains array index */
1049 call new_arrayindexoutofboundsexception
1053 pop %ecx /* delete return address */
1054 sub $2,%ecx /* faulting address is return adress - 2 */
1055 jmp asm_handle_exception
1060 mov string_java_lang_ArrayStoreException,%eax
1063 jmp asm_throw_and_handle_exception
1066 push string_java_lang_ArrayStoreException
1071 pop %ecx /* delete return address */
1072 sub $2,%ecx /* faulting address is return adress - 2 */
1073 jmp asm_handle_exception
1076 /******************* function asm_builtin_arrayinstanceof **********************
1078 * Does the instanceof check of arrays *
1080 *******************************************************************************/
1082 asm_builtin_arrayinstanceof:
1083 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1091 call builtin_arrayinstanceof
1097 /******************* function asm_initialize_thread_stack **********************
1099 * initialized a thread stack *
1100 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1102 *******************************************************************************/
1104 asm_initialize_thread_stack:
1105 mov 8(%esp),%eax /* (to)->stackEnd */
1106 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1118 mov 4(%esp),%edx /* save (u1*) (func) */
1121 ret /* return restorepoint in %eax */
1124 /******************* function asm_perform_threadswitch *************************
1126 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1128 * performs a threadswitch *
1130 *******************************************************************************/
1132 asm_perform_threadswitch:
1144 mov 36(%esp),%eax /* save current return address */
1147 mov 40(%esp),%eax /* first argument **from */
1150 mov 48(%esp),%eax /* third argument **stackTop */
1153 mov 44(%esp),%eax /* second argument **to */
1154 mov 0(%eax),%esp /* load new stack pointer */
1160 /* skip stack pointer */
1165 add $32,%esp /* leave return address on stack */
1169 /********************* function asm_switchstackandcall *************************
1171 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1174 * Switches to a new stack, calls a function and switches back. *
1175 * a0 new stack pointer *
1176 * a1 function pointer *
1177 * a2 pointer to variable where stack top should be stored *
1178 * a3 pointer to user data, is passed to the function *
1180 *******************************************************************************/
1182 asm_switchstackandcall:
1183 mov 4(%esp),%edx /* first argument *stack */
1184 sub $8,%edx /* allocate new stack */
1186 mov (%esp),%eax /* save return address on new stack */
1189 mov %esp,4(%edx) /* save old stack pointer on new stack */
1191 mov 12(%esp),%eax /* third argument **stacktopsave */
1192 mov %esp,(%eax) /* save old stack pointer to variable */
1194 mov 8(%esp),%eax /* load function pointer */
1195 mov 16(%esp),%ecx /* fourth argument *p */
1197 mov %edx,%esp /* switch to new stack */
1200 mov %ecx,0(%esp) /* pass pointer */
1201 call *%eax /* and call function */
1204 mov (%esp),%edx /* load return address */
1205 mov 4(%esp),%esp /* switch to old stack */
1210 Java_java_lang_VMSecurityManager_currentClassLoader:
1211 mov cacao_initializing,%eax
1213 jz Java_java_lang_VMSecurityManager_cont
1217 Java_java_lang_VMSecurityManager_cont:
1218 lea builtin_asm_getclassloader,%eax
1219 push %eax /*store collector function pointer*/
1220 jmp getClassContext_begin
1221 Java_java_lang_VMSecurityManager_getClassContext:
1222 lea builtin_asm_createclasscontextarray,%eax
1223 push %eax /*store collector function pointer*/
1224 getClassContext_begin: /*start the real work*/
1228 sub $68,%esp /*64 memory location without overwriting return adress and collector function adress*/
1229 mov %esp,%ebx /*end of allocated memory block for classpointers is the adress of the working data block +4 */
1230 push $0 /*%esp+32 was native*/
1231 push %eax /*%esp+24 blkbegin*/
1232 push %eax /*%esp+20 currentpos*/
1233 push %ebx /*%esp+16 blkend*/
1235 call builtin_asm_get_threadrootmethod
1236 push %eax /*%esp+12*/
1237 movl 104(%esp),%eax /*(stack contains: threadRootMethod,blkend,blkpos,blkbegin,was native, data(64kB),collector,ret,env,class,frame stack info of stub, we want the frame stack info of thestub*/
1240 push %edx /*esp+8*/ /*position of return address of native stub*/
1241 call builtin_asm_get_stackframeinfo
1242 /* movl (%eax),%eax*/ /*TEST*/
1243 push 0(%eax) /*esp+4*/ /*address of frame info block*/
1250 call i386_native_stub_debug
1253 push %edx /*esp+0*/ /*return adress out of native stub*/
1254 call codegen_findmethod /*find calling java method, this one is still to be skipped (==SecurityManager.getClassContext (or .currentClassLoader)*/
1258 movl MethodPointer(%eax),%eax
1260 call temporaryGetClassContextHelper
1262 call traverseStackInfo
1267 movl MethodPointer(%eax),%ebx
1268 movl offclassmethodinfo(%ebx),%ecx
1273 mov 8(%esp),%ebx /*pos of return adress */
1274 add FrameSize(%eax),%ebx
1275 add $4,%ebx /*adress of new return adress (out of Securitymanager.*/
1279 /* by now we have skipped this method call*/
1281 getClassContext_next:
1284 movl %eax,(%esp) /*return adress*/
1286 call codegen_findmethod
1290 add FrameSize(%eax),%ebx
1292 mov %ebx,8(%esp) /*store adress of next return adress*/
1293 getClassContext_nextRetStored:
1295 mov MethodPointer(%eax),%ecx /*get struct methodinfo*/
1298 je getClassContext_nativeCall
1299 /*save class pointer*/
1301 getClassContext_saveClassPointer:
1302 movl 20(%esp),%ebx /*get temporary memory adress in stack*/
1303 movl offclassmethodinfo(%ecx),%edx /* get class pointer of method*/
1304 movl %edx,(%ebx) /*save */
1305 sub $4,%ebx /*calculate next position */
1306 movl %ebx,20(%esp) /* check if the new adress would overwrite our working data */
1308 je getClassContext_incStack
1309 getClassContext_checkLeave:
1311 cmp 12(%esp),%ecx /*check if we reached the toplevel method of our thread*/
1312 je getClassContext_leave /*yes ->leave*/
1316 call temporaryGetClassContextHelper
1320 jmp getClassContext_next /*continue*/
1323 getClassContext_nativeCall:
1325 movl 4(%esp),%eax /*get top most element on stackframe help information stack*/
1327 jz getClassContext_leave
1336 je getClassContext_checkLeave
1337 jmp getClassContext_saveClassPointer
1339 getClassContext_incStack:
1340 /*make another 64 in our temporary storage free and store the workingdata */
1342 subl $40,%esp /*should be 32*/
1354 jmp getClassContext_checkLeave /* continue */
1356 getClassContext_leave:
1359 call temporaryGetClassContextHelper*/
1361 /*call collector function with begin/end of temporary classarray*/
1370 /* free stack memory of this function*/
1376 asm_throw_and_handle_exception:
1377 sub $20,%esp /*build stack frame*/
1378 mov %ecx,16(%esp) /*save eip of problem */
1380 movl $0,12(%esp) /*internal function -> no function description */
1381 call builtin_asm_get_stackframeinfo
1389 /* mov string_java_lang_NullPointerException,%eax
1399 jmp asm_handle_exception
1400 ret /*should never be reached */
1402 asm_throw_and_handle_hardware_arithmetic_exception:
1403 sub $24,%esp /*build stack frame*/
1404 mov %ecx,20(%esp) /*save eip of problem */
1406 movl $0,16(%esp) /*internal function -> no function description */
1407 call builtin_asm_get_stackframeinfo
1415 mov string_java_lang_ArithmeticException,%eax
1417 mov string_java_lang_ArithmeticException_message,%eax
1420 call new_exception_message
1429 jmp asm_handle_exception
1430 ret /*should never be reached */
1433 /*optimize a littlebit */
1437 call i386_native_stub_debug
1441 mov offclassinit(%eax),%ecx /* get initialized flag */
1443 jnz L_builtin_new_noinit
1445 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1450 call builtin_asm_get_stackframeinfo
1467 jmp L_builtin_new_patch
1470 L_builtin_new_noinit:
1475 /*jmp L_builtin_new_patch*/
1477 L_builtin_new_patch:
1478 /*add patching code here */
1479 lea builtin_new,%edx
1481 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1489 push %ebp /*(%ebp-4)*/
1492 push %edi /*(%ebp-8)*/
1493 push %esi /*(%ebp-12)*/
1494 push %ebx /*(%ebp-16)*/
1495 call builtin_asm_get_stackframeinfo
1497 pushl 0(%eax) /*(%ebp-20)*/
1499 call builtin_asm_get_threadrootmethod
1500 pushl %eax /*(%ebp-24)*/
1503 asm_get_stackTraceLoop:
1504 call codegen_findmethod
1507 pushl $1 /*no indent*/
1512 get_stackTrace_line:
1513 movl LineNumberTableSize(%esi),%ecx
1514 test %ecx,%ecx /* skip if empty line table */
1515 je get_stackTrace_noLineInfo
1517 movl LineNumberTableStart(%esi),%ebx
1519 get_stackTrace_lineLoop:
1520 cmp %edx,LinePC(%ebx)
1521 jg get_stackTrace_nextLineInfo
1523 pushl LineLine(%ebx)
1524 jmp get_stackTrace_cont
1526 get_stackTrace_nextLineInfo:
1527 lea LineEntrySize(%ebx),%ebx
1531 jne get_stackTrace_lineLoop
1533 get_stackTrace_noLineInfo:
1537 get_stackTrace_cont:
1539 pushl MethodPointer(%esi)
1540 pushl $0 /*8(%ebp)*/ /*exception ptr*/
1541 call builtin_trace_exception
1544 movl MethodPointer(%esi),%eax
1547 je get_stackTrace_nat
1550 je get_stackTrace_leave
1552 mov FrameSize(%esi),%eax
1556 jmp asm_get_stackTraceLoop
1562 je get_stackTrace_leave
1569 jmp asm_get_stackTraceLoop
1571 get_stackTrace_leave:
1577 call builtin_stacktrace_copy
1587 asm_getclassvalues_atomic:
1589 mov 4(%esp),%ecx /* super */
1590 mov 8(%esp),%edx /* sub */
1592 mov offbaseval(%ecx),%eax
1593 mov offdiffval(%ecx),%ecx
1594 mov offbaseval(%edx),%edx
1597 mov 16(%esp),%ebx /* out */
1598 mov %eax,offcast_super_baseval(%ebx)
1599 mov %ecx,offcast_super_diffval(%ebx)
1600 mov %edx,offcast_sub_baseval(%ebx)
1606 asm_criticalsections:
1607 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1610 .long _crit_restart1
1613 .long _crit_restart2
1618 * These are local overrides for various environment variables in Emacs.
1619 * Please do not remove this and leave it at the end of the file, where
1620 * Emacs will automagically detect them.
1621 * ---------------------------------------------------------------------
1624 * indent-tabs-mode: t