should have been , now it works in the cvs version too
[cacao.git] / src / vm / jit / i386 / asmpart.S
1 /* jit/i386/asmpart.S - Java-C interface functions for i386
2
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,
7    J. Wenninger
8
9    This file is part of CACAO.
10
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.
15
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.
20
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
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Andreas Krall
29             Reinhard Grafl
30             Christian Thalinger
31
32    $Id: asmpart.S 1111 2004-05-29 07:51:40Z jowenn $
33
34 */
35
36
37 #include "config.h"
38 #include "offsets.h"
39
40 /* data segment offsets */
41
42 #define MethodPointer           -4
43 #define FrameSize               -8
44 #define IsSync                  -12
45 #define IsLeaf                  -16
46 #define IntSave                 -20
47 #define FltSave                 -24
48 #define LineNumberTableSize     -28
49 #define LineNumberTableStart    -32
50 #define ExTableSize             -36
51 #define ExTableStart            -36
52
53 #define ExEntrySize     -16
54 #define ExStartPC       -4
55 #define ExEndPC         -8
56 #define ExHandlerPC     -12
57 #define ExCatchType     -16
58
59
60 #define LineEntrySize   -8
61 #define LinePC          0
62 #define LineLine        -4
63
64
65 #define itmp1    %eax
66 #define itmp2    %ecx
67 #define itmp3    %edx
68
69                 
70         .text
71
72
73 /********************* exported functions and variables ***********************/
74
75         .globl asm_calljavafunction
76         .globl asm_calljavafunction2
77         .globl asm_calljavafunction2long
78         .globl asm_calljavafunction2double
79
80         .globl asm_call_jit_compiler
81         .globl asm_handle_builtin_exception
82         .globl asm_handle_nat_exception
83         .globl asm_handle_exception
84         .globl asm_check_clinit
85         .globl asm_builtin_checkcast    
86         .globl asm_builtin_checkarraycast
87         .globl asm_builtin_newarray
88         .globl asm_builtin_anewarray
89         .globl asm_builtin_newarray_array
90         .globl asm_builtin_aastore
91         .globl asm_builtin_monitorenter
92         .globl asm_builtin_monitorexit
93         .globl asm_builtin_ldiv
94         .globl asm_builtin_lrem
95     .globl asm_builtin_f2i
96     .globl asm_builtin_f2l
97     .globl asm_builtin_d2i
98     .globl asm_builtin_d2l
99         .globl asm_builtin_arrayinstanceof
100         .globl asm_perform_threadswitch
101         .globl asm_initialize_thread_stack
102         .globl asm_switchstackandcall
103         .globl asm_getcallingmethod
104         .globl Java_java_lang_VMSecurityManager_getClassContext
105         .globl Java_java_lang_VMSecurityManager_currentClassLoader    
106         .globl asm_builtin_new
107         .globl asm_get_stackTrace
108         .globl asm_criticalsections
109         .globl asm_getclassvalues_atomic
110
111 /*************************** imported functions *******************************/
112
113         .globl jit_compile
114         .globl builtin_monitorexit
115         .globl builtin_throw_exception
116         .globl builtin_trace_exception
117         .globl class_java_lang_Object
118         .globl codegen_findmethod
119         .globl builtin_asm_createclasscontextarray
120         .globl builtin_asm_getclassloader
121         .globl callgetexceptionptrptr
122         .globl asm_throw_and_handle_hardware_nullpointer_exception
123         .globl asm_throw_and_handle_hardware_arithmetic_exception
124
125
126 /********************* function asm_calljavafunction ***************************
127 *                                                                              *
128 *   This function calls a Java-method (which possibly needs compilation)       *
129 *   with up to 4 address parameters.                                           *
130 *                                                                              *
131 *   This functions calls the JIT-compiler which eventually translates the      *
132 *   method into machine code.                                                  *
133 *                                                                              *
134 *   C-prototype:                                                               *
135 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
136 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
137 *                                                                              *
138 *******************************************************************************/
139
140 call_name:
141         .ascii  "calljavafunction\0\0"
142
143         .align  8
144         .long   0                         /* catch type all                       */
145         .long   calljava_xhandler         /* handler pc                           */
146         .long   calljava_xhandler         /* end pc                               */
147         .long   asm_calljavafunction      /* start pc                             */
148         .long   1                         /* extable size                         */
149         .long   0                         /* line number table  start             */
150         .long   0                         /* line number table  size              */
151         .long   0                         /* fltsave                              */
152         .long   0                         /* intsave                              */
153         .long   0                         /* isleaf                               */
154         .long   0                         /* IsSync                               */
155         .long   32                        /* frame size                           */
156         .long   0                         /* method pointer (pointer to name)     */
157
158 asm_calljavafunction:
159                 push    %ebp                  /* allocate stack space                 */
160                 mov             %esp, %ebp
161
162         push    %ebx                  /* save registers                       */
163         push    %esi
164         push    %edi
165         
166                 sub             $32,%esp              /* pass the remaining parameters        */
167                 xor             %edx,%edx
168
169                 mov             %edx,28(%esp)         /* convert parms to 8 byte              */
170                 mov             24(%ebp),%eax
171                 mov             %eax,24(%esp)
172                 
173                 mov             %edx,20(%esp)
174                 mov             20(%ebp),%eax
175                 mov             %eax,16(%esp)
176
177                 mov             %edx,12(%esp)
178                 mov             16(%ebp),%eax
179                 mov             %eax,8(%esp)
180
181                 mov             %edx,4(%esp)
182                 mov             12(%ebp),%eax
183                 mov             %eax,(%esp)
184
185                 mov             8(%ebp),%eax          /* move function pointer to %eax        */
186
187                 lea             asm_call_jit_compiler,%edx 
188                 call    *%edx                 /* call JIT compiler                    */
189         
190 calljava_return:
191         add     $32,%esp
192         pop     %edi                 /* restore registers                     */
193         pop     %esi
194         pop     %ebx
195                 leave
196                 ret
197
198 calljava_xhandler:
199                 push    %eax                              /* pass exception pointer               */
200                 call    builtin_throw_exception
201                 add     $4,%esp
202
203                 add     $32,%esp
204         pop     %edi                 /* restore registers                     */
205         pop     %esi
206         pop     %ebx
207         leave
208                 ret
209
210
211 /********************* function asm_calljavafunction ***************************
212 *                                                                              *
213 *   This function calls a Java-method (which possibly needs compilation)       *
214 *   with up to 4 address parameters.                                           *
215 *                                                                              *
216 *   This functions calls the JIT-compiler which eventually translates the      *
217 *   method into machine code.                                                  *
218 *                                                                              *
219 *   C-prototype:                                                               *
220 *    javaobject_header *asm_calljavafunction2(methodinfo *m,                   *
221 *         u4 count, u4 size, void *callblock);                                 *
222 *                                                                              *
223 *******************************************************************************/
224
225 call_name2:
226         .ascii  "calljavafunction2\0\0"
227
228         .align  8
229         .long   0                         /* catch type all                       */
230         .long   calljava_xhandler2        /* handler pc                           */
231         .long   calljava_xhandler2        /* end pc                               */
232         .long   asm_calljavafunction2     /* start pc                             */
233         .long   1                         /* extable size                         */
234         .long   0                         /* line number table start              */
235         .long   0                         /* line number table size               */
236         .long   0                         /* fltsave                              */
237         .long   0                         /* intsave                              */
238         .long   0                         /* isleaf                               */
239         .long   0                         /* IsSync                               */
240         .long   32                        /* frame size                           */
241         .long   0                         /* method pointer (pointer to name)     */
242
243 asm_calljavafunction2:
244 asm_calljavafunction2double:
245 asm_calljavafunction2long:
246         push    %ebp
247         mov     %esp,%ebp                 /* save stackptr                        */
248
249         push    %ebx                      /* save registers                       */
250         push    %esi
251         push    %edi
252
253         mov     20(%ebp),%eax             /* pointer to arg block                 */
254         mov     12(%ebp),%ecx             /* arg count                            */
255         test    %ecx,%ecx                 /* maybe we have no args                */
256         jle     calljava_copydone
257
258         mov     %ecx,%edx                 /* calculate stack size                 */
259         shl     $3,%edx
260         mov     %edx,%esi                 /* save in callee saved register        */
261         sub     %esi,%esp                 /* stack frame for arguments            */
262         mov     %esp,%edi
263
264 calljava_copyloop:
265     mov     offjniitem(%eax),%edx
266     mov     %edx,0(%edi)
267     mov     offjniitem+4(%eax),%edx
268     mov     %edx,4(%edi)
269
270         sub     $1,%ecx                   /* are there any args left?             */
271         test    %ecx,%ecx
272         jle     calljava_copydone
273
274         add     $sizejniblock,%eax        /* goto next argument block             */
275     add     $8,%edi                   /* increase sp to next argument         */
276         jmp     calljava_copyloop
277
278 calljava_copydone:
279         mov     8(%ebp),%eax              /* move function pointer to %eax        */
280
281         lea     asm_call_jit_compiler,%edx 
282         call    *%edx                     /* call JIT compiler                    */
283         
284 calljava_return2:
285         add     %esi,%esp                 /* remove arg stack frame               */
286         pop     %edi                      /* restore registers                    */
287         pop     %esi
288         pop     %ebx
289         leave
290         ret
291
292 calljava_xhandler2:
293         push    %eax                      /* pass exception pointer               */
294         call    builtin_throw_exception
295         add     $4,%esp
296     
297         add     %esi,%esp                 /* remove arg stack frame               */
298         pop     %edi                      /* restore registers                    */
299         pop     %esi
300         pop     %ebx
301         leave
302         ret
303
304
305 /****************** function asm_call_jit_compiler *****************************
306 *                                                                              *
307 *   invokes the compiler for untranslated JavaVM methods.                      *
308 *                                                                              *
309 *   Register R0 contains a pointer to the method info structure (prepared      *
310 *   by createcompilerstub). Using the return address in R26 and the            *
311 *   offset in the LDA instruction or using the value in methodptr R28 the      *
312 *   patching address for storing the method address can be computed:           *
313 *                                                                              *
314 *   method address was either loaded using                                     *
315 *                                                                              *
316 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
317 *   i386_call_reg(REG_ITMP2)                                                   *
318 *                                                                              *
319 *   or                                                                         *
320 *                                                                              *
321 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface    *
322 *   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)                *
323 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \                *
324 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
325 *   i386_call_reg(REG_ITMP1)                                                   *
326 *                                                                              *
327 *   in the static case the method pointer can be computed using the            *
328 *   return address and the lda function following the jmp instruction          *
329 *                                                                              *
330 *******************************************************************************/
331
332 asm_call_jit_compiler:
333         push    %ebx                /* save register                              */
334     push    %ebp
335                         
336         mov     8(%esp),%ebp        /* get return address (2 push)                */
337         mov     -1(%ebp),%bl        /* get function code                          */
338         cmp     $0xd1,%bl           /* called with `call *REG_ITMP2' (%ecx)?      */
339         jne             L_not_static_special
340
341         sub     $6,%ebp             /* calculate address of immediate             */
342         jmp             L_call_jit_compile
343                 
344 L_not_static_special:
345         cmp     $0xd0,%bl           /* called with `call *REG_ITMP1' (%eax)       */
346         jne             L_not_virtual_interface
347         
348         sub     $6,%ebp             /* calculate address of offset                */
349         mov     (%ebp),%ebp         /* get offset                                 */
350         add     itmp2,%ebp          /* add base address to get method address     */
351         jmp             L_call_jit_compile
352
353 L_not_virtual_interface:        /* a call from asm_calljavafunction           */
354         xor     %ebp,%ebp
355                 
356 L_call_jit_compile:
357         push    %ebp                /* save address for method pointer            */
358
359         push    %eax                /* push methodpointer on stack                */
360         call    jit_compile
361         add     $4,%esp
362
363         pop     %ebp                /* restore address for method pointer         */
364
365         test    %eax,%eax           /* check for exception                        */
366         je      L_exception
367
368         test    %ebp,%ebp           /* is address == 0 (asm_calljavafunction)     */
369         je              L_call_method
370         
371         mov     %eax,(%ebp)         /* and now save the new pointer               */
372
373 L_call_method:
374         pop     %ebp                /* restore registers                          */
375         pop     %ebx
376                 
377         jmp             *%eax               /* ...and now call the new method             */
378
379 L_exception:
380         pop     %ebp                /* restore registers                          */
381         pop     %ebx
382
383 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
384         call    builtin_asm_get_exceptionptrptr
385         mov     %eax,%ecx
386         mov     (%ecx),%eax         /* get the exception pointer                  */
387         movl    $0,(%ecx)           /* clear the exception pointer                */
388 #else
389         lea     _exceptionptr,%ecx
390         mov     (%ecx),%eax         /* get the exception pointer                  */
391         movl    $0,(%ecx)           /* clear the exception pointer                */
392 #endif
393
394         pop     %ecx                /* delete return address                      */
395         sub     $2,%ecx             /* faulting address is return adress - 2      */
396
397         jmp     asm_handle_exception
398
399
400 /********************* function asm_handle_exception ***************************
401 *                                                                              *
402 *   This function handles an exception. It does not use the usual calling      *
403 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
404 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
405 *   the local exception table for a handler. If no one is found, it unwinds    *
406 *   stacks and continues searching the callers.                                *
407 *                                                                              *
408 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
409 *                                                                              *
410 *******************************************************************************/
411
412 asm_handle_nat_exception:
413                 add     $4,%esp                                         /* clear return address of native stub */
414                 
415 asm_handle_exception:
416 #if 0
417                 push %ebp
418                 mov %esp,%ebp
419                 push %eax       /* exception pointer */
420                 push %ecx       /* excepiton pc */
421
422                 call asm_get_stackTrace
423
424                 pop %ecx
425                 pop %eax
426                 pop %ebp
427 #endif
428 asm_handle_exception_loop:
429                 push    %ebp
430                 mov     %esp,%ebp
431         
432                 push    %eax                                            /* save exception pointer         */
433                 push    %ecx                        /* save exception pc              */
434
435         call    codegen_findmethod          /* get the data segment ptr           */
436                 mov     %eax,%edx
437                         
438                 mov     -4(%ebp),%eax
439                 mov     -8(%ebp),%ecx               /* could be changed in findmethod */
440
441                 push    %edx                                            /* save data segment pointer      */
442                 push    %ebx
443                 push    %esi
444                 push    %edi
445                 
446 ex_stack_loop:
447                 sub     $20,%esp
448                 mov     %eax,(%esp)                                     /* exception pointer              */
449                 mov     MethodPointer(%edx),%eax        /* method pointer                 */
450                 mov     %eax,4(%esp)
451                 mov     %ecx,8(%esp)                            /* exception pc                   */
452                 movl    $0,12(%esp)                 /* line number                    */
453                 movl    $1,16(%esp)                                     /* set no unwind flag             */
454                 call    builtin_trace_exception
455                 add     $20,%esp
456                 mov     -12(%ebp),%esi                          /* %esi = data segment pointer    */
457                 mov     ExTableSize(%esi),%ecx          /* %ecx = exception table size    */
458                 test    %ecx,%ecx                                       /* if empty table skip            */
459                 je      empty_table
460
461                 lea             ExTableStart(%esi),%edi         /* %edi = start of exception table*/
462                 mov     -4(%ebp),%eax               /* get xptr                       */
463                 
464 ex_table_loop:
465                 mov     -8(%ebp),%edx                           /* get xpc                        */
466
467                 mov     ExStartPC(%edi),%ebx            /* %ebx = exception start pc      */
468                 cmp     %edx,%ebx                                       /* %ebx = (startpc <= xpc)        */
469                 jg      ex_table_cont                           /* if (false) continue            */
470                 mov     ExEndPC(%edi),%ebx                      /* %ebx = exception end pc        */
471                 cmp     %ebx,%edx                                       /* %ebx = (xpc < endpc)           */
472                 jge     ex_table_cont                           /* if (false) continue            */
473                 mov     ExCatchType(%edi),%ebx          /* arg1 = exception catch type    */
474                 test    %ebx,%ebx                                       /* NULL catches everything        */
475                 je      ex_handle_it
476
477         cmpl    $0,offclassloaded(%ebx)     /* check if class is loaded           */
478         jne     L_class_loaded
479
480         sub     $3*4,%esp
481         mov     %eax,1*4(%esp)              /* save not callee saved regs         */
482         mov     %ecx,2*4(%esp)
483
484         mov     %ebx,0*4(%esp)              /* exception class is argument        */
485         call    class_load
486
487         mov     1*4(%esp),%eax
488         mov     2*4(%esp),%ecx
489         add     $3*4,%esp
490
491 L_class_loaded:
492         cmpl    $0,offclasslinked(%ebx)
493         jne     L_class_linked
494
495         sub     $3*4,%esp
496         mov     %eax,1*4(%esp)              /* save not callee saved regs         */
497         mov     %ecx,2*4(%esp)
498
499         mov     %ebx,0*4(%esp)              /* exception class is argument        */
500         call    class_link
501
502         mov     1*4(%esp),%eax
503         mov     2*4(%esp),%ecx
504         add     $3*4,%esp
505
506 L_class_linked:
507 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
508                 push    %ebx
509
510 _crit_restart1:
511                 mov     0(%esp),%ebx
512 #endif
513                 
514 _crit_begin1:
515                 mov     offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr)          */
516                 mov     offclassvftbl(%ebx),%ebx    /* %ebx = vftblptr(catchtype) class (not obj) */
517                 mov     offbaseval(%esi),%esi           /* %esi = baseval(xptr)           */
518                 mov     offbaseval(%ebx),%edx           /* %edx = baseval(catchtype)      */
519                 mov     offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype)      */
520 _crit_end1:
521                 sub     %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
522
523 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
524                 add     $4,%esp
525 #endif
526         
527                 cmp     %ebx,%esi                                       /* xptr is instanceof catchtype   */
528                 ja      ex_table_cont
529                 
530 ex_handle_it:
531                 mov     ExHandlerPC(%edi),%edx
532                 
533                 pop     %edi                        /* restore registers              */
534                 pop     %esi
535                 pop     %ebx
536         add     $8,%esp                     /* suck %ecx, %edx                */
537         pop     %eax                        /* restore xptr                   */
538
539                 leave
540                 jmp             *%edx                       /* jump to exception handler      */
541
542 ex_table_cont:
543                 lea     ExEntrySize(%edi),%edi
544                 dec     %ecx
545                 test    %ecx,%ecx
546                 jg      ex_table_loop
547                 
548 empty_table:
549         pop     %edi
550         pop     %esi
551         pop     %ebx
552         pop     %edx                        /* restore data segment pointer   */
553         pop     %ecx
554         pop     %eax
555         pop     %ebp
556
557         push    %eax                        /* save exception pointer         */
558         
559 ex_already_cleared:
560                 mov     IsSync(%edx),%eax                       /* %eax = SyncOffset              */
561                 test    %eax,%eax                                       /* if zero no monitorexit         */
562                 je      no_monitor_exit
563
564         add     %esp,%eax
565         mov     -4(%eax),%eax               /* we have the xptr on the stack  */
566         push    %edx                        /* save regs                      */
567         push    %eax
568                 call    builtin_monitorexit
569                 add     $4,%esp
570         pop     %edx                        /* restore regs                   */
571         
572 no_monitor_exit:
573         mov     %esp,%eax
574         add     FrameSize(%edx),%eax        /* %eax = frame size              */
575         add     $4,%eax                     /* we have the xptr on the stack  */
576         
577                 mov     IntSave(%edx),%ecx          /* %ecx = saved int register count*/
578                 test    %ecx,%ecx
579                 je      noint
580                 cmp     $1,%ecx
581                 je      int1
582                 cmp     $2,%ecx
583                 je      int2
584                 cmp     $3,%ecx
585                 je      int3
586
587 int4:   
588                 mov     -32(%eax),%ebx
589
590 int3:   
591                 mov     -24(%eax),%ebp
592
593 int2:   
594                 mov     -16(%eax),%esi
595
596 int1:   
597                 mov     -8(%eax),%edi
598
599                 shl     $3,%ecx                                         /* multiply by 8 bytes             */
600                 sub     %ecx,%eax
601                 
602 noint:
603                 mov     FltSave(%edx),%ecx                      /* %ecx = saved flt register count */
604                 test    %ecx,%ecx
605                 je      noflt
606                 cmp     $1,%ecx
607                 je      flt1
608                 cmp     $2,%ecx
609                 je      flt2
610                 cmp     $3,%ecx
611                 je      flt3
612                 
613 flt4:   
614                 fldl    -32(%eax)
615                 fstp    %st(1)
616
617 flt3:   
618                 fldl    -24(%eax)
619                 fstp    %st(2)
620                 
621 flt2:   
622                 fldl    -16(%eax)
623                 fstp    %st(3)
624                 
625 flt1:   
626                 fldl    -8(%eax)
627                 fstp    %st(4)
628                 
629 noflt:
630         pop     %eax                        /* restore exception pointer      */
631         
632         mov     FrameSize(%edx),%ecx        /* %ecx = frame size              */
633         add     %ecx,%esp                   /* unwind stack                   */
634         
635                 pop     %ecx                        /* the new xpc is return address  */
636                 sub     $2,%ecx
637                 
638                 jmp             asm_handle_exception_loop
639                 
640
641 /********************* function asm_check_clinit *******************************
642 *                                                                              *
643 *   Does null check and calls monitorenter or throws an exception              *
644 *                                                                              *
645 *******************************************************************************/
646
647 asm_check_clinit:
648         mov     offclassinit(%eax),%ecx     /* get initialized flag               */
649         test    %ecx,%ecx
650         jnz     L_is_initialized
651
652         sub     $16,%esp                    /* build stack frame (4 * 4 bytes)    */
653         mov     %eax,(%esp)
654         call    builtin_asm_get_stackframeinfo
655
656         movl    $0,12(%esp)
657     mov     %eax,8(%esp)
658         mov     (%eax),%ecx
659         mov     %ecx,4(%esp)
660         mov     %esp,%ecx
661         add     $4,%ecx
662         mov     %ecx,(%eax)
663
664         call    class_init                  /* call class_init function           */
665
666         mov     4(%esp),%ebx
667         mov     8(%esp),%ecx
668         mov     %ebx,(%ecx)
669
670         add     $16,%esp
671
672         test    %eax,%eax                   /* we had an exception                */
673         je      L_initializererror
674
675 L_is_initialized:
676         mov     (%esp),%eax                 /* get return address                 */
677         sub     $12,%eax                    /* asm_putstatic call code size       */
678         movb    $0xeb,(%eax)                /* jmp rel8                           */
679         movb    $10,1(%eax)                 /* 8-bit offset                       */
680         ret
681
682 L_initializererror:
683 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
684         call    builtin_asm_get_exceptionptrptr
685         mov     %eax,%ecx
686         mov     (%ecx),%eax                 /* get the exception pointer          */
687         movl    $0,(%ecx)                   /* clear the exception pointer        */
688 #else
689         lea     _exceptionptr,%ecx
690         mov     (%ecx),%eax                 /* get the exception pointer          */
691         movl    $0,(%ecx)                   /* clear the exception pointer        */
692 #endif
693
694         pop     %ecx                        /* delete return address              */
695         sub     $2,%ecx                     /* faulting address is return adress - 2 */
696
697         jmp     asm_handle_exception
698
699
700 /********************* function asm_builtin_monitorenter ***********************
701 *                                                                              *
702 *   Does null check and calls monitorenter or throws an exception              *
703 *                                                                              *
704 *******************************************************************************/
705
706 asm_builtin_monitorenter:
707         cmpl    $0,4(%esp)
708         je      nb_monitorenter             /* if (null) throw exception          */
709         jmp             builtin_monitorenter        /* else call builtin_monitorenter     */
710
711 nb_monitorenter:
712         push    string_java_lang_NullPointerException
713         call    new_exception
714         add     $(1*4),%esp
715         
716         pop     %ecx                        /* delete return address              */
717         sub     $2,%ecx                     /* faulting address is return adress - 2 */
718         jmp     asm_handle_exception
719                 
720
721 /********************* function asm_builtin_monitorexit ************************
722 *                                                                              *
723 *   Does null check and calls monitorexit or throws an exception               *
724 *                                                                              *
725 *******************************************************************************/
726
727 asm_builtin_monitorexit:
728         mov     4(%esp),%eax
729     test    %eax,%eax
730         je      nb_monitorexit              /* if (null) throw exception          */
731     push    %ecx                        /* save registers which could be used */
732     push    %edx
733     push    %eax
734         call    builtin_monitorexit         /* else call builtin_monitorenter     */
735     add     $4,%esp
736     pop     %edx                        /* restore registers which could be used */
737     pop     %ecx
738     ret
739
740 nb_monitorexit:
741         push    string_java_lang_NullPointerException
742         call    new_exception
743         add     $(1*4),%esp
744         
745         pop     %ecx                    /* delete return address              */
746         sub     $2,%ecx                 /* faulting address is return adress - 2 */
747         jmp     asm_handle_exception
748
749
750 /************************ function asm_builtin_ldiv ****************************
751 *                                                                              *
752 *   Does null check and calls ldiv or throws an exception                      *
753 *                                                                              *
754 *******************************************************************************/
755
756 asm_builtin_ldiv:
757         mov     12(%esp),%eax
758         or      16(%esp),%eax
759         test    %eax,%eax                   /* if (null) throw exception          */
760         je      nb_ldiv
761
762         jmp     builtin_ldiv
763
764 nb_ldiv:
765         push    string_java_lang_ArithmeticException_message
766         push    string_java_lang_ArithmeticException
767         call    new_exception_message
768         add     $(2*4),%esp
769         
770         pop     %ecx                        /* delete return address              */
771         sub     $2,%ecx                     /* faulting address is return adress - 2 */
772         jmp     asm_handle_exception
773                                 
774
775 /************************ function asm_builtin_lrem ****************************
776 *                                                                              *
777 *   Does null check and calls lrem or throws an exception                      *
778 *                                                                              *
779 *******************************************************************************/
780
781 asm_builtin_lrem:
782         mov     12(%esp),%eax
783         or      16(%esp),%eax
784         test    %eax,%eax                   /* if (null) throw exception          */
785         je      nb_lrem
786
787         jmp     builtin_lrem
788
789 nb_lrem:
790         push    string_java_lang_ArithmeticException_message
791         push    string_java_lang_ArithmeticException
792         call    new_exception_message
793         add     $(2*4),%esp
794
795         pop     %ecx                        /* delete return address              */
796         sub     $2,%ecx                     /* faulting address is return adress - 2 */
797         jmp     asm_handle_exception
798                 
799
800 /************************ function asm_builtin_x2x *****************************
801 *                                                                              *
802 *   Wrapper functions for corner cases                                         *
803 *                                                                              *
804 *******************************************************************************/
805
806 asm_builtin_f2i:
807         sub     $4,%esp
808         fsts    (%esp)
809         call    builtin_f2i
810         add     $4,%esp
811         ret
812
813 asm_builtin_d2i:
814         sub     $8,%esp
815         fstl    (%esp)
816         call    builtin_d2i
817         add     $8,%esp
818         ret
819
820 asm_builtin_f2l:
821         sub     $4,%esp
822         fsts    (%esp)
823         call    builtin_f2l
824         add     $4,%esp
825         ret
826
827 asm_builtin_d2l:
828         sub     $8,%esp
829         fstl    (%esp)
830         call    builtin_d2l
831         add     $8,%esp
832         ret
833
834
835 /******************* function asm_builtin_checkarraycast ***********************
836 *                                                                              *
837 *   Does the cast check and eventually throws an exception                     *
838 *                                                                              *
839 *******************************************************************************/
840
841 asm_builtin_checkarraycast:
842         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
843
844         mov             12(%esp),%eax               /* 8 (frame) + 4 (return)             */
845         mov             %eax,(%esp)                 /* save object pointer                */
846
847         mov             20(%esp),%eax
848         mov             %eax,4(%esp)
849
850         call    builtin_checkarraycast      /* builtin_checkarraycast             */
851
852         test    %eax,%eax                   /* if (false) throw exception         */
853         je              nb_carray_throw
854
855         mov             12(%esp),%eax               /* return object pointer              */
856         add             $8,%esp
857         ret
858
859 nb_carray_throw:
860         push    string_java_lang_ClassCastException
861         call    new_exception
862         add     $(1*4),%esp
863         
864         add             $8,%esp
865         
866         pop             %ecx                        /* delete return address              */
867         sub             $2,%ecx                     /* faulting address is return adress - 2 */
868         jmp             asm_handle_exception
869
870                 
871 /******************* function asm_builtin_newarray *****************************
872 *                                                                              *
873 *   Does the cast check and eventually throws an exception                     *
874 *                                                                              *
875 *******************************************************************************/
876
877 asm_builtin_newarray:
878         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
879
880         mov             12(%esp),%eax
881         mov             %eax,(%esp)
882
883         mov             20(%esp),%eax
884         mov             %eax,4(%esp)
885
886         call    builtin_newarray
887
888         add             $8,%esp
889         ret
890
891                 
892 /******************* function asm_builtin_aastore ******************************
893 *                                                                              *
894 *   Does the cast check and eventually throws an exception                     *
895 *                                                                              *
896 *******************************************************************************/
897
898 asm_builtin_aastore:
899         sub     $12,%esp                    /* build stack frame (3 * 4 bytes)    */
900
901         mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
902         test    %eax,%eax                   /* if null pointer throw exception    */
903         je      nb_aastore_null
904
905         mov     offarraysize(%eax),%edx /* load size                          */
906         mov     24(%esp),%ecx               /* index                              */
907         cmp     %edx,%ecx                   /* do bound check                     */
908         jae     nb_aastore_bound            /* if out of bounds throw exception   */
909
910         shl     $2,%ecx                     /* index * 4                          */
911         add     %eax,%ecx                   /* add index * 4 to arrayref          */
912            
913         mov     %ecx,8(%esp)                /* save store position                */
914            
915         mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
916         mov     %eax,(%esp)
917            
918         mov     32(%esp),%eax               /* object is second argument          */
919         mov     %eax,4(%esp)
920         
921         call    builtin_canstore            /* builtin_canstore(arrayref,object)  */
922
923         test    %eax,%eax                   /* if (false) throw exception         */
924         je      nb_aastore_store
925
926         mov     32(%esp),%eax
927         mov     8(%esp),%ecx
928         mov     %eax,offobjarrdata(%ecx)    /* store objectptr in array           */
929         
930         add     $12,%esp
931         ret
932
933 nb_aastore_null:
934         push    string_java_lang_NullPointerException
935         call    new_exception
936         add     $(1*4),%esp
937         
938         add     $12,%esp
939         pop     %ecx                        /* delete return address              */
940         sub     $2,%ecx                     /* faulting address is return adress - 2 */
941         jmp             asm_handle_exception
942
943 nb_aastore_bound:
944         push    %ecx                        /* itmp2 contains array index         */
945         push    string_java_lang_ArrayIndexOutOfBoundsException
946         call    new_exception_int
947         add     $(2*4),%esp
948
949         add     $12,%esp
950         pop     %ecx                        /* delete return address              */
951         sub     $2,%ecx                     /* faulting address is return adress - 2 */
952         jmp     asm_handle_exception
953                 
954 nb_aastore_store:
955         push    string_java_lang_ArrayStoreException
956         call    new_exception
957         add     $(1*4),%esp
958         
959         add     $12,%esp
960         pop     %ecx                        /* delete return address              */
961         sub     $2,%ecx                     /* faulting address is return adress - 2 */
962         jmp     asm_handle_exception
963
964                 
965 /******************* function asm_builtin_arrayinstanceof **********************
966 *                                                                              *
967 *   Does the instanceof check of arrays                                        *
968 *                                                                              *
969 *******************************************************************************/
970
971 asm_builtin_arrayinstanceof:
972         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
973
974         mov     12(%esp),%eax
975         mov     %eax,(%esp)
976
977         mov     20(%esp),%eax
978         mov     %eax,4(%esp)
979
980         call    builtin_arrayinstanceof
981
982         add     $8,%esp
983         ret
984
985                 
986 /******************* function asm_initialize_thread_stack **********************
987 *                                                                              *
988 * initialized a thread stack                                                   *
989 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
990 *                                                                              *
991 *******************************************************************************/
992
993 asm_initialize_thread_stack:
994                 mov             8(%esp),%eax            /* (to)->stackEnd                     */
995                 sub             $36,%eax                /* 4 bytes * 8 regs + 4 bytes func    */
996                                 
997                 xor             %edx,%edx
998                 mov             %edx,0(%eax)
999                 mov             %edx,4(%eax)
1000                 mov             %edx,8(%eax)
1001                 mov             %edx,12(%eax)
1002                 mov             %edx,16(%eax)
1003                 mov             %edx,20(%eax)
1004                 mov     %edx,24(%eax)
1005                 mov     %edx,28(%eax)
1006                                 
1007                 mov     4(%esp),%edx            /* save (u1*) (func)                  */
1008                 mov     %edx,32(%eax)
1009
1010                 ret                             /* return restorepoint in %eax        */
1011
1012
1013 /******************* function asm_perform_threadswitch *************************
1014 *                                                                              *
1015 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1016 *                                                                              *
1017 *   performs a threadswitch                                                    *
1018 *                                                                              *
1019 *******************************************************************************/
1020
1021 asm_perform_threadswitch:
1022         sub     $36,%esp
1023            
1024         mov     %eax,0(%esp)
1025         mov     %ecx,4(%esp)
1026         mov     %edx,8(%esp)
1027         mov     %ebx,12(%esp)
1028         mov     %esp,16(%esp)
1029         mov     %ebp,20(%esp)
1030         mov     %esi,24(%esp)
1031         mov     %edi,28(%esp)
1032            
1033         mov     36(%esp),%eax         /* save current return address              */
1034         mov     %eax,32(%esp)
1035            
1036         mov     40(%esp),%eax         /* first argument **from                    */
1037         mov     %esp,0(%eax)
1038            
1039         mov     48(%esp),%eax         /* third argument **stackTop                */
1040         mov     %esp,0(%eax)
1041            
1042         mov     44(%esp),%eax         /* second argument **to                     */
1043         mov     0(%eax),%esp          /* load new stack pointer                   */
1044            
1045         mov     0(%esp),%eax
1046         mov     4(%esp),%ecx
1047         mov     8(%esp),%edx
1048         mov     12(%esp),%ebx
1049                                       /* skip stack pointer                       */
1050         mov     20(%esp),%ebp
1051         mov     24(%esp),%esi
1052         mov     28(%esp),%edi
1053            
1054         add     $32,%esp              /* leave return address on stack            */
1055         ret
1056                 
1057
1058 /********************* function asm_switchstackandcall *************************
1059 *                                                                              *
1060 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
1061 *                                      void *p);                                       *
1062 *                                                                              *
1063 *   Switches to a new stack, calls a function and switches back.               *
1064 *       a0      new stack pointer                                              *
1065 *       a1      function pointer                                               *
1066 *               a2              pointer to variable where stack top should be stored           *
1067 *       a3      pointer to user data, is passed to the function                *
1068 *                                                                              *
1069 *******************************************************************************/
1070
1071 asm_switchstackandcall:
1072         mov     4(%esp),%edx          /* first argument *stack                    */
1073         sub     $8,%edx               /* allocate new stack                       */
1074
1075         mov     (%esp),%eax           /* save return address on new stack         */
1076         mov     %eax,(%edx)
1077
1078         mov     %esp,4(%edx)          /* save old stack pointer on new stack      */
1079
1080         mov     12(%esp),%eax         /* third argument **stacktopsave            */
1081         mov     %esp,(%eax)           /* save old stack pointer to variable       */
1082
1083         mov     8(%esp),%eax          /* load function pointer                    */
1084         mov     16(%esp),%ecx         /* fourth argument *p                       */
1085         
1086         mov     %edx,%esp             /* switch to new stack                      */
1087
1088         sub     $4,%esp
1089         mov     %ecx,0(%esp)          /* pass pointer                             */
1090         call    *%eax                 /* and call function                        */
1091         add     $4,%esp
1092
1093         mov     (%esp),%edx           /* load return address                      */
1094         mov     4(%esp),%esp          /* switch to old stack                      */
1095         mov     %edx,(%esp)
1096         ret
1097
1098                 
1099 Java_java_lang_VMSecurityManager_currentClassLoader:
1100         lea  builtin_asm_getclassloader,%eax 
1101         push %eax       /*store collector function pointer*/
1102         jmp getClassContext_begin
1103 Java_java_lang_VMSecurityManager_getClassContext:
1104         lea  builtin_asm_createclasscontextarray,%eax 
1105         push %eax /*store collector function pointer*/
1106 getClassContext_begin:  /*start the real work*/
1107
1108         mov %esp,%eax
1109         sub $4,%eax
1110         sub $68,%esp /*64 memory location without overwriting return adress and collector function adress*/
1111         mov %esp,%ebx   /*end of allocated memory block for classpointers is the adress of the working data block +4 */
1112         push $0 /*%esp+32 was native*/
1113         push %eax /*%esp+24 blkbegin*/
1114         push %eax /*%esp+20 currentpos*/
1115         push %ebx /*%esp+16 blkend*/
1116
1117         call builtin_asm_get_threadrootmethod
1118         push %eax /*%esp+12*/
1119         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*/
1120         movl %esp,%edx
1121         addl $116, %edx
1122         push %edx /*esp+8*/ /*position of return address of native stub*/
1123         call builtin_asm_get_stackframeinfo
1124         movl (%eax),%eax /*comment ??*/
1125         push 0(%eax) /*esp+4*/ /*address of frame info block*/
1126         movl 124(%esp),%edx
1127
1128 /*DEBUG*/
1129 /*      mov %esp,%eax
1130         addl $116,%eax
1131         push %eax
1132         call i386_native_stub_debug
1133         pop %eax*/
1134
1135         push %edx /*esp+0*/ /*return adress out of native stub*/
1136         call codegen_findmethod /*find calling java method, this one is still to be skipped (==SecurityManager.getClassContext (or .currentClassLoader)*/
1137
1138 /*DEBUGGING*/
1139 /*      push %eax
1140         movl MethodPointer(%eax),%eax
1141         push %eax
1142         call temporaryGetClassContextHelper
1143         pop %eax
1144         call traverseStackInfo
1145         pop %eax
1146 */
1147
1148         movl 20(%esp),%edx
1149         movl MethodPointer(%eax),%ebx
1150         movl offclassmethodinfo(%ebx),%ecx
1151         movl %ecx,(%edx)
1152         subl $4,%edx
1153         movl %edx,20(%esp)
1154
1155         mov 8(%esp),%ebx /*pos of return adress */
1156         add FrameSize(%eax),%ebx
1157         add $4,%ebx     /*adress of new return adress (out of Securitymanager.*/
1158         mov %ebx,8(%esp) 
1159         mov %eax,(%esp)
1160
1161         /* by now we have skipped this method call*/
1162
1163 getClassContext_next:   
1164         movl 8(%esp),%eax
1165         movl (%eax),%eax
1166         movl %eax,(%esp) /*return adress*/
1167
1168         call codegen_findmethod
1169
1170         cmp $1,32(%esp)
1171         mov 8(%esp),%ebx
1172         add FrameSize(%eax),%ebx
1173         add $4,%ebx
1174         mov %ebx,8(%esp) /*store adress of next return adress*/
1175 getClassContext_nextRetStored:
1176
1177         mov MethodPointer(%eax),%ecx    /*get struct methodinfo*/
1178
1179         cmp $0,%ecx
1180         je getClassContext_nativeCall
1181         /*save class pointer*/
1182         movl $0,32(%esp)
1183 getClassContext_saveClassPointer:
1184         movl 20(%esp),%ebx      /*get temporary memory adress in stack*/
1185         movl offclassmethodinfo(%ecx),%edx /* get class pointer of method*/
1186         movl %edx,(%ebx) /*save */
1187         sub $4,%ebx     /*calculate next position */
1188         movl %ebx,20(%esp) /* check if the new adress would overwrite our working data */
1189         cmp %ebx,16(%esp)
1190         je getClassContext_incStack
1191 getClassContext_checkLeave:
1192         
1193         cmp 12(%esp),%ecx       /*check if we reached the toplevel method of our thread*/
1194         je  getClassContext_leave /*yes ->leave*/
1195
1196 /*DEBUGING*/
1197 /*      mov %ecx,(%esp)
1198         call temporaryGetClassContextHelper
1199 */
1200         
1201         
1202         jmp getClassContext_next /*continue*/
1203
1204
1205 getClassContext_nativeCall:
1206         movl $1,32(%esp)
1207         movl 4(%esp),%eax       /*get top most element on stackframe help information stack*/
1208         movl 0(%eax),%ecx 
1209         movl %ecx,4(%esp)
1210         addl $8,%eax
1211         movl (%eax),%ecx
1212         addl $4,%eax
1213         movl %eax,8(%esp)
1214         
1215         cmp $0,%ecx
1216         je getClassContext_checkLeave
1217         jmp getClassContext_saveClassPointer
1218
1219 getClassContext_incStack:
1220         /*make another 64 in our temporary storage free and store the workingdata */
1221         movl %esp,%edx
1222         subl $40,%esp /*should be 32*/
1223         push 32(%edx)
1224         push 28(%edx)
1225         push 24(%edx)
1226         push 20(%edx)
1227         push 16(%edx)
1228         push 12(%edx)
1229         push 8(%edx)
1230         push 4(%edx)
1231         push 0(%edx)
1232         subl $64,16(%esp)
1233
1234         jmp getClassContext_checkLeave /* continue */
1235
1236 getClassContext_leave:
1237 /*DEBUGING*/
1238 /*      mov %ecx,(%esp)
1239         call temporaryGetClassContextHelper*/
1240
1241         /*call collector function with begin/end of temporary classarray*/
1242         push 24(%esp)
1243         push 24(%esp)
1244         
1245         movl 32(%esp),%eax
1246         add $4,%eax
1247         movl (%eax),%ebx
1248         call *%ebx
1249
1250         /* free stack memory of this function*/
1251         mov 32(%esp),%esp
1252         add $8,%esp
1253         ret
1254
1255
1256 asm_throw_and_handle_hardware_nullpointer_exception:
1257         sub $20,%esp /*build stack frame*/
1258         mov %ecx,16(%esp) /*save eip of problem */
1259         
1260         movl $0,12(%esp) /*internal function -> no function description */
1261         call builtin_asm_get_stackframeinfo
1262         mov %eax,8(%esp)
1263         mov (%eax),%ecx
1264         mov %ecx,4(%esp)
1265         mov %esp,%ecx
1266         add $4,%ecx
1267         mov %ecx,(%eax)
1268         
1269         mov string_java_lang_NullPointerException,%eax
1270         mov %eax,(%esp)
1271         call new_exception
1272         push %eax
1273         mov 8(%esp),%eax
1274         mov 12(%esp),%ecx
1275         mov %eax,(%ecx)
1276         pop %eax
1277         add $16,%esp
1278         pop %ecx
1279         jmp asm_handle_exception
1280         ret /*should never be reached */
1281
1282 asm_throw_and_handle_hardware_arithmetic_exception:
1283         sub $24,%esp /*build stack frame*/
1284         mov %ecx,20(%esp) /*save eip of problem */
1285         
1286         movl $0,16(%esp) /*internal function -> no function description */
1287         call builtin_asm_get_stackframeinfo
1288         mov %eax,12(%esp)
1289         mov (%eax),%ecx
1290         mov %ecx,8(%esp)
1291         mov %esp,%ecx
1292         add $8,%ecx
1293         mov %ecx,(%eax)
1294         
1295         mov string_java_lang_ArithmeticException,%eax
1296         mov %eax,(%esp)
1297         mov string_java_lang_ArithmeticException_message,%eax
1298         mov %eax,4(%esp)
1299
1300         call new_exception_message
1301
1302         push %eax
1303         mov 12(%esp),%eax
1304         mov 16(%esp),%ecx
1305         mov %eax,(%ecx)
1306         pop %eax
1307         add $20,%esp
1308         pop %ecx
1309         jmp asm_handle_exception
1310         ret /*should never be reached */
1311
1312 asm_builtin_new:
1313 /*optimize a littlebit */
1314                 mov %esp,%eax
1315 /*DEBUG*/
1316 /*              push %eax
1317                 call i386_native_stub_debug
1318                 pop %eax */
1319                 
1320                 movl 4(%esp),%eax
1321                 mov     offclassinit(%eax),%ecx     /* get initialized flag           */
1322                 test    %ecx,%ecx
1323                 jnz             L_builtin_new_noinit
1324
1325                 sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
1326
1327                 mov             20(%esp),%eax
1328                 mov             %eax,(%esp)
1329
1330                 call    builtin_asm_get_stackframeinfo
1331                 movl    $0,12(%esp)
1332                 mov     %eax,8(%esp)
1333                 mov     (%eax),%ebx
1334                 mov     %ebx,4(%esp)
1335                 mov     %esp,%ecx
1336                 add     $4,%ecx
1337                 mov     %ecx,(%eax)
1338
1339                 call    builtin_new
1340
1341                 mov     4(%esp),%ebx
1342                 mov     8(%esp),%ecx
1343                 mov     %ebx,(%ecx)
1344
1345                 add             $16,%esp
1346
1347                 jmp L_builtin_new_patch
1348
1349
1350 L_builtin_new_noinit:
1351                 mov 4(%esp),%eax
1352                 push %eax
1353                 call builtin_new
1354                 add $4,%esp
1355                 /*jmp L_builtin_new_patch*/
1356
1357 L_builtin_new_patch:
1358 /*add patching code here */
1359                 lea builtin_new,%edx
1360                 mov (%esp),%ecx
1361                 mov %edx,-6(%ecx)       /*patch calling instruction, t directly call builtin_new the next time*/
1362                 ret
1363
1364
1365
1366
1367
1368 asm_get_stackTrace:
1369         push %ebp /*(%ebp-4)*/
1370         mov %esp,%ebp
1371         add $4,%ebp
1372         push %edi /*(%ebp-8)*/
1373         push %esi /*(%ebp-12)*/
1374         push %ebx /*(%ebp-16)*/
1375         call builtin_asm_get_stackframeinfo
1376         movl (%eax),%eax
1377         pushl 0(%eax) /*(%ebp-20)*/
1378         lea 12(%eax),%edi
1379         call builtin_asm_get_threadrootmethod
1380         pushl %eax /*(%ebp-24)*/
1381
1382         pushl (%edi)
1383 asm_get_stackTraceLoop:
1384         call codegen_findmethod
1385         mov %eax,%esi
1386         add $4,%esp
1387         pushl $1 /*no indent*/
1388
1389         mov (%edi),%edx
1390         sub $4,%edx
1391
1392 get_stackTrace_line:
1393         movl LineNumberTableSize(%esi),%ecx
1394         test    %ecx,%ecx /* skip if empty line table */
1395         je      get_stackTrace_noLineInfo
1396
1397         movl LineNumberTableStart(%esi),%ebx
1398         
1399 get_stackTrace_lineLoop:
1400         cmp %edx,LinePC(%ebx)
1401         jg get_stackTrace_nextLineInfo
1402
1403         pushl LineLine(%ebx)
1404         jmp get_stackTrace_cont
1405
1406 get_stackTrace_nextLineInfo:    
1407         lea LineEntrySize(%ebx),%ebx
1408         dec %ecx
1409         test %ecx,%ecx
1410
1411         jne get_stackTrace_lineLoop
1412
1413 get_stackTrace_noLineInfo:
1414         pushl $0
1415
1416
1417 get_stackTrace_cont:
1418         pushl (%edi) /*4*/
1419         pushl MethodPointer(%esi)
1420         pushl $0 /*8(%ebp)*/ /*exception ptr*/
1421         call builtin_trace_exception
1422         add $12,%esp
1423
1424         movl MethodPointer(%esi),%eax
1425         movl %eax,4(%esp)
1426         test %eax,%eax
1427         je get_stackTrace_nat
1428
1429         cmp %eax,-24(%ebp)
1430         je get_stackTrace_leave
1431
1432         mov FrameSize(%esi),%eax
1433         add $4,%edi
1434         add %eax,%edi
1435         pushl (%edi)
1436         jmp asm_get_stackTraceLoop
1437
1438 get_stackTrace_nat:
1439         add $8,%esp
1440         movl -20(%ebp),%eax
1441         cmp $0,%eax
1442         je get_stackTrace_leave
1443         movl  0(%eax),%ebx
1444         movl  %ebx,-20(%ebp)
1445         pushl 8(%eax)
1446         pushl $0
1447         lea 12(%eax),%edi
1448         pushl (%edi)
1449         jmp asm_get_stackTraceLoop
1450
1451 get_stackTrace_leave:
1452         mov %esp,%eax
1453         lea -24(%ebp),%ebx
1454         push %ebx
1455         push %eax
1456         push 4(%ebp)
1457         call builtin_stacktrace_copy
1458
1459         lea -16(%ebp),%esp
1460         pop %ebx
1461         pop %esi
1462         pop %edi
1463         pop %ebp
1464         ret
1465
1466 asm_getclassvalues_atomic:
1467 _crit_restart2:
1468         mov 4(%esp),%ecx        /* super */
1469         mov 8(%esp),%edx        /* sub */
1470 _crit_begin2:
1471         mov offbaseval(%ecx),%eax
1472         mov offdiffval(%ecx),%ecx
1473         mov offbaseval(%edx),%edx
1474 _crit_end2:
1475         push %ebx
1476         mov 16(%esp),%ebx      /* out */
1477         mov %eax,offcast_super_baseval(%ebx)
1478         mov %ecx,offcast_super_diffval(%ebx)
1479         mov %edx,offcast_sub_baseval(%ebx)
1480         pop %ebx
1481         ret
1482
1483         .data
1484
1485 asm_criticalsections:
1486 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1487         .long _crit_begin1
1488         .long _crit_end1
1489         .long _crit_restart1
1490         .long _crit_begin2
1491         .long _crit_end2
1492         .long _crit_restart2
1493 #endif
1494         .long 0
1495
1496 /*
1497  * These are local overrides for various environment variables in Emacs.
1498  * Please do not remove this and leave it at the end of the file, where
1499  * Emacs will automagically detect them.
1500  * ---------------------------------------------------------------------
1501  * Local variables:
1502  * mode: asm
1503  * indent-tabs-mode: t
1504  * c-basic-offset: 4
1505  * tab-width: 4
1506  * End:
1507  */