about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-05-01 21:46:34 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-05-01 21:47:09 -0400
commit6210de9529f37bb4ff51050bca19dfd6f28026c9 (patch)
tree75d79271bc55df772ff6a7e1116a9b807bb38f31 /src
parentd231c427e655b7164571a1a712563ba5fd2e4a3c (diff)
downloadrust-6210de9529f37bb4ff51050bca19dfd6f28026c9.tar.gz
rust-6210de9529f37bb4ff51050bca19dfd6f28026c9.zip
lang: fix code for maintaining borrow list
Diffstat (limited to 'src')
-rw-r--r--src/libcore/unstable/lang.rs50
-rw-r--r--src/librustc/middle/trans/common.rs8
-rw-r--r--src/librustc/middle/trans/datum.rs3
3 files changed, 48 insertions, 13 deletions
diff --git a/src/libcore/unstable/lang.rs b/src/libcore/unstable/lang.rs
index 283f2329649..017fc4b7b63 100644
--- a/src/libcore/unstable/lang.rs
+++ b/src/libcore/unstable/lang.rs
@@ -19,6 +19,7 @@ use sys;
 use unstable::exchange_alloc;
 use cast::transmute;
 use task::rt::rust_get_task;
+use option::{Some, None};
 
 #[allow(non_camel_case_types)]
 pub type rust_task = c_void;
@@ -71,6 +72,7 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
     }
 }
 
+#[deriving(Eq)]
 struct BorrowRecord {
     box: *mut BoxRepr,
     file: *c_char,
@@ -108,7 +110,7 @@ pub fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
                         str::raw::from_c_str(entry.file)
                     };
                     str::push_str(&mut msg, filename);
-                    str::push_str(&mut msg, fmt!(":%u", line as uint));
+                    str::push_str(&mut msg, fmt!(":%u", entry.line as uint));
                     sep = " and at ";
                 }
             }
@@ -208,6 +210,26 @@ fn add_borrow_to_task_list(a: *mut BoxRepr, file: *c_char, line: size_t) {
     }
 }
 
+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)]
@@ -215,8 +237,9 @@ pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
     let a: *mut BoxRepr = transmute(a);
     let ref_count = (*a).header.ref_count;
 
-    debug_ptr("borrow_as_imm (ptr): ", a);
-    debug_ptr("borrow_as_imm (ref): ", ref_count as *());
+    debug_ptr("borrow_as_imm (ptr) :", a);
+    debug_ptr("              (ref) :", ref_count as *());
+    debug_ptr("              (line): ", line as *());
 
     if (ref_count & MUT_BIT) != 0 {
         fail_borrowed(a, file, line);
@@ -236,7 +259,7 @@ pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
     let a: *mut BoxRepr = transmute(a);
 
     debug_ptr("borrow_as_mut (ptr): ", a);
-    debug_ptr("borrow_as_mut (line): ", line as *());
+    debug_ptr("              (line): ", line as *());
 
     let ref_count = (*a).header.ref_count;
     if (ref_count & (MUT_BIT|FROZEN_BIT)) != 0 {
@@ -265,18 +288,25 @@ pub unsafe fn return_to_mut(a: *u8) {
 #[cfg(not(stage0))]
 #[lang="return_to_mut"]
 #[inline(always)]
-pub unsafe fn return_to_mut(a: *u8, old_ref_count: uint) {
+pub unsafe fn return_to_mut(a: *u8, old_ref_count: uint,
+                            file: *c_char, line: size_t) {
     // Sometimes the box is null, if it is conditionally frozen.
     // See e.g. #4904.
     if !a.is_null() {
         let a: *mut BoxRepr = transmute(a);
+        let ref_count = (*a).header.ref_count;
+        let combined = (ref_count & !ALL_BITS) | (old_ref_count & ALL_BITS);
+        (*a).header.ref_count = combined;
 
-        debug_ptr("return_to_mut (ptr): ", a);
-        debug_ptr("return_to_mut (ref): ", old_ref_count as *());
+        debug_ptr("return_to_mut (ptr) : ", a);
+        debug_ptr("              (line): ", line as *());
+        debug_ptr("              (old) : ", old_ref_count as *());
+        debug_ptr("              (new) : ", ref_count as *());
+        debug_ptr("              (comb): ", combined as *());
 
-        let ref_count = (*a).header.ref_count & !ALL_BITS;
-        let old_bits = old_ref_count & ALL_BITS;
-        (*a).header.ref_count = ref_count | old_bits;
+        if ::rt::env::get().debug_borrows {
+            remove_borrow_from_task_list(a, file, line);
+        }
     }
 }
 
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index d0da8a2e1ee..dba9ddd2b1d 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -469,7 +469,9 @@ pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) {
 }
 pub fn add_clean_return_to_mut(bcx: block,
                                frozen_val_ref: ValueRef,
-                               bits_val_ref: ValueRef) {
+                               bits_val_ref: ValueRef,
+                               filename_val: ValueRef,
+                               line_val: ValueRef) {
     //! When an `@mut` has been frozen, we have to
     //! call the lang-item `return_to_mut` when the
     //! freeze goes out of scope. We need to pass
@@ -495,7 +497,9 @@ pub fn add_clean_return_to_mut(bcx: block,
                                         build::PointerCast(bcx,
                                                            frozen_val_ref,
                                                            T_ptr(T_ptr(T_i8())))),
-                            build::Load(bcx, bits_val_ref)
+                            build::Load(bcx, bits_val_ref),
+                            filename_val,
+                            line_val
                         ],
                         expr::Ignore
                     )
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index f4fb3b6c6f5..d6df6c87dec 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -578,7 +578,8 @@ pub impl Datum {
                     expr::SaveIn(scratch_bits.val));
 
                 add_clean_return_to_mut(
-                    cleanup_bcx, scratch.val, scratch_bits.val);
+                    cleanup_bcx, scratch.val, scratch_bits.val,
+                    filename, line);
             }
         }