about summary refs log tree commit diff
path: root/src/rt/rust_task.cpp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-12-18 16:59:49 -0800
committerBrian Anderson <banderson@mozilla.com>2011-12-18 17:17:31 -0800
commitbd6b80c9720bb4b0143378a052b568697ce3abe6 (patch)
tree4d261511241d91b59b485f3192803c922d98b728 /src/rt/rust_task.cpp
parentc73eb8ff51da170ff10aba73934f10e40d26366d (diff)
downloadrust-bd6b80c9720bb4b0143378a052b568697ce3abe6.tar.gz
rust-bd6b80c9720bb4b0143378a052b568697ce3abe6.zip
rt: Get rid of the rethrow in upcall_fail
Throwing in upcall_fail ends up running lots of code in the red zone. To avoid
it we have the personality function figure out which stack it's on and switch
as needed.
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index f74f821819c..f30315174b6 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -732,6 +732,17 @@ rust_task::record_stack_limit() {
 
 extern "C" uintptr_t get_sp();
 
+static bool
+sp_in_stk_seg(uintptr_t sp, stk_seg *stk) {
+    // Not positive these bounds for sp are correct.  I think that the first
+    // possible value for esp on a new stack is stk->end, which points to the
+    // address before the first value to be pushed onto a new stack. The last
+    // possible address we can push data to is stk->data.  Regardless, there's
+    // so much slop at either end that we should never hit one of these
+    // boundaries.
+    return (uintptr_t)stk->data <= sp && sp <= stk->end;
+}
+
 /*
 Called by landing pads during unwinding to figure out which
 stack segment we are currently running on, delete the others,
@@ -741,17 +752,21 @@ through __morestack).
 void
 rust_task::reset_stack_limit() {
     uintptr_t sp = get_sp();
-    // Not positive these bounds for sp are correct.
-    // I think that the first possible value for esp on a new
-    // stack is stk->end, which points one word in front of
-    // the first work to be pushed onto a new stack.
-    while (sp <= (uintptr_t)stk->data || stk->end < sp) {
+    while (!sp_in_stk_seg(sp, stk)) {
         del_stk(this, stk);
         A(sched, stk != NULL, "Failed to find the current stack");
     }
     record_stack_limit();
 }
 
+/*
+Returns true if we're currently running on the Rust stack
+ */
+bool
+rust_task::on_rust_stack() {
+    return sp_in_stk_seg(get_sp(), stk);
+}
+
 //
 // Local Variables:
 // mode: C++