about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-08-11 18:54:23 -0700
committerBrian Anderson <banderson@mozilla.com>2013-08-19 20:39:39 -0700
commit0f9ab936423cfc427ff30e87efc7ca794fec8bcf (patch)
tree01a0efa5b80b7440f4eca606e506ea197687a9ab /src
parent2ec9b8ce2f08dd9b931bd084f83fd3a4d0c3e8c7 (diff)
downloadrust-0f9ab936423cfc427ff30e87efc7ca794fec8bcf.tar.gz
rust-0f9ab936423cfc427ff30e87efc7ca794fec8bcf.zip
std: Restore dynamic borrow tracking
Diffstat (limited to 'src')
-rw-r--r--src/libstd/cleanup.rs5
-rw-r--r--src/libstd/rt/borrowck.rs28
-rw-r--r--src/libstd/rt/env.rs9
-rw-r--r--src/libstd/rt/task.rs18
4 files changed, 43 insertions, 17 deletions
diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs
index 7c2348a3533..6a6ba12bae3 100644
--- a/src/libstd/cleanup.rs
+++ b/src/libstd/cleanup.rs
@@ -71,7 +71,6 @@ pub unsafe fn annihilate() {
     use io::WriterUtil;
     use io;
     use libc;
-    use rt::borrowck;
     use sys;
     use managed;
 
@@ -81,10 +80,6 @@ pub unsafe fn annihilate() {
         n_bytes_freed: 0
     };
 
-    // Quick hack: we need to free this list upon task exit, and this
-    // is a convenient place to do it.
-    borrowck::clear_task_borrow_list();
-
     // Pass 1: Make all boxes immortal.
     //
     // In this pass, nothing gets freed, so it does not matter whether
diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs
index 6400c1b660d..cbac43f27c7 100644
--- a/src/libstd/rt/borrowck.rs
+++ b/src/libstd/rt/borrowck.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use cell::Cell;
 use c_str::ToCStr;
 use cast::transmute;
 use libc::{c_char, size_t, STDERR_FILENO};
@@ -15,6 +16,9 @@ use io;
 use io::{Writer, WriterUtil};
 use option::{Option, None, Some};
 use uint;
+use rt::env;
+use rt::local::Local;
+use rt::task::Task;
 use str;
 use str::{OwnedStr, StrSlice};
 use sys;
@@ -26,22 +30,31 @@ pub static MUT_BIT: uint = 1 << (uint::bits - 2);
 static ALL_BITS: uint = FROZEN_BIT | MUT_BIT;
 
 #[deriving(Eq)]
-struct BorrowRecord {
+pub struct BorrowRecord {
     box: *mut raw::Box<()>,
     file: *c_char,
     line: size_t
 }
 
 fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
-    // XXX
-    None
+    do Local::borrow::<Task, Option<~[BorrowRecord]>> |task| {
+        task.borrow_list.take()
+    }
 }
 
-fn swap_task_borrow_list(_f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
-    // XXX
+fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
+    let borrows = match try_take_task_borrow_list() {
+        Some(l) => l,
+        None => ~[]
+    };
+    let borrows = f(borrows);
+    let borrows = Cell::new(borrows);
+    do Local::borrow::<Task, ()> |task| {
+        task.borrow_list = Some(borrows.take());
+    }
 }
 
-pub unsafe fn clear_task_borrow_list() {
+pub fn clear_task_borrow_list() {
     // pub because it is used by the box annihilator.
     let _ = try_take_task_borrow_list();
 }
@@ -89,8 +102,7 @@ unsafe fn debug_borrow<T>(tag: &'static str,
     //! A useful debugging function that prints a pointer + tag + newline
     //! without allocating memory.
 
-    // XXX
-    if false {
+    if ENABLE_DEBUG && env::debug_borrow() {
         debug_borrow_slow(tag, p, old_bits, new_bits, filename, line);
     }
 
diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs
index 3ca39acbfcd..5b840655120 100644
--- a/src/libstd/rt/env.rs
+++ b/src/libstd/rt/env.rs
@@ -18,6 +18,7 @@ use os;
 // They are expected to be initialized once then left alone.
 
 static mut MIN_STACK: uint = 2000000;
+static mut DEBUG_BORROW: bool = false;
 
 pub fn init() {
     unsafe {
@@ -28,9 +29,17 @@ pub fn init() {
             },
             None => ()
         }
+        match os::getenv("RUST_DEBUG_BORROW") {
+            Some(_) => DEBUG_BORROW = true,
+            None => ()
+        }
     }
 }
 
 pub fn min_stack() -> uint {
     unsafe { MIN_STACK }
 }
+
+pub fn debug_borrow() -> bool {
+    unsafe { DEBUG_BORROW }
+}
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 22d26005078..95d60c11df6 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -20,6 +20,8 @@ use libc::{c_void, uintptr_t};
 use ptr;
 use prelude::*;
 use option::{Option, Some, None};
+use rt::borrowck;
+use rt::borrowck::BorrowRecord;
 use rt::env;
 use rt::kill::Death;
 use rt::local::Local;
@@ -51,7 +53,9 @@ pub struct Task {
     name: Option<~str>,
     coroutine: Option<Coroutine>,
     sched: Option<~Scheduler>,
-    task_type: TaskType
+    task_type: TaskType,
+    // Dynamic borrowck debugging info
+    borrow_list: Option<~[BorrowRecord]>
 }
 
 pub enum TaskType {
@@ -135,7 +139,8 @@ impl Task {
             coroutine: Some(Coroutine::empty()),
             name: None,
             sched: None,
-            task_type: SchedTask
+            task_type: SchedTask,
+            borrow_list: None
         }
     }
 
@@ -168,7 +173,8 @@ impl Task {
             name: None,
             coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
             sched: None,
-            task_type: GreenTask(Some(~home))
+            task_type: GreenTask(Some(~home)),
+            borrow_list: None
         }
     }
 
@@ -190,7 +196,8 @@ impl Task {
             name: None,
             coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
             sched: None,
-            task_type: GreenTask(Some(~home))
+            task_type: GreenTask(Some(~home)),
+            borrow_list: None
         }
     }
 
@@ -253,6 +260,9 @@ impl Task {
             }
         }
 
+        // Cleanup the dynamic borrowck debugging info
+        borrowck::clear_task_borrow_list();
+
         // NB. We pass the taskgroup into death so that it can be dropped while
         // the unkillable counter is set. This is necessary for when the
         // taskgroup destruction code drops references on KillHandles, which