rt: Update 32-bit __morestack for recent LLVM changes

This commit is contained in:
Brian Anderson 2011-12-04 20:40:34 -08:00
parent a69eab16ec
commit 52d7dc5e0a
2 changed files with 24 additions and 20 deletions

View File

@ -25,11 +25,6 @@
#endif
#endif
// FIXME: Future LLVM patches remove these 8 alignment bytes from
// the function prologue in order to match gcc's behavior
#define ALIGNMENT 8
#define RETURN_OFFSET 7
.globl UPCALL_NEW_STACK
.globl UPCALL_DEL_STACK
.globl RUST_GET_TASK
@ -57,17 +52,17 @@ MORESTACK:
// FIXME (1226): main is compiled with the split-stack prologue,
// causing it to call __morestack, so we have to jump back out
subl $20,%esp
subl $28,%esp
calll RUST_GET_TASK
testl %eax,%eax
jz .L$bail
// The arguments to rust_new_stack2
movl 32(%esp),%eax // Size of stack arguments
movl 40(%esp),%eax // Size of stack arguments
movl %eax,16(%esp)
leal 40+ALIGNMENT(%esp),%eax // Address of stack arguments
leal 48(%esp),%eax // Address of stack arguments
movl %eax,12(%esp)
movl 28(%esp),%eax // The amount of stack needed
movl 36(%esp),%eax // The amount of stack needed
movl %eax,8(%esp)
#ifdef __APPLE__
@ -83,8 +78,8 @@ MORESTACK:
movl %eax,(%esp)
call UPCALL_CALL_C
movl 24(%esp),%edx // Grab the return pointer.
addl $RETURN_OFFSET,%edx // Skip past the `add esp,4` and the `ret`.
movl 32(%esp),%edx // Grab the return pointer.
inc %edx // Skip past the ret instruction in the parent fn
movl %eax,%esp // Switch stacks.
call *%edx // Re-enter the function that called us.
@ -95,6 +90,8 @@ MORESTACK:
// Switch back to the rust stack
movl %ebp, %esp
subl $8, %esp // Alignment
#ifdef __APPLE__
call 1f
1: popl %ebx
@ -107,17 +104,17 @@ MORESTACK:
pushl $0
call UPCALL_CALL_C
addl $8,%esp
addl $16,%esp
popl %ebp
retl $8
.L$bail:
movl 24(%esp),%edx
addl $RETURN_OFFSET,%edx
movl 32(%esp),%edx
inc %edx
addl $20, %esp
addl $28, %esp
popl %ebp
addl $4+8+ALIGNMENT,%esp
addl $4+8,%esp
jmpl *%edx

View File

@ -598,10 +598,17 @@ rust_task::del_stack() {
void
rust_task::record_stack_limit() {
// FIXME: Future LLVM patches expect us to add an additional 256 bytes
// here so that, if the frame size is < 256 it can generate the
// comparison against esp directly, instead of some offset from esp
record_sp(stk->data + RED_ZONE_SIZE);
// The function prolog compares the amount of stack needed to the end of
// the stack. As an optimization, when the frame size is less than 256
// bytes, it will simply compare %esp to to the stack limit instead of
// subtracting the frame size. As a result we need our stack limit to
// account for those 256 bytes.
const unsigned LIMIT_OFFSET = 256;
A(sched,
(uintptr_t)stk->limit - RED_ZONE_SIZE
- (uintptr_t)stk->data >= LIMIT_OFFSET,
"Stack size must be greater than LIMIT_OFFSET");
record_sp(stk->data + LIMIT_OFFSET + RED_ZONE_SIZE);
}
//
// Local Variables: