about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-11-30 14:24:54 -0800
committerBrian Anderson <banderson@mozilla.com>2011-11-30 20:31:32 -0800
commit037ca7f7cb00c5eb2def4b766c01aac4c07a9fb4 (patch)
tree1560ec50fa608feeb3e9fb5991de86bb880af040 /src/rt
parentfdebd1e2ef440312ac791d505af7dd089efa2499 (diff)
rt: Rewrite 32-bit __morestack to use the shim upcall
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/arch/i386/morestack.S148
1 files changed, 63 insertions, 85 deletions
diff --git a/src/rt/arch/i386/morestack.S b/src/rt/arch/i386/morestack.S
index f888373e5cf..d739f820422 100644
--- a/src/rt/arch/i386/morestack.S
+++ b/src/rt/arch/i386/morestack.S
@@ -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
-
-    movl $16, (%esp)
-    calll UPCALL_ALLOC_C_STACK
-    movl %eax,%edx
-
-    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
-
-    calll .L$pic_ref_pt_0
-.L$pic_ref_pt_0:
-    popl %eax
-
-    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 12(%esp),%edx          // Grab the return pointer.
-    addl $RETURN_OFFSET,%edx    // Skip past the `add esp,4` and the `ret`.
-
-    movl %eax,%esp          // Switch stacks.
-    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_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 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
+	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
+
+	// 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 $RUST_NEW_STACK2,4(%esp)
+	leal 8(%esp), %eax
+	movl %eax,(%esp)
+	call UPCALL_CALL_C
+
+	movl 28(%esp),%edx          // Grab the return pointer.
+	addl $RETURN_OFFSET,%edx    // Skip past the `add esp,4` and the `ret`.
+
+	movl %eax,%esp          // Switch stacks.
+	call *%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.
+
+	// 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
+
+	// Switch back to the rust stack
+	movl %eax, %esp
+
+	movl $RUST_DEL_STACK,4(%esp)
+	movl $0, (%esp)
+	call UPCALL_CALL_C
+
+	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