rt: Make 64-bit __morestack grow and shrink properly

This commit is contained in:
Brian Anderson 2011-11-28 21:57:52 -08:00
parent 5461c61af2
commit a9967423f8
3 changed files with 55 additions and 8 deletions

View File

@ -8,11 +8,15 @@
#if defined(__APPLE__) || defined(_WIN32)
#define RUST_NEW_STACK2 _rust_new_stack2
#define RUST_DEL_STACK _rust_del_stack
#define RUST_DEL_STACK _rust_del_stack
#define RUST_GET_PREV_STACK _rust_get_prev_stack
#define UPCALL_CALL_C _upcall_call_shim_on_c_stack
#define MORESTACK ___morestack
#else
#define RUST_NEW_STACK2 rust_new_stack2
#define RUST_DEL_STACK rust_del_stack
#define RUST_DEL_STACK rust_del_stack
#define RUST_GET_PREV_STACK rust_get_prev_stack
#define UPCALL_CALL_C upcall_call_shim_on_c_stack
#define MORESTACK __morestack
#endif
@ -59,6 +63,11 @@ MORESTACK:
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
// Alignment
pushq $0
// FIXME: libgcc also saves rax. not sure if we need to
// Save argument registers
pushq %rdi
pushq %rsi
@ -77,15 +86,46 @@ MORESTACK:
pushq %rcx // Address of stack arguments
pushq %r10 // The amount of stack needed
lea RUST_NEW_STACK2@PLT(%rip), %rsi
mov %rsp, %rdi
leaq RUST_NEW_STACK2@PLT(%rip), %rsi
movq %rsp, %rdi
call UPCALL_CALL_C@PLT
mov (%rsp),%rdx // Grab the return pointer.
inc %rdx // Skip past the `ret`.
mov %rax,%rsp // Switch to the new stack.
call *%rdx // Enter the new function.
// Pop the new_stack_args struct
addq $32, %rsp
// Pop the saved arguments
popq %r9
popq %r8
popq %rcx
popq %rdx
popq %rsi
popq %rdi
movq 8(%rbp),%r10 // Grab the return pointer.
incq %r10 // Skip past the `ret` in our parent frame
movq %rax,%rsp // Switch to the new stack.
call *%r10 // Reenter the caller function
leaq RUST_GET_PREV_STACK@PLT(%rip), %rsi
movq $0, %rdi
call UPCALL_CALL_C@PLT
// Switch back to the rust stack, positioned
// where we pushed %ebp
movq %rax, %rsp
// Align the stack again
pushq $0
leaq RUST_DEL_STACK@PLT(%rip), %rsi
movq $0, %rdi
call UPCALL_CALL_C@PLT
addq $8, %rsp
popq %rbp
ret
.cfi_endproc
#else
MORESTACK:

View File

@ -11,6 +11,7 @@
#if defined(__linux__)
RECORD_SP:
movq %rdi, %fs:112
ret
#else
RECORD_SP:
ret

View File

@ -95,7 +95,13 @@ static size_t const BUF_BYTES = 2048;
#define PROC_FAIL_CODE 101;
// FIXME: We want this to be 128 but need to slim the red zone calls down
#define RED_ZONE_SIZE 256
#ifdef __i386__
#define RED_ZONE_SIZE 256
#endif
#ifdef __x86_64__
#define RED_ZONE_SIZE 2048
#endif
// Every reference counted object should use this macro and initialize
// ref_count.