Skip to content

Commit 0f9ab93

Browse files
committed
std: Restore dynamic borrow tracking
1 parent 2ec9b8c commit 0f9ab93

File tree

4 files changed

+43
-17
lines changed

4 files changed

+43
-17
lines changed

src/libstd/cleanup.rs

-5
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ pub unsafe fn annihilate() {
7171
use io::WriterUtil;
7272
use io;
7373
use libc;
74-
use rt::borrowck;
7574
use sys;
7675
use managed;
7776

@@ -81,10 +80,6 @@ pub unsafe fn annihilate() {
8180
n_bytes_freed: 0
8281
};
8382

84-
// Quick hack: we need to free this list upon task exit, and this
85-
// is a convenient place to do it.
86-
borrowck::clear_task_borrow_list();
87-
8883
// Pass 1: Make all boxes immortal.
8984
//
9085
// In this pass, nothing gets freed, so it does not matter whether

src/libstd/rt/borrowck.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use cell::Cell;
1112
use c_str::ToCStr;
1213
use cast::transmute;
1314
use libc::{c_char, size_t, STDERR_FILENO};
1415
use io;
1516
use io::{Writer, WriterUtil};
1617
use option::{Option, None, Some};
1718
use uint;
19+
use rt::env;
20+
use rt::local::Local;
21+
use rt::task::Task;
1822
use str;
1923
use str::{OwnedStr, StrSlice};
2024
use sys;
@@ -26,22 +30,31 @@ pub static MUT_BIT: uint = 1 << (uint::bits - 2);
2630
static ALL_BITS: uint = FROZEN_BIT | MUT_BIT;
2731

2832
#[deriving(Eq)]
29-
struct BorrowRecord {
33+
pub struct BorrowRecord {
3034
box: *mut raw::Box<()>,
3135
file: *c_char,
3236
line: size_t
3337
}
3438

3539
fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
36-
// XXX
37-
None
40+
do Local::borrow::<Task, Option<~[BorrowRecord]>> |task| {
41+
task.borrow_list.take()
42+
}
3843
}
3944

40-
fn swap_task_borrow_list(_f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
41-
// XXX
45+
fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
46+
let borrows = match try_take_task_borrow_list() {
47+
Some(l) => l,
48+
None => ~[]
49+
};
50+
let borrows = f(borrows);
51+
let borrows = Cell::new(borrows);
52+
do Local::borrow::<Task, ()> |task| {
53+
task.borrow_list = Some(borrows.take());
54+
}
4255
}
4356

44-
pub unsafe fn clear_task_borrow_list() {
57+
pub fn clear_task_borrow_list() {
4558
// pub because it is used by the box annihilator.
4659
let _ = try_take_task_borrow_list();
4760
}
@@ -89,8 +102,7 @@ unsafe fn debug_borrow<T>(tag: &'static str,
89102
//! A useful debugging function that prints a pointer + tag + newline
90103
//! without allocating memory.
91104
92-
// XXX
93-
if false {
105+
if ENABLE_DEBUG && env::debug_borrow() {
94106
debug_borrow_slow(tag, p, old_bits, new_bits, filename, line);
95107
}
96108

src/libstd/rt/env.rs

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use os;
1818
// They are expected to be initialized once then left alone.
1919

2020
static mut MIN_STACK: uint = 2000000;
21+
static mut DEBUG_BORROW: bool = false;
2122

2223
pub fn init() {
2324
unsafe {
@@ -28,9 +29,17 @@ pub fn init() {
2829
},
2930
None => ()
3031
}
32+
match os::getenv("RUST_DEBUG_BORROW") {
33+
Some(_) => DEBUG_BORROW = true,
34+
None => ()
35+
}
3136
}
3237
}
3338

3439
pub fn min_stack() -> uint {
3540
unsafe { MIN_STACK }
3641
}
42+
43+
pub fn debug_borrow() -> bool {
44+
unsafe { DEBUG_BORROW }
45+
}

src/libstd/rt/task.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use libc::{c_void, uintptr_t};
2020
use ptr;
2121
use prelude::*;
2222
use option::{Option, Some, None};
23+
use rt::borrowck;
24+
use rt::borrowck::BorrowRecord;
2325
use rt::env;
2426
use rt::kill::Death;
2527
use rt::local::Local;
@@ -51,7 +53,9 @@ pub struct Task {
5153
name: Option<~str>,
5254
coroutine: Option<Coroutine>,
5355
sched: Option<~Scheduler>,
54-
task_type: TaskType
56+
task_type: TaskType,
57+
// Dynamic borrowck debugging info
58+
borrow_list: Option<~[BorrowRecord]>
5559
}
5660

5761
pub enum TaskType {
@@ -135,7 +139,8 @@ impl Task {
135139
coroutine: Some(Coroutine::empty()),
136140
name: None,
137141
sched: None,
138-
task_type: SchedTask
142+
task_type: SchedTask,
143+
borrow_list: None
139144
}
140145
}
141146

@@ -168,7 +173,8 @@ impl Task {
168173
name: None,
169174
coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
170175
sched: None,
171-
task_type: GreenTask(Some(~home))
176+
task_type: GreenTask(Some(~home)),
177+
borrow_list: None
172178
}
173179
}
174180

@@ -190,7 +196,8 @@ impl Task {
190196
name: None,
191197
coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
192198
sched: None,
193-
task_type: GreenTask(Some(~home))
199+
task_type: GreenTask(Some(~home)),
200+
borrow_list: None
194201
}
195202
}
196203

@@ -253,6 +260,9 @@ impl Task {
253260
}
254261
}
255262

263+
// Cleanup the dynamic borrowck debugging info
264+
borrowck::clear_task_borrow_list();
265+
256266
// NB. We pass the taskgroup into death so that it can be dropped while
257267
// the unkillable counter is set. This is necessary for when the
258268
// taskgroup destruction code drops references on KillHandles, which

0 commit comments

Comments
 (0)