diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2011-11-14 13:52:35 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-11-17 10:52:59 -0800 |
| commit | e6c3c4e48c6187212b5bb21b5fdb521660b6b510 (patch) | |
| tree | f558c547c4f68221dbd14392fc35c938ad6f762d /src/rt/arch | |
| parent | f4eb25e0d032495fef50c445b211f2c2ff20eb9c (diff) | |
| download | rust-e6c3c4e48c6187212b5bb21b5fdb521660b6b510.tar.gz rust-e6c3c4e48c6187212b5bb21b5fdb521660b6b510.zip | |
rt: More work on morestack
Diffstat (limited to 'src/rt/arch')
| -rw-r--r-- | src/rt/arch/i386/morestack.S | 119 |
1 files changed, 98 insertions, 21 deletions
diff --git a/src/rt/arch/i386/morestack.S b/src/rt/arch/i386/morestack.S index 2f5987a4350..ec356ea91c6 100644 --- a/src/rt/arch/i386/morestack.S +++ b/src/rt/arch/i386/morestack.S @@ -2,40 +2,117 @@ // __morestack // -// LLVM generates a call to this to allocate more stack space in a functiono +// LLVM generates a call to this to allocate more stack space in a function // prolog when we run out. #if defined(__APPLE__) || defined(_WIN32) -#define RUST_NEW_STACK _rust_new_stack -#define RUST_DEL_STACK _rust_del_stack -#define MORESTACK ___morestack +#define RUST_NEW_STACK _rust_new_stack +#define RUST_DEL_STACK _rust_del_stack +#define RUST_GET_PREV_STACK _rust_get_prev_stack +#define RUST_GET_TASK _rust_get_task +#define UPCALL_ALLOC_C_STACK _upcall_alloc_c_stack +#define UPCALL_CALL_C_STACK _upcall_call_c_stack +#define MORESTACK ___morestack #else -#define RUST_NEW_STACK rust_new_stack -#define RUST_DEL_STACK rust_del_stack -#define MORESTACK __morestack +#define RUST_NEW_STACK rust_new_stack +#define RUST_DEL_STACK rust_del_stack +#define RUST_GET_PREV_STACK rust_get_prev_stack +#define RUST_GET_TASK rust_get_task +#define UPCALL_ALLOC_C_STACK upcall_alloc_c_stack +#define UPCALL_CALL_C_STACK upcall_call_c_stack +#define MORESTACK __morestack #endif +#ifdef __APPLE__ +#define ALIGNMENT 4 +#else +#define ALIGNMENT 8 +#endif + +#define RETURN_OFFSET 7 + .globl RUST_NEW_STACK .globl RUST_DEL_STACK - +.globl RUST_GET_PREV_STACK +.globl RUST_GET_TASK +.globl UPCALL_ALLOC_C_STACK +.globl UPCALL_CALL_C_STACK .globl MORESTACK MORESTACK: - pushl 8(%esp) // argsz > ra stksz argsz x x ra args - leal 28(%esp),%eax // argsz ra stksz argsz x x ra args - pushl %eax // argp > argsz ra stksz argsz x x ra args - pushl 12(%esp) // stksz > argp argsz ra stksz argsz x x ra args - calll RUST_NEW_STACK - addl $12,%esp // ra stksz argsz x x ra args - - movl (%esp),%edx // Grab the return pointer. - incl %edx // Skip past the `ret`. - movl %eax,%esp // Switch to the new stack. + + // Sanity check to make sure that there is a currently-running task. + subl $12,%esp + calll RUST_GET_TASK + testl %eax,%eax + jz L$bail + + subl $12,%esp + pushl $12 + calll UPCALL_ALLOC_C_STACK + movl %eax,%edx + + // C stack | esp+12 + // ---------------------+------------------------- + movl 20(%esp),%eax // | ra stksz argsz x ra args + movl %eax,8(%edx) // argsz > | ra stksz argsz x ra args + leal 32(%esp),%eax // argsz | ra stksz argsz x ra args + movl %eax,4(%edx) // argp > argsz | ra stksz argsz x ra args + movl 16(%esp),%eax // argp argsz | ra stksz argsz x ra args + movl %eax,(%edx) // stksz > argp argsz | ra stksz argsz x ra args + + calll L$pic_ref_pt_0 +L$pic_ref_pt_0: + popl %eax + + movl rust_new_stack_sym-L$pic_ref_pt_0(%eax),%eax + movl %eax,(%esp) + movl %edx,4(%esp) + calll UPCALL_CALL_C_STACK + + movl 16(%esp),%edx // Grab the return pointer. + addl $RETURN_OFFSET,%edx // Skip past the `add esp,4` and the `ret`. + + movl %eax,%esp // Switch stacks. + subl $12,%esp // Align the stack. calll *%edx // Re-enter the function that called us. // Now the function that called us has returned, so we need to delete the // old stack space. - calll RUST_DEL_STACK - movl %eax,%esp - retl $8 // ra stksz argsz x x ra args + + calll RUST_GET_PREV_STACK + movl %eax,%esp // Switch back to the old stack. + + movl $0,(%esp) + calll UPCALL_ALLOC_C_STACK + + calll L$pic_ref_pt_1 +L$pic_ref_pt_1: + popl %edx + + movl rust_del_stack_sym-L$pic_ref_pt_1(%edx),%edx + movl %edx,(%esp) + movl %eax,4(%esp) + calll UPCALL_CALL_C_STACK + + addl $16,%esp + retl $16 + ALIGNMENT // ra stksz argsz x ra args + +L$bail: + movl 12(%esp),%edx + addl $RETURN_OFFSET,%edx + addl $12+16,%esp + jmpl *%edx + +#ifdef __APPLE__ + + .section __IMPORT,__pointers,non_lazy_symbol_pointers +rust_new_stack_sym: + .indirect_symbol RUST_NEW_STACK + .long 0 +rust_del_stack_sym: + .indirect_symbol RUST_DEL_STACK + .long 0 + +#endif |
