about summary refs log tree commit diff
path: root/src/rt/rust_task.cpp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-02-22 23:50:27 -0800
committerBrian Anderson <banderson@mozilla.com>2012-02-22 23:50:47 -0800
commitb5c7997ef588916e566c18ba91608454bc4ffaaf (patch)
tree00e12238b49663ac9d9a800120572852f6ae2499 /src/rt/rust_task.cpp
parentc16bfbe0c365b6d3f0c274a53bc1374822766e6b (diff)
downloadrust-b5c7997ef588916e566c18ba91608454bc4ffaaf.tar.gz
rust-b5c7997ef588916e566c18ba91608454bc4ffaaf.zip
rt: Switch to the C stack in reset_stack_limit
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index f8fd01d4a49..f2bb15796f2 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -687,6 +687,23 @@ sp_in_stk_seg(uintptr_t sp, stk_seg *stk) {
     return (uintptr_t)stk->data <= sp && sp <= stk->end;
 }
 
+struct reset_args {
+    rust_task *task;
+    uintptr_t sp;
+};
+
+void
+reset_stack_limit_on_c_stack(reset_args *args) {
+    rust_task *task = args->task;
+    uintptr_t sp = args->sp;
+    while (!sp_in_stk_seg(sp, task->stk)) {
+        task->del_stack();
+        A(task->thread, task->stk != NULL,
+          "Failed to find the current stack");
+    }
+    task->record_stack_limit();
+}
+
 /*
 Called by landing pads during unwinding to figure out which
 stack segment we are currently running on, delete the others,
@@ -695,12 +712,12 @@ through __morestack).
  */
 void
 rust_task::reset_stack_limit() {
+    I(thread, on_rust_stack());
     uintptr_t sp = get_sp();
-    while (!sp_in_stk_seg(sp, stk)) {
-        del_stack();
-        A(thread, stk != NULL, "Failed to find the current stack");
-    }
-    record_stack_limit();
+    // Have to do the rest on the C stack because it involves
+    // freeing stack segments, logging, etc.
+    reset_args ra = {this, sp};
+    call_on_c_stack(&ra, (void*)reset_stack_limit_on_c_stack);
 }
 
 void