1 /* 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 951 2004-03-11 17:30:03Z jowenn $
39 /* data segment offsets */
41 #define MethodPointer -4
47 #define LineNumberTableSize -28
48 #define ExTableSize -32
49 #define ExTableStart -32
51 #define ExEntrySize -16
54 #define ExHandlerPC -12
55 #define ExCatchType -16
61 /********************* exported functions and variables ***********************/
63 .globl has_no_x_instr_set
64 .globl asm_calljavafunction
65 .globl asm_calljavafunction2
66 .globl asm_calljavafunction2long
67 .globl asm_calljavafunction2double
69 .globl asm_call_jit_compiler
70 .globl asm_dumpregistersandcall
71 .globl asm_handle_builtin_exception
72 .globl asm_handle_nat_exception
73 .globl asm_handle_exception
74 .globl asm_check_clinit
75 .globl asm_builtin_checkcast
76 .globl asm_builtin_checkarraycast
77 .globl asm_builtin_newarray
78 .globl asm_builtin_anewarray
79 .globl asm_builtin_newarray_array
80 .globl asm_builtin_aastore
81 .globl asm_builtin_monitorenter
82 .globl asm_builtin_monitorexit
83 .globl asm_builtin_ldiv
84 .globl asm_builtin_lrem
85 .globl asm_builtin_f2i
86 .globl asm_builtin_f2l
87 .globl asm_builtin_d2i
88 .globl asm_builtin_d2l
89 .globl asm_builtin_arrayinstanceof
90 .globl asm_perform_threadswitch
91 .globl asm_initialize_thread_stack
92 .globl asm_switchstackandcall
93 .globl asm_getcallingmethod
94 .globl Java_java_lang_VMSecurityManager_getClassContext
95 .globl Java_java_lang_VMSecurityManager_currentClassLoader
96 .globl asm_builtin_new
97 /*************************** imported functions *******************************/
100 .globl builtin_monitorexit
101 .globl builtin_throw_exception
102 .globl builtin_trace_exception
103 .globl class_java_lang_Object
105 .globl builtin_asm_createclasscontextarray
106 .globl builtin_asm_getclassloader
107 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
113 /*********************** function has_no_x_instr_set ***************************
115 * determines if the byte support instruction set (21164a and higher) *
118 * Use it on i386 architecture to init the fpu. *
120 *******************************************************************************/
123 finit /* intitialize the fpu */
125 pushl $0x027f /* Round to nearest, 53-bit mode, exceptions masked */
129 xor %eax,%eax /* result code 0 (not used for i386) */
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 size */
157 .long 0 /* fltsave */
158 .long 0 /* intsave */
161 .long 32 /* frame size */
162 .long 0 /* method pointer (pointer to name) */
164 asm_calljavafunction:
165 push %ebp /* allocate stack space */
168 push %ebx /* save registers */
172 sub $32,%esp /* pass the remaining parameters */
175 mov %edx,28(%esp) /* convert parms to 8 byte */
191 mov 8(%ebp),%eax /* move function pointer to %eax */
193 lea asm_call_jit_compiler,%edx
194 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 */
218 /********************* function asm_calljavafunction ***************************
220 * This function calls a Java-method (which possibly needs compilation) *
221 * with up to 4 address parameters. *
223 * This functions calls the JIT-compiler which eventually translates the *
224 * method into machine code. *
227 * javaobject_header *asm_calljavamethod (methodinfo *m, *
228 * void *arg1, void *arg2, void *arg3, void *arg4); *
230 *******************************************************************************/
233 .ascii "calljavafunction2\0\0"
236 .long 0 /* catch type all */
237 .long calljava_xhandler2 /* handler pc */
238 .long calljava_xhandler2 /* end pc */
239 .long asm_calljavafunction2 /* start pc */
240 .long 1 /* extable size */
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:
252 push %ebp /* save ebp */
254 mov %esp,%eax /* save stackptr */
257 push %ebx /* save registers */
263 mov sizejniblock*3+offjniitem+4(%ebp),%ebx
265 mov sizejniblock*3+offjniitem(%ebp),%ebx
268 mov sizejniblock*2+offjniitem+4(%ebp),%ebx
270 mov sizejniblock*2+offjniitem(%ebp),%ebx
274 mov sizejniblock+offjniitem+4(%ebp),%ebx
276 mov sizejniblock+offjniitem(%ebp),%ebx
279 mov offjniitem+4(%ebp),%ebx
281 mov offjniitem(%ebp),%ebx
285 mov 8(%ebp),%eax /* move function pointer to %eax */
287 lea asm_call_jit_compiler,%edx
288 call *%edx /* call JIT compiler */
292 pop %edi /* restore registers */
299 push %eax /* pass exception pointer */
300 call builtin_throw_exception
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 *******************************************************************************/
339 asm_call_jit_compiler:
340 push %ebx /* save register */
343 mov 8(%esp),%ebp /* get return address (2 push) */
344 mov -1(%ebp),%bl /* get function code */
345 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
346 jne L_not_static_special
348 sub $6,%ebp /* calculate address of immediate */
349 jmp L_call_jit_compile
351 L_not_static_special:
352 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
353 jne L_not_virtual_interface
355 sub $6,%ebp /* calculate address of offset */
356 mov (%ebp),%ebp /* get offset */
357 add %ecx,%ebp /* add base address to get method address */
358 jmp L_call_jit_compile
360 L_not_virtual_interface: /* a call from asm_calljavafunction */
364 push %ebp /* save address for method pointer */
366 push %eax /* push methodpointer on stack */
370 pop %ebp /* restore address for method pointer */
371 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
374 mov %eax,(%ebp) /* and now save the new pointer */
377 pop %ebp /* restore registers */
380 jmp *%eax /* ...and now call the new method */
384 /****************** function asm_dumpregistersandcall **************************
386 * This funtion saves all callee saved registers and calls the function *
387 * which is passed as parameter. *
389 * This function is needed by the garbage collector, which needs to access *
390 * all registers which are stored on the stack. Unused registers are *
391 * cleared to avoid interferances with the GC. *
393 * void asm_dumpregistersandcall (functionptr f); *
395 *******************************************************************************/
397 asm_dumpregistersandcall:
408 mov 4(%ebp),%eax /* load function pointer */
409 call *%eax /* call function */
421 /********************* function asm_handle_exception ***************************
423 * This function handles an exception. It does not use the usual calling *
424 * conventions. The exception pointer is passed in REG_ITMP1 and the *
425 * pc from the exception raising position is passed in REG_ITMP2. It searches *
426 * the local exception table for a handler. If no one is found, it unwinds *
427 * stacks and continues searching the callers. *
429 * void asm_handle_exception (exceptionptr, exceptionpc); *
431 *******************************************************************************/
433 asm_handle_builtin_exception:
434 add $4,%esp /* clear return address of this call */
435 mov (%esp),%eax /* get exceptionptr */
436 leave /* leave builtin function */
437 mov (%esp),%edx /* get exceptionpc */
438 sub $2,%edx /* size of builtin call */
439 jmp asm_handle_exception
441 asm_handle_nat_exception:
442 add $4,%esp /* clear return address of native stub */
444 asm_handle_exception:
448 push %eax /* save exception pointer */
449 push %ecx /* save exception pc */
451 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
455 call findmethod /* get the data segment ptr */
459 mov -8(%ebp),%ecx /* could be changed in findmethod */
461 push %edx /* save data segment pointer */
468 mov %eax,(%esp) /* exception pointer */
469 mov MethodPointer(%edx),%eax /* method pointer */
471 mov %ecx,8(%esp) /* exception pc */
472 movl $1,12(%esp) /* set no unwind flag */
473 call builtin_trace_exception
476 mov -12(%ebp),%esi /* %esi = data segment pointer */
477 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
478 test %ecx,%ecx /* if empty table skip */
481 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
482 mov -4(%ebp),%eax /* get xptr */
485 mov -8(%ebp),%edx /* get xpc */
487 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
488 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
489 jg ex_table_cont /* if (false) continue */
490 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
491 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
492 jge ex_table_cont /* if (false) continue */
493 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
494 test %ebx,%ebx /* NULL catches everything */
497 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
498 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
499 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
500 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
501 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
502 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
503 cmp %ebx,%esi /* xptr is instanceof catchtype */
507 mov ExHandlerPC(%edi),%edx
509 pop %edi /* restore registers */
512 add $8,%esp /* suck %ecx, %edx */
513 pop %eax /* restore xptr */
515 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
520 jmp *%edx /* jump to exception handler */
523 lea ExEntrySize(%edi),%edi
532 pop %edx /* restore data segment pointer */
537 push %eax /* save exception pointer */
540 mov IsSync(%edx),%eax /* %eax = SyncOffset */
541 test %eax,%eax /* if zero no monitorexit */
545 mov -4(%eax),%eax /* we have the xptr on the stack */
546 push %edx /* save regs */
548 call builtin_monitorexit
550 pop %edx /* restore regs */
554 add FrameSize(%edx),%eax /* %eax = frame size */
555 add $4,%eax /* we have the xptr on the stack */
557 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
579 shl $3,%ecx /* multiply by 8 bytes */
583 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
610 pop %eax /* restore exception pointer */
612 mov FrameSize(%edx),%ecx /* %ecx = frame size */
613 add %ecx,%esp /* unwind stack */
615 pop %ecx /* the new xpc is return address */
618 jmp asm_handle_exception
621 /********************* function asm_check_clinit *******************************
623 * Does null check and calls monitorenter or throws an exception *
625 *******************************************************************************/
628 mov offclassinit(%eax),%ecx /* get initialized flag */
632 push %eax /* pass classinfo pointer */
633 call class_init /* call class_init function */
637 mov (%esp),%eax /* get return address */
638 sub $12,%eax /* asm_putstatic call code size */
639 movb $0xeb,(%eax) /* jmp rel8 */
640 movl $10,1(%eax) /* 32-bit offset */
644 /********************* function asm_builtin_monitorenter ***********************
646 * Does null check and calls monitorenter or throws an exception *
648 *******************************************************************************/
650 asm_builtin_monitorenter:
652 je nb_monitorenter /* if (null) throw exception */
653 jmp builtin_monitorenter /* else call builtin_monitorenter */
656 popl %ecx /* delete return address */
657 subl $2,%ecx /* faulting address is return adress - 2 */
658 movl proto_java_lang_NullPointerException,%eax
659 jmp asm_handle_exception
662 /********************* function asm_builtin_monitorexit ************************
664 * Does null check and calls monitorexit or throws an exception *
666 *******************************************************************************/
668 asm_builtin_monitorexit:
671 je nb_monitorexit /* if (null) throw exception */
672 push %ecx /* save registers which could be used */
675 call builtin_monitorexit /* else call builtin_monitorenter */
677 pop %edx /* restore registers which could be used */
682 popl %ecx /* delete return address */
683 subl $2,%ecx /* faulting address is return adress - 2 */
684 movl proto_java_lang_NullPointerException,%eax
685 jmp asm_handle_exception
688 /************************ function asm_builtin_ldiv ****************************
690 * Does null check and calls ldiv or throws an exception *
692 *******************************************************************************/
697 test %eax,%eax /* if (null) throw exception */
703 pop %ecx /* delete return address */
704 sub $2,%ecx /* faulting address is return adress - 2 */
705 mov proto_java_lang_ArithmeticException,%eax
706 jmp asm_handle_exception
709 /************************ function asm_builtin_lrem ****************************
711 * Does null check and calls lrem or throws an exception *
713 *******************************************************************************/
718 test %eax,%eax /* if (null) throw exception */
724 pop %ecx /* delete return address */
725 sub $2,%ecx /* faulting address is return adress - 2 */
726 mov proto_java_lang_ArithmeticException,%eax
727 jmp asm_handle_exception
730 /************************ function asm_builtin_x2x *****************************
732 * Wrapper functions for corner cases *
734 *******************************************************************************/
765 /*********************** function new_builtin_checkcast ************************
767 * Does the cast check and eventually throws an exception *
769 *******************************************************************************/
771 asm_builtin_checkcast:
777 /******************* function asm_builtin_checkarraycast ***********************
779 * Does the cast check and eventually throws an exception *
781 *******************************************************************************/
783 asm_builtin_checkarraycast:
784 sub $8,%esp /* build stack frame (2 * 4 bytes) */
786 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
787 mov %eax,(%esp) /* save object pointer */
792 call builtin_checkarraycast /* builtin_checkarraycast */
794 test %eax,%eax /* if (false) throw exception */
797 mov 12(%esp),%eax /* return object pointer */
804 pop %ecx /* delete return address */
805 sub $2,%ecx /* faulting address is return adress - 2 */
806 mov proto_java_lang_ClassCastException,%eax
807 jmp asm_handle_exception
810 /******************* function asm_builtin_newarray *****************************
812 * Does the cast check and eventually throws an exception *
814 *******************************************************************************/
816 asm_builtin_newarray:
817 sub $8,%esp /* build stack frame (2 * 4 bytes) */
825 call builtin_newarray
831 /******************* function asm_builtin_aastore ******************************
833 * Does the cast check and eventually throws an exception *
835 *******************************************************************************/
838 subl $12,%esp /* build stack frame (3 * 4 bytes) */
840 movl 16(%esp),%eax /* 12 (frame) + 4 (return) */
841 test %eax,%eax /* if null pointer throw exception */
844 movl offarraysize(%eax),%edx /* load size */
845 movl 24(%esp),%ecx /* index */
846 cmpl %edx,%ecx /* do bound check */
847 ja nb_aastore_bound /* if out of bounds throw exception */
849 shll $2,%ecx /* index * 4 */
850 addl %eax,%ecx /* add index * 4 to arrayref */
852 movl %ecx,8(%esp) /* save store position */
854 movl 16(%esp),%eax /* 12 (frame) + 4 (return) */
857 movl 32(%esp),%eax /* object is second argument */
860 call builtin_canstore /* builtin_canstore(arrayref,object) */
862 test %eax,%eax /* if (false) throw exception */
867 movl %eax,offobjarrdata(%ecx)/* store objectptr in array */
874 popl %ecx /* delete return address */
875 subl $2,%ecx /* faulting address is return adress - 2 */
876 movl proto_java_lang_NullPointerException,%eax
877 jmp asm_handle_exception
881 popl %ecx /* delete return address */
882 subl $2,%ecx /* faulting address is return adress - 2 */
883 movl proto_java_lang_ArrayIndexOutOfBoundsException,%eax
884 jmp asm_handle_exception
888 popl %ecx /* delete return address */
889 subl $2,%ecx /* faulting address is return adress - 2 */
890 movl proto_java_lang_ArrayStoreException,%eax
891 jmp asm_handle_exception
894 /******************* function asm_builtin_arrayinstanceof **********************
896 * Does the instanceof check of arrays *
898 *******************************************************************************/
900 asm_builtin_arrayinstanceof:
901 subl $8,%esp /* build stack frame (2 * 4 bytes) */
909 call builtin_arrayinstanceof
915 /******************* function asm_initialize_thread_stack **********************
917 * initialized a thread stack *
918 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
920 *******************************************************************************/
922 asm_initialize_thread_stack:
923 movl 8(%esp),%eax /* (to)->stackEnd */
924 subl $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
936 movl 4(%esp),%edx /* save (u1*) (func) */
939 ret /* return restorepoint in %eax */
942 /******************* function asm_perform_threadswitch *************************
944 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
946 * performs a threadswitch *
948 *******************************************************************************/
950 asm_perform_threadswitch:
962 movl 36(%esp),%eax /* save current return address */
965 movl 40(%esp),%eax /* first argument **from */
968 movl 48(%esp),%eax /* third argument **stackTop */
971 movl 44(%esp),%eax /* second argument **to */
972 movl 0(%eax),%esp /* load new stack pointer */
978 /* skip stack pointer */
983 addl $32,%esp /* leave return address on stack */
987 /********************* function asm_switchstackandcall *************************
989 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
992 * Switches to a new stack, calls a function and switches back. *
993 * a0 new stack pointer *
994 * a1 function pointer *
995 * a2 pointer to variable where stack top should be stored *
996 * a3 pointer to user data, is passed to the function *
998 *******************************************************************************/
1000 asm_switchstackandcall:
1001 movl 4(%esp),%edx /* first argument *stack */
1002 subl $8,%edx /* allocate new stack */
1004 movl (%esp),%eax /* save return address on new stack */
1007 movl %esp,4(%edx) /* save old stack pointer on new stack*/
1009 movl 12(%esp),%eax /* third argument **stacktopsave */
1010 movl %esp,(%eax) /* save old stack pointer to variable */
1012 movl 8(%esp),%eax /* load function pointer */
1013 movl 16(%esp),%ecx /* fourth argument *p */
1015 movl %edx,%esp /* switch to new stack */
1018 movl %ecx,0(%esp) /* pass pointer */
1019 call *%eax /* and call function */
1022 movl (%esp),%edx /* load return address */
1023 movl 4(%esp),%esp /* switch to old stack */
1028 /********************* function asm_getcallingmethod ***************************
1030 * classinfo *asm_getcallingmethod (); *
1032 * goes back stack frames to get the calling method *
1038 *******************************************************************************/
1040 asm_getcallingmethod:
1042 /* movl $0,(%eax) */
1045 Java_java_lang_VMSecurityManager_currentClassLoader:
1046 lea builtin_asm_getclassloader,%eax
1047 push %eax /*store collector function pointer*/
1048 jmp getClassContext_begin
1049 Java_java_lang_VMSecurityManager_getClassContext:
1050 lea builtin_asm_createclasscontextarray,%eax
1051 push %eax /*store collector function pointer*/
1052 getClassContext_begin: /*start the real work*/
1056 sub $68,%esp /*64 memory location without overwriting return adress and collector function adress*/
1057 mov %esp,%ebx /*end of allocated memory block for classpointers is the adress of the working data block +4 */
1058 push $0 /*%esp+32 was native*/
1059 push %eax /*%esp+24 blkbegin*/
1060 push %eax /*%esp+20 currentpos*/
1061 push %ebx /*%esp+16 blkend*/
1063 call builtin_asm_get_threadrootmethod
1064 push %eax /*%esp+12*/
1065 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*/
1068 push %edx /*esp+8*/ /*position of return address of native stub*/
1069 call builtin_asm_get_stackframeinfo
1070 movl (%eax),%eax /*comment ??*/
1071 push 0(%eax) /*esp+4*/ /*address of frame info block*/
1078 call i386_native_stub_debug
1081 push %edx /*esp+0*/ /*return adress out of native stub*/
1082 call findmethod /*find calling java method, this one is still to be skipped (==SecurityManager.getClassContext (or .currentClassLoader)*/
1086 movl MethodPointer(%eax),%eax
1088 call temporaryGetClassContextHelper
1090 call traverseStackInfo
1095 movl MethodPointer(%eax),%ebx
1096 movl offclassmethodinfo(%ebx),%ecx
1101 mov 8(%esp),%ebx /*pos of return adress */
1102 add FrameSize(%eax),%ebx
1103 add $4,%ebx /*adress of new return adress (out of Securitymanager.*/
1107 /* by now we have skipped this method call*/
1109 getClassContext_next:
1112 movl %eax,(%esp) /*return adress*/
1118 add FrameSize(%eax),%ebx
1120 mov %ebx,8(%esp) /*store adress of next return adress*/
1121 getClassContext_nextRetStored:
1123 mov MethodPointer(%eax),%ecx /*get struct methodinfo*/
1126 je getClassContext_nativeCall
1127 /*save class pointer*/
1129 getClassContext_saveClassPointer:
1130 movl 20(%esp),%ebx /*get temporary memory adress in stack*/
1131 movl offclassmethodinfo(%ecx),%edx /* get class pointer of method*/
1132 movl %edx,(%ebx) /*save */
1133 sub $4,%ebx /*calculate next position */
1134 movl %ebx,20(%esp) /* check if the new adress would overwrite our working data */
1136 je getClassContext_incStack
1137 getClassContext_checkLeave:
1139 cmp 12(%esp),%ecx /*check if we reached the toplevel method of our thread*/
1140 je getClassContext_leave /*yes ->leave*/
1144 call temporaryGetClassContextHelper
1148 jmp getClassContext_next /*continue*/
1151 getClassContext_nativeCall:
1153 movl 4(%esp),%eax /*get top most element on stackframe help information stack*/
1162 je getClassContext_checkLeave
1163 jmp getClassContext_saveClassPointer
1165 getClassContext_incStack:
1166 /*make another 64 in our temporary storage free and store the workingdata */
1168 subl $40,%esp /*should be 32*/
1180 jmp getClassContext_checkLeave /* continue */
1182 getClassContext_leave:
1185 call temporaryGetClassContextHelper*/
1187 /*call collector function with begin/end of temporary classarray*/
1196 /* free stack memory of this function*/
1203 /*optimize a littlebit */
1207 call i386_native_stub_debug
1210 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1215 call builtin_asm_get_stackframeinfo
1235 * These are local overrides for various environment variables in Emacs.
1236 * Please do not remove this and leave it at the end of the file, where
1237 * Emacs will automagically detect them.
1238 * ---------------------------------------------------------------------
1241 * indent-tabs-mode: t