diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2013-05-01 21:46:34 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2013-05-01 21:47:09 -0400 |
| commit | 6210de9529f37bb4ff51050bca19dfd6f28026c9 (patch) | |
| tree | 75d79271bc55df772ff6a7e1116a9b807bb38f31 /src | |
| parent | d231c427e655b7164571a1a712563ba5fd2e4a3c (diff) | |
| download | rust-6210de9529f37bb4ff51050bca19dfd6f28026c9.tar.gz rust-6210de9529f37bb4ff51050bca19dfd6f28026c9.zip | |
lang: fix code for maintaining borrow list
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/unstable/lang.rs | 50 | ||||
| -rw-r--r-- | src/librustc/middle/trans/common.rs | 8 | ||||
| -rw-r--r-- | src/librustc/middle/trans/datum.rs | 3 |
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); } } |
