Change borrow debugging so it is disabled by -O
This commit is contained in:
@@ -33,8 +33,6 @@ pub struct Environment {
|
|||||||
argv: **c_char,
|
argv: **c_char,
|
||||||
/// Print GC debugging info (true if env var RUST_DEBUG_MEM is set)
|
/// Print GC debugging info (true if env var RUST_DEBUG_MEM is set)
|
||||||
debug_mem: bool,
|
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
|
/// Get the global environment settings
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use sys;
|
|||||||
use unstable::exchange_alloc;
|
use unstable::exchange_alloc;
|
||||||
use cast::transmute;
|
use cast::transmute;
|
||||||
use task::rt::rust_get_task;
|
use task::rt::rust_get_task;
|
||||||
use option::{Some, None};
|
use option::{Option, Some, None};
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub type rust_task = c_void;
|
pub type rust_task = c_void;
|
||||||
@@ -79,6 +79,19 @@ struct BorrowRecord {
|
|||||||
line: size_t
|
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]) {
|
fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let cur_task = rust_get_task();
|
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 unsafe fn clear_task_borrow_list() {
|
||||||
// pub because it is used by the box annihilator.
|
// pub because it is used by the box annihilator.
|
||||||
let cur_task = rust_get_task();
|
let _ = try_take_task_borrow_list();
|
||||||
let ptr = rustrt::rust_take_task_borrow_list(cur_task);
|
|
||||||
if !ptr.is_null() {
|
|
||||||
let _: ~[BorrowRecord] = transmute(ptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
|
fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
|
||||||
debug_ptr("fail_borrowed: ", box);
|
debug_ptr("fail_borrowed: ", box);
|
||||||
|
|
||||||
if !::rt::env::get().debug_borrows {
|
match try_take_task_borrow_list() {
|
||||||
let msg = "borrowed";
|
None => { // not recording borrows
|
||||||
do str::as_buf(msg) |msg_p, _| {
|
let msg = "borrowed";
|
||||||
fail_(msg_p as *c_char, file, line);
|
do str::as_buf(msg) |msg_p, _| {
|
||||||
|
fail_(msg_p as *c_char, file, line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
Some(borrow_list) => { // recording borrows
|
||||||
do swap_task_borrow_list |borrow_list| {
|
|
||||||
let mut msg = ~"borrowed";
|
let mut msg = ~"borrowed";
|
||||||
let mut sep = " at ";
|
let mut sep = " at ";
|
||||||
for borrow_list.each_reverse |entry| {
|
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, _| {
|
do str::as_buf(msg) |msg_p, _| {
|
||||||
fail_(msg_p as *c_char, file, line)
|
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;
|
(*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))]
|
#[cfg(not(stage0))]
|
||||||
#[lang="borrow_as_imm"]
|
#[lang="borrow_as_imm"]
|
||||||
#[inline(always)]
|
#[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 {
|
if (ref_count & MUT_BIT) != 0 {
|
||||||
fail_borrowed(a, file, line);
|
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
|
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;
|
let ref_count = (*a).header.ref_count;
|
||||||
if (ref_count & (MUT_BIT|FROZEN_BIT)) != 0 {
|
if (ref_count & (MUT_BIT|FROZEN_BIT)) != 0 {
|
||||||
fail_borrowed(a, file, line);
|
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
|
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)]
|
#[cfg(stage0)]
|
||||||
#[lang="return_to_mut"]
|
#[lang="return_to_mut"]
|
||||||
#[inline(always)]
|
#[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(" (old) : ", old_ref_count as *());
|
||||||
debug_ptr(" (new) : ", ref_count as *());
|
debug_ptr(" (new) : ", ref_count as *());
|
||||||
debug_ptr(" (comb): ", combined as *());
|
debug_ptr(" (comb): ", combined as *());
|
||||||
|
|
||||||
if ::rt::env::get().debug_borrows {
|
|
||||||
remove_borrow_from_task_list(a, file, line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,18 +70,20 @@ pub enum LangItem {
|
|||||||
ReturnToMutFnLangItem, // 32
|
ReturnToMutFnLangItem, // 32
|
||||||
CheckNotBorrowedFnLangItem, // 33
|
CheckNotBorrowedFnLangItem, // 33
|
||||||
StrDupUniqFnLangItem, // 34
|
StrDupUniqFnLangItem, // 34
|
||||||
|
RecordBorrowFnLangItem, // 35
|
||||||
|
UnrecordBorrowFnLangItem, // 36
|
||||||
|
|
||||||
StartFnLangItem, // 35
|
StartFnLangItem, // 37
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LanguageItems {
|
pub struct LanguageItems {
|
||||||
items: [Option<def_id>, ..36]
|
items: [Option<def_id>, ..38]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl LanguageItems {
|
pub impl LanguageItems {
|
||||||
pub fn new() -> LanguageItems {
|
pub fn new() -> LanguageItems {
|
||||||
LanguageItems {
|
LanguageItems {
|
||||||
items: [ None, ..36 ]
|
items: [ None, ..38 ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,8 +135,10 @@ pub impl LanguageItems {
|
|||||||
32 => "return_to_mut",
|
32 => "return_to_mut",
|
||||||
33 => "check_not_borrowed",
|
33 => "check_not_borrowed",
|
||||||
34 => "strdup_uniq",
|
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 {
|
pub fn strdup_uniq_fn(&const self) -> def_id {
|
||||||
self.items[StrDupUniqFnLangItem as uint].get()
|
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 {
|
pub fn start_fn(&const self) -> def_id {
|
||||||
self.items[StartFnLangItem as uint].get()
|
self.items[StartFnLangItem as uint].get()
|
||||||
}
|
}
|
||||||
@@ -302,6 +312,8 @@ fn LanguageItemCollector(crate: @crate,
|
|||||||
item_refs.insert(@~"check_not_borrowed",
|
item_refs.insert(@~"check_not_borrowed",
|
||||||
CheckNotBorrowedFnLangItem as uint);
|
CheckNotBorrowedFnLangItem as uint);
|
||||||
item_refs.insert(@~"strdup_uniq", StrDupUniqFnLangItem 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);
|
item_refs.insert(@~"start", StartFnLangItem as uint);
|
||||||
|
|
||||||
LanguageItemCollector {
|
LanguageItemCollector {
|
||||||
|
|||||||
@@ -489,15 +489,37 @@ pub fn add_clean_return_to_mut(bcx: block,
|
|||||||
clean_temp(
|
clean_temp(
|
||||||
frozen_val_ref,
|
frozen_val_ref,
|
||||||
|bcx| {
|
|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(
|
callee::trans_lang_call(
|
||||||
bcx,
|
bcx,
|
||||||
bcx.tcx().lang_items.return_to_mut_fn(),
|
bcx.tcx().lang_items.return_to_mut_fn(),
|
||||||
~[
|
~[
|
||||||
build::Load(bcx,
|
box_ptr,
|
||||||
build::PointerCast(bcx,
|
bits_val,
|
||||||
frozen_val_ref,
|
|
||||||
T_ptr(T_ptr(T_i8())))),
|
|
||||||
build::Load(bcx, bits_val_ref),
|
|
||||||
filename_val,
|
filename_val,
|
||||||
line_val
|
line_val
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ use middle::trans::type_of;
|
|||||||
use middle::ty;
|
use middle::ty;
|
||||||
use util::common::indenter;
|
use util::common::indenter;
|
||||||
use util::ppaux::ty_to_str;
|
use util::ppaux::ty_to_str;
|
||||||
|
use driver::session;
|
||||||
|
|
||||||
use core::container::Set; // XXX: this should not be necessary
|
use core::container::Set; // XXX: this should not be necessary
|
||||||
use core::to_bytes;
|
use core::to_bytes;
|
||||||
@@ -564,19 +565,34 @@ pub impl Datum {
|
|||||||
DynaMut => bcx.tcx().lang_items.borrow_as_mut_fn(),
|
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 = callee::trans_lang_call(
|
||||||
bcx,
|
bcx,
|
||||||
freeze_did,
|
freeze_did,
|
||||||
~[
|
~[
|
||||||
Load(bcx,
|
box_ptr,
|
||||||
PointerCast(bcx,
|
|
||||||
scratch.val,
|
|
||||||
T_ptr(T_ptr(T_i8())))),
|
|
||||||
filename,
|
filename,
|
||||||
line
|
line
|
||||||
],
|
],
|
||||||
expr::SaveIn(scratch_bits.val));
|
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(
|
add_clean_return_to_mut(
|
||||||
cleanup_bcx, scratch.val, scratch_bits.val,
|
cleanup_bcx, scratch.val, scratch_bits.val,
|
||||||
filename, line);
|
filename, line);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#define RUST_SEED "RUST_SEED"
|
#define RUST_SEED "RUST_SEED"
|
||||||
#define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE"
|
#define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE"
|
||||||
#define RUST_DEBUG_MEM "RUST_DEBUG_MEM"
|
#define RUST_DEBUG_MEM "RUST_DEBUG_MEM"
|
||||||
#define RUST_DEBUG_BORROWS "RUST_DEBUG_BORROWS"
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
static int
|
static int
|
||||||
@@ -131,7 +130,6 @@ load_env(int argc, char **argv) {
|
|||||||
env->argc = argc;
|
env->argc = argc;
|
||||||
env->argv = argv;
|
env->argv = argv;
|
||||||
env->debug_mem = getenv(RUST_DEBUG_MEM) != NULL;
|
env->debug_mem = getenv(RUST_DEBUG_MEM) != NULL;
|
||||||
env->debug_borrows = getenv(RUST_DEBUG_BORROWS) != NULL;
|
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ struct rust_env {
|
|||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
rust_bool debug_mem;
|
rust_bool debug_mem;
|
||||||
rust_bool debug_borrows;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
rust_env* load_env(int argc, char **argv);
|
rust_env* load_env(int argc, char **argv);
|
||||||
|
|||||||
Reference in New Issue
Block a user