mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-25 06:03:16 +00:00
std: Restore dynamic borrow tracking
This commit is contained in:
parent
2ec9b8ce2f
commit
0f9ab93642
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user