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-03-03 17:15:51 -0800
committerBrian Anderson <banderson@mozilla.com>2012-03-05 19:39:56 -0800
commitcc276fe3c96965ba39b9fba3b588a1eaa3941d86 (patch)
treee0891c8a19fedf11797652052a6dbbcf3e45b2be /src/rt/rust_task.cpp
parentc78da1e17016d178d55d5f899ab254f5ed44a899 (diff)
downloadrust-cc276fe3c96965ba39b9fba3b588a1eaa3941d86.tar.gz
rust-cc276fe3c96965ba39b9fba3b588a1eaa3941d86.zip
rt: Be more precise with VALGRIND_MAKE_MEM_UNDEFINED
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index c6e0aa159da..71f4949888f 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -571,7 +571,6 @@ rust_task::new_stack(size_t requested_sz) {
             LOG(this, mem, "reusing existing stack");
             stk = stk->prev;
             A(thread, stk->prev == NULL, "Bogus stack ptr");
-            prepare_valgrind_stack(stk);
             return;
         } else {
             LOG(this, mem, "existing stack is not big enough");
@@ -637,12 +636,29 @@ rust_task::del_stack() {
 
 void *
 rust_task::next_stack(size_t stk_sz, void *args_addr, size_t args_sz) {
+    stk_seg *maybe_next_stack = NULL;
+    if (stk != NULL) {
+        maybe_next_stack = stk->prev;
+    }
+
     new_stack(stk_sz + args_sz);
     A(thread, stk->end - (uintptr_t)stk->data >= stk_sz + args_sz,
       "Did not receive enough stack");
     uint8_t *new_sp = (uint8_t*)stk->end;
     // Push the function arguments to the new stack
     new_sp = align_down(new_sp - args_sz);
+
+    // When reusing a stack segment we need to tell valgrind that this area of
+    // memory is accessible before writing to it, because the act of popping
+    // the stack previously made all of the stack inaccessible.
+    if (maybe_next_stack == stk) {
+        // I don't know exactly where the region ends that valgrind needs us
+        // to mark accessible. On x86_64 these extra bytes aren't needed, but
+        // on i386 we get errors without.
+        int fudge_bytes = 16;
+        reuse_valgrind_stack(stk, new_sp - fudge_bytes);
+    }
+
     memcpy(new_sp, args_addr, args_sz);
     A(thread, rust_task_thread::get_task() == this,
       "Recording the stack limit for the wrong thread");