rt: Rewrite 32-bit __morestack to use the shim upcall

This commit is contained in:
Brian Anderson 2011-11-30 14:24:54 -08:00
parent fdebd1e2ef
commit 037ca7f7cb

View File

@ -6,42 +6,22 @@
// prolog when we run out.
#if defined(__APPLE__) || defined(_WIN32)
#define RUST_NEW_STACK _rust_new_stack
#define RUST_NEW_STACK2 _rust_new_stack2
#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 UPCALL_CALL_C _upcall_call_shim_on_c_stack
#define MORESTACK ___morestack
#else
#define RUST_NEW_STACK rust_new_stack
#define RUST_NEW_STACK2 rust_new_stack2
#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 UPCALL_CALL_C upcall_call_shim_on_c_stack
#define MORESTACK __morestack
#endif
#ifdef __APPLE__
#define ALIGNMENT 4
#else
#define ALIGNMENT 8
#endif
#if defined (__APPLE__)
#define NEW_STACK_ADDR rust_new_stack_sym-.L$pic_ref_pt_0(%eax)
#define DEL_STACK_ADDR rust_del_stack_sym-.L$pic_ref_pt_1(%edx)
#else
#if defined (_WIN32)
#define NEW_STACK_ADDR $_rust_new_stack
#define DEL_STACK_ADDR $_rust_del_stack
#else
#define NEW_STACK_ADDR $rust_new_stack
#define DEL_STACK_ADDR $rust_del_stack
#endif
#endif
#define ALIGNMENT 8
#define RETURN_OFFSET 7
.globl RUST_NEW_STACK
@ -68,68 +48,66 @@
#if defined(__linux__)
MORESTACK:
// 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
pushl %ebp
movl %esp, %ebp
// FIXME (1226): main is compiled with the split-stack prologue,
// causing it to call __morestack, so we have to jump back out
subl $24,%esp
calll RUST_GET_TASK
testl %eax,%eax
jz .L$bail
movl $16, (%esp)
calll UPCALL_ALLOC_C_STACK
movl %eax,%edx
// The arguments to rust_new_stack2
movl %esp, 20(%esp) // Save the stack pointer
movl 36(%esp),%eax // Size of stack arguments
movl %eax,16(%esp)
leal 44+ALIGNMENT(%esp),%eax // Address of stack arguments
movl %eax,12(%esp)
movl 32(%esp),%eax // The amount of stack needed
movl %eax,8(%esp)
movl %esp, 12(%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 28+ALIGNMENT(%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
movl $RUST_NEW_STACK2,4(%esp)
leal 8(%esp), %eax
movl %eax,(%esp)
call UPCALL_CALL_C
calll .L$pic_ref_pt_0
.L$pic_ref_pt_0:
popl %eax
movl 28(%esp),%edx // Grab the return pointer.
addl $RETURN_OFFSET,%edx // Skip past the `add esp,4` and the `ret`.
movl NEW_STACK_ADDR,%eax
movl %eax,(%esp)
movl %edx,4(%esp)
// FIXME: Don't understand why just _here_ I have to say @PLT
calll UPCALL_CALL_C_STACK@PLT
movl %eax,%esp // Switch stacks.
call *%edx // Re-enter the function that called us.
movl 12(%esp),%edx // Grab the return pointer.
addl $RETURN_OFFSET,%edx // Skip past the `add esp,4` and the `ret`.
// Now the function that called us has returned, so we need to delete the
// old stack space.
movl %eax,%esp // Switch stacks.
calll *%edx // Re-enter the function that called us.
// NB: This is assuming we already have at least 2 words
// pushed onto the C stack. This is always true because
// Rust functions have implicit arguments.
movl $RUST_GET_PREV_STACK,4(%esp)
movl $0, (%esp)
call UPCALL_CALL_C
// Now the function that called us has returned, so we need to delete the
// old stack space.
// Switch back to the rust stack
movl %eax, %esp
calll RUST_GET_PREV_STACK
movl %eax,%esp // Switch back to the old stack.
movl $RUST_DEL_STACK,4(%esp)
movl $0, (%esp)
call UPCALL_CALL_C
movl $0,(%esp)
calll UPCALL_ALLOC_C_STACK
calll .L$pic_ref_pt_1
.L$pic_ref_pt_1:
popl %edx
movl DEL_STACK_ADDR,%edx
movl %edx,(%esp)
movl %eax,4(%esp)
calll UPCALL_CALL_C_STACK
addl $12,%esp
retl $8 // ra stksz argsz x ra args
addl $24,%esp
popl %ebp
retl $8
.L$bail:
movl 12(%esp),%edx
addl $RETURN_OFFSET,%edx
addl $12+4+8+ALIGNMENT,%esp
jmpl *%edx
movl 28(%esp),%edx
addl $RETURN_OFFSET,%edx
addl $24, %esp
popl %ebp
addl $4+8+ALIGNMENT,%esp
jmpl *%edx
#else