about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-05-03 05:42:00 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-05-03 05:42:00 -0400
commit34024353e86e22e459a1981f563e3d4f43906432 (patch)
treeb9984481268376f1858195de87e354bd3793f7f8
parent9bded762601e47b16bd97ef4439536fb9d7af0cd (diff)
Change borrow debugging so it is disabled by -O
-rw-r--r--src/libcore/rt/env.rs2
-rw-r--r--src/libcore/unstable/lang.rs121
-rw-r--r--src/librustc/middle/lang_items.rs20
-rw-r--r--src/librustc/middle/trans/common.rs32
-rw-r--r--src/librustc/middle/trans/datum.rs24
-rw-r--r--src/rt/rust_env.cpp2
-rw-r--r--src/rt/rust_env.h1
7 files changed, 129 insertions, 73 deletions
diff --git a/src/libcore/rt/env.rs b/src/libcore/rt/env.rs
index 1f52cf77868..e479375401a 100644
--- a/src/libcore/rt/env.rs
+++ b/src/libcore/rt/env.rs
@@ -33,8 +33,6 @@ pub struct Environment {
     argv: **c_char,
     /// Print GC debugging info (true if env var RUST_DEBUG_MEM is set)
     debug_mem: bool,
-    /// Track origin of `@mut` borrows (true if env var RUST_DEBUG_BORROWS is set)
-    debug_borrows: bool
 }
 
 /// Get the global environment settings
diff --git a/src/libcore/unstable/lang.rs b/src/libcore/unstable/lang.rs
index a3e44b5feea..27fc3287bdb 100644
--- a/src/libcore/unstable/lang.rs
+++ b/src/libcore/unstable/lang.rs
@@ -19,7 +19,7 @@ use sys;
 use unstable::exchange_alloc;
 use cast::transmute;
 use task::rt::rust_get_task;
-use option::{Some, None};
+use option::{Option, Some, None};
 
 #[allow(non_camel_case_types)]
 pub type rust_task = c_void;
@@ -79,6 +79,19 @@ struct BorrowRecord {
     line: size_t
 }
 
+fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
+    unsafe {
+        let cur_task = rust_get_task();
+        let ptr = rustrt::rust_take_task_borrow_list(cur_task);
+        if ptr.is_null() {
+            None
+        } else {
+            let v: ~[BorrowRecord] = transmute(ptr);
+            Some(v)
+        }
+    }
+}
+
 fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
     unsafe {
         let cur_task = rust_get_task();
@@ -93,23 +106,20 @@ fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
 
 pub unsafe fn clear_task_borrow_list() {
     // pub because it is used by the box annihilator.
-    let cur_task = rust_get_task();
-    let ptr = rustrt::rust_take_task_borrow_list(cur_task);
-    if !ptr.is_null() {
-        let _: ~[BorrowRecord] = transmute(ptr);
-    }
+    let _ = try_take_task_borrow_list();
 }
 
 fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
     debug_ptr("fail_borrowed: ", box);
 
-    if !::rt::env::get().debug_borrows {
-        let msg = "borrowed";
-        do str::as_buf(msg) |msg_p, _| {
-            fail_(msg_p as *c_char, file, line);
+    match try_take_task_borrow_list() {
+        None => { // not recording borrows
+            let msg = "borrowed";
+            do str::as_buf(msg) |msg_p, _| {
+                fail_(msg_p as *c_char, file, line);
+            }
         }
-    } else {
-        do swap_task_borrow_list |borrow_list| {
+        Some(borrow_list) => { // recording borrows
             let mut msg = ~"borrowed";
             let mut sep = " at ";
             for borrow_list.each_reverse |entry| {
@@ -126,7 +136,6 @@ fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
             do str::as_buf(msg) |msg_p, _| {
                 fail_(msg_p as *c_char, file, line)
             }
-            borrow_list
         }
     }
 }
@@ -211,34 +220,6 @@ pub unsafe fn borrow_as_imm(a: *u8) {
     (*a).header.ref_count |= FROZEN_BIT;
 }
 
-fn add_borrow_to_task_list(a: *mut BoxRepr, file: *c_char, line: size_t) {
-    do swap_task_borrow_list |borrow_list| {
-        let mut borrow_list = borrow_list;
-        borrow_list.push(BorrowRecord {box: a, file: file, line: line});
-        borrow_list
-    }
-}
-
-fn remove_borrow_from_task_list(a: *mut BoxRepr, file: *c_char, line: size_t) {
-    do swap_task_borrow_list |borrow_list| {
-        let mut borrow_list = borrow_list;
-        let br = BorrowRecord {box: a, file: file, line: line};
-        match borrow_list.rposition_elem(&br) {
-            Some(idx) => {
-                borrow_list.remove(idx);
-                borrow_list
-            }
-            None => {
-                let err = fmt!("no borrow found, br=%?, borrow_list=%?",
-                               br, borrow_list);
-                do str::as_buf(err) |msg_p, _| {
-                    fail_(msg_p as *c_char, file, line)
-                }
-            }
-        }
-    }
-}
-
 #[cfg(not(stage0))]
 #[lang="borrow_as_imm"]
 #[inline(always)]
@@ -252,12 +233,8 @@ pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
 
     if (ref_count & MUT_BIT) != 0 {
         fail_borrowed(a, file, line);
-    } else {
-        (*a).header.ref_count |= FROZEN_BIT;
-        if ::rt::env::get().debug_borrows {
-            add_borrow_to_task_list(a, file, line);
-        }
     }
+
     ref_count
 }
 
@@ -273,15 +250,53 @@ pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
     let ref_count = (*a).header.ref_count;
     if (ref_count & (MUT_BIT|FROZEN_BIT)) != 0 {
         fail_borrowed(a, file, line);
-    } else {
-        (*a).header.ref_count |= (MUT_BIT|FROZEN_BIT);
-        if ::rt::env::get().debug_borrows {
-            add_borrow_to_task_list(a, file, line);
-        }
     }
     ref_count
 }
 
+
+#[cfg(not(stage0))]
+#[lang="record_borrow"]
+pub unsafe fn record_borrow(a: *u8, old_ref_count: uint,
+                            file: *c_char, line: size_t) {
+    if (old_ref_count & ALL_BITS) == 0 {
+        // was not borrowed before
+        let a: *mut BoxRepr = transmute(a);
+        do swap_task_borrow_list |borrow_list| {
+            let mut borrow_list = borrow_list;
+            borrow_list.push(BorrowRecord {box: a, file: file, line: line});
+            borrow_list
+        }
+    }
+}
+
+#[cfg(not(stage0))]
+#[lang="unrecord_borrow"]
+pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
+                              file: *c_char, line: size_t) {
+    if (old_ref_count & ALL_BITS) == 0 {
+        // was not borrowed before
+        let a: *mut BoxRepr = transmute(a);
+        do swap_task_borrow_list |borrow_list| {
+            let mut borrow_list = borrow_list;
+            let br = BorrowRecord {box: a, file: file, line: line};
+            match borrow_list.rposition_elem(&br) {
+                Some(idx) => {
+                    borrow_list.remove(idx);
+                    borrow_list
+                }
+                None => {
+                    let err = fmt!("no borrow found, br=%?, borrow_list=%?",
+                                   br, borrow_list);
+                    do str::as_buf(err) |msg_p, _| {
+                        fail_(msg_p as *c_char, file, line)
+                    }
+                }
+            }
+        }
+    }
+}
+
 #[cfg(stage0)]
 #[lang="return_to_mut"]
 #[inline(always)]
@@ -312,10 +327,6 @@ pub unsafe fn return_to_mut(a: *u8, old_ref_count: uint,
         debug_ptr("              (old) : ", old_ref_count as *());
         debug_ptr("              (new) : ", ref_count as *());
         debug_ptr("              (comb): ", combined as *());
-
-        if ::rt::env::get().debug_borrows {
-            remove_borrow_from_task_list(a, file, line);
-        }
     }
 }
 
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 314b58d13e1..448f33796bc 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -70,18 +70,20 @@ pub enum LangItem {
     ReturnToMutFnLangItem,      // 32
     CheckNotBorrowedFnLangItem, // 33
     StrDupUniqFnLangItem,       // 34
+    RecordBorrowFnLangItem,     // 35
+    UnrecordBorrowFnLangItem,   // 36
 
-    StartFnLangItem,            // 35
+    StartFnLangItem,            // 37
 }
 
 pub struct LanguageItems {
-    items: [Option<def_id>, ..36]
+    items: [Option<def_id>, ..38]
 }
 
 pub impl LanguageItems {
     pub fn new() -> LanguageItems {
         LanguageItems {
-            items: [ None, ..36 ]
+            items: [ None, ..38 ]
         }
     }
 
@@ -133,8 +135,10 @@ pub impl LanguageItems {
             32 => "return_to_mut",
             33 => "check_not_borrowed",
             34 => "strdup_uniq",
+            35 => "record_borrow",
+            36 => "unrecord_borrow",
 
-            35 => "start",
+            37 => "start",
 
             _ => "???"
         }
@@ -251,6 +255,12 @@ pub impl LanguageItems {
     pub fn strdup_uniq_fn(&const self) -> def_id {
         self.items[StrDupUniqFnLangItem as uint].get()
     }
+    pub fn record_borrow_fn(&const self) -> def_id {
+        self.items[RecordBorrowFnLangItem as uint].get()
+    }
+    pub fn unrecord_borrow_fn(&const self) -> def_id {
+        self.items[UnrecordBorrowFnLangItem as uint].get()
+    }
     pub fn start_fn(&const self) -> def_id {
         self.items[StartFnLangItem as uint].get()
     }
@@ -302,6 +312,8 @@ fn LanguageItemCollector(crate: @crate,
     item_refs.insert(@~"check_not_borrowed",
                      CheckNotBorrowedFnLangItem as uint);
     item_refs.insert(@~"strdup_uniq", StrDupUniqFnLangItem as uint);
+    item_refs.insert(@~"record_borrow", RecordBorrowFnLangItem as uint);
+    item_refs.insert(@~"unrecord_borrow", UnrecordBorrowFnLangItem as uint);
     item_refs.insert(@~"start", StartFnLangItem as uint);
 
     LanguageItemCollector {
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 705a89381df..2a13cf73f8b 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -489,15 +489,37 @@ pub fn add_clean_return_to_mut(bcx: block,
             clean_temp(
                 frozen_val_ref,
                 |bcx| {
+                    let mut bcx = bcx;
+
+                    let box_ptr =
+                        build::Load(bcx,
+                                    build::PointerCast(bcx,
+                                                       frozen_val_ref,
+                                                       T_ptr(T_ptr(T_i8()))));
+
+                    let bits_val =
+                        build::Load(bcx,
+                                    bits_val_ref);
+
+                    if bcx.tcx().sess.opts.optimize == session::No {
+                        bcx = callee::trans_lang_call(
+                            bcx,
+                            bcx.tcx().lang_items.unrecord_borrow_fn(),
+                            ~[
+                                box_ptr,
+                                bits_val,
+                                filename_val,
+                                line_val
+                            ],
+                            expr::Ignore);
+                    }
+
                     callee::trans_lang_call(
                         bcx,
                         bcx.tcx().lang_items.return_to_mut_fn(),
                         ~[
-                            build::Load(bcx,
-                                        build::PointerCast(bcx,
-                                                           frozen_val_ref,
-                                                           T_ptr(T_ptr(T_i8())))),
-                            build::Load(bcx, bits_val_ref),
+                            box_ptr,
+                            bits_val,
                             filename_val,
                             line_val
                         ],
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index d6df6c87dec..af7165c53a7 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -101,6 +101,7 @@ use middle::trans::type_of;
 use middle::ty;
 use util::common::indenter;
 use util::ppaux::ty_to_str;
+use driver::session;
 
 use core::container::Set; // XXX: this should not be necessary
 use core::to_bytes;
@@ -564,19 +565,34 @@ pub impl Datum {
                     DynaMut => bcx.tcx().lang_items.borrow_as_mut_fn(),
                 };
 
+                let box_ptr = Load(bcx,
+                                   PointerCast(bcx,
+                                               scratch.val,
+                                               T_ptr(T_ptr(T_i8()))));
+
                 bcx = callee::trans_lang_call(
                     bcx,
                     freeze_did,
                     ~[
-                        Load(bcx,
-                             PointerCast(bcx,
-                                         scratch.val,
-                                         T_ptr(T_ptr(T_i8())))),
+                        box_ptr,
                         filename,
                         line
                     ],
                     expr::SaveIn(scratch_bits.val));
 
+                if bcx.tcx().sess.opts.optimize == session::No {
+                    bcx = callee::trans_lang_call(
+                        bcx,
+                        bcx.tcx().lang_items.record_borrow_fn(),
+                        ~[
+                            box_ptr,
+                            Load(bcx, scratch_bits.val),
+                            filename,
+                            line
+                        ],
+                        expr::Ignore);
+                }
+
                 add_clean_return_to_mut(
                     cleanup_bcx, scratch.val, scratch_bits.val,
                     filename, line);
diff --git a/src/rt/rust_env.cpp b/src/rt/rust_env.cpp
index e6fe35609ec..041b4efac52 100644
--- a/src/rt/rust_env.cpp
+++ b/src/rt/rust_env.cpp
@@ -24,7 +24,6 @@
 #define RUST_SEED "RUST_SEED"
 #define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE"
 #define RUST_DEBUG_MEM "RUST_DEBUG_MEM"
-#define RUST_DEBUG_BORROWS "RUST_DEBUG_BORROWS"
 
 #if defined(__WIN32__)
 static int
@@ -131,7 +130,6 @@ load_env(int argc, char **argv) {
     env->argc = argc;
     env->argv = argv;
     env->debug_mem = getenv(RUST_DEBUG_MEM) != NULL;
-    env->debug_borrows = getenv(RUST_DEBUG_BORROWS) != NULL;
     return env;
 }
 
diff --git a/src/rt/rust_env.h b/src/rt/rust_env.h
index 322198bb031..df27f7674f2 100644
--- a/src/rt/rust_env.h
+++ b/src/rt/rust_env.h
@@ -28,7 +28,6 @@ struct rust_env {
     int argc;
     char **argv;
     rust_bool debug_mem;
-    rust_bool debug_borrows;
 };
 
 rust_env* load_env(int argc, char **argv);