Skip to content

Commit 8143272

Browse files
committed
---
yaml --- r: 58626 b: refs/heads/try c: 4af2d90 h: refs/heads/master v: v3
1 parent 339e2cd commit 8143272

File tree

11 files changed

+122
-15
lines changed

11 files changed

+122
-15
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: c081ffbd1e845687202a975ea2e698b623e5722f
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 213f7b24ccd9a6833af7e1a329c5e7ffc8f9e3d2
5-
refs/heads/try: 84861101eca12942b42f36f8adb18cfc74515431
5+
refs/heads/try: 4af2d90af59bb5e28e5d114d8a6004d68fad3bd5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libcore/rt/env.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ pub struct Environment {
3131
argc: c_int,
3232
/// The argv value passed to main
3333
argv: **c_char,
34-
/// Print GC debugging info
35-
debug_mem: bool
34+
/// Print GC debugging info (true if env var RUST_DEBUG_MEM is set)
35+
debug_mem: bool,
36+
/// Track origin of `@mut` borrows (true if env var RUST_DEBUG_BORROWS is set)
37+
debug_borrows: bool
3638
}
3739

3840
/// Get the global environment settings

branches/try/src/libcore/unstable/lang.rs

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use str;
1717
use sys;
1818
use unstable::exchange_alloc;
1919
use cast::transmute;
20+
use task::rt::rust_get_task;
2021

2122
#[allow(non_camel_case_types)]
2223
pub type rust_task = c_void;
@@ -27,7 +28,8 @@ pub static FROZEN_BIT: uint = 0x80000000;
2728
pub static FROZEN_BIT: uint = 0x8000000000000000;
2829

2930
pub mod rustrt {
30-
use libc::{c_char, uintptr_t};
31+
use unstable::lang::rust_task;
32+
use libc::{c_void, c_char, uintptr_t};
3133

3234
pub extern {
3335
#[rust_stack]
@@ -43,6 +45,12 @@ pub mod rustrt {
4345

4446
#[fast_ffi]
4547
unsafe fn rust_upcall_free_noswitch(ptr: *c_char);
48+
49+
#[rust_stack]
50+
fn rust_take_task_borrow_list(task: *rust_task) -> *c_void;
51+
52+
#[rust_stack]
53+
fn rust_set_task_borrow_list(task: *rust_task, map: *c_void);
4654
}
4755
}
4856

@@ -61,10 +69,50 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
6169
}
6270
}
6371

64-
pub fn fail_borrowed(file: *c_char, line: size_t) {
65-
let msg = "borrowed";
66-
do str::as_buf(msg) |msg_p, _| {
67-
fail_(msg_p as *c_char, file, line);
72+
struct BorrowRecord {
73+
box: *mut BoxRepr,
74+
file: *c_char,
75+
line: size_t
76+
}
77+
78+
fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
79+
unsafe {
80+
let cur_task = rust_get_task();
81+
let mut borrow_list: ~[BorrowRecord] = {
82+
let ptr = rustrt::rust_take_task_borrow_list(cur_task);
83+
if ptr.is_null() { ~[] } else { transmute(ptr) }
84+
};
85+
borrow_list = f(borrow_list);
86+
rustrt::rust_set_task_borrow_list(cur_task, transmute(borrow_list));
87+
}
88+
}
89+
90+
pub fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
91+
if !::rt::env::get().debug_borrows {
92+
let msg = "borrowed";
93+
do str::as_buf(msg) |msg_p, _| {
94+
fail_(msg_p as *c_char, file, line);
95+
}
96+
} else {
97+
do swap_task_borrow_list |borrow_list| {
98+
let mut msg = ~"borrowed";
99+
let mut sep = " at ";
100+
for borrow_list.each_reverse |entry| {
101+
if entry.box == box {
102+
str::push_str(&mut msg, sep);
103+
let filename = unsafe {
104+
str::raw::from_c_str(entry.file)
105+
};
106+
str::push_str(&mut msg, filename);
107+
str::push_str(&mut msg, fmt!(":%u", line as uint));
108+
sep = " and at ";
109+
}
110+
}
111+
do str::as_buf(msg) |msg_p, _| {
112+
fail_(msg_p as *c_char, file, line)
113+
}
114+
borrow_list
115+
}
68116
}
69117
}
70118

@@ -140,13 +188,29 @@ pub unsafe fn local_free(ptr: *c_char) {
140188
rustrt::rust_upcall_free_noswitch(ptr);
141189
}
142190

191+
#[cfg(stage0)]
143192
#[lang="borrow_as_imm"]
144193
#[inline(always)]
145194
pub unsafe fn borrow_as_imm(a: *u8) {
146195
let a: *mut BoxRepr = transmute(a);
147196
(*a).header.ref_count |= FROZEN_BIT;
148197
}
149198

199+
#[cfg(not(stage0))]
200+
#[lang="borrow_as_imm"]
201+
#[inline(always)]
202+
pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) {
203+
let a: *mut BoxRepr = transmute(a);
204+
(*a).header.ref_count |= FROZEN_BIT;
205+
if ::rt::env::get().debug_borrows {
206+
do swap_task_borrow_list |borrow_list| {
207+
let mut borrow_list = borrow_list;
208+
borrow_list.push(BorrowRecord {box: a, file: file, line: line});
209+
borrow_list
210+
}
211+
}
212+
}
213+
150214
#[lang="return_to_mut"]
151215
#[inline(always)]
152216
pub unsafe fn return_to_mut(a: *u8) {
@@ -165,7 +229,7 @@ pub unsafe fn check_not_borrowed(a: *u8) {
165229
let a: *mut BoxRepr = transmute(a);
166230
if ((*a).header.ref_count & FROZEN_BIT) != 0 {
167231
do str::as_buf("XXX") |file_p, _| {
168-
fail_borrowed(file_p as *c_char, 0);
232+
fail_borrowed(a, file_p as *c_char, 0);
169233
}
170234
}
171235
}
@@ -178,7 +242,7 @@ pub unsafe fn check_not_borrowed(a: *u8,
178242
line: size_t) {
179243
let a: *mut BoxRepr = transmute(a);
180244
if ((*a).header.ref_count & FROZEN_BIT) != 0 {
181-
fail_borrowed(file, line);
245+
fail_borrowed(a, file, line);
182246
}
183247
}
184248

branches/try/src/librustc/middle/trans/_match.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ pub fn root_pats_as_necessary(bcx: block,
966966
967967
let datum = Datum {val: val, ty: node_id_type(bcx, pat_id),
968968
mode: ByRef, source: ZeroMem};
969-
bcx = datum.root(bcx, root_info);
969+
bcx = datum.root(bcx, br.pats[col].span, root_info);
970970
// If we kept going, we'd only re-root the same value, so
971971
// return now.
972972
return bcx;

branches/try/src/librustc/middle/trans/datum.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ pub impl Datum {
517517
}
518518
}
519519

520-
fn root(&self, bcx: block, root_info: RootInfo) -> block {
520+
fn root(&self, bcx: block, span: span, root_info: RootInfo) -> block {
521521
/*!
522522
*
523523
* In some cases, borrowck will decide that an @T/@[]/@str
@@ -542,14 +542,22 @@ pub impl Datum {
542542
// If we need to freeze the box, do that now.
543543
if root_info.freeze.is_some() {
544544
// NOTE distinguish the two kinds of freezing here
545+
546+
let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo);
547+
let line = C_int(bcx.ccx(), loc.line as int);
548+
let filename_cstr = C_cstr(bcx.ccx(), @/*bad*/copy loc.file.name);
549+
let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8()));
550+
545551
callee::trans_lang_call(
546552
bcx,
547553
bcx.tcx().lang_items.borrow_as_imm_fn(),
548554
~[
549555
Load(bcx,
550556
PointerCast(bcx,
551557
scratch.val,
552-
T_ptr(T_ptr(T_i8()))))
558+
T_ptr(T_ptr(T_i8())))),
559+
filename,
560+
line
553561
],
554562
expr::Ignore)
555563
} else {
@@ -647,7 +655,7 @@ pub impl Datum {
647655
let key = root_map_key { id: expr_id, derefs: derefs };
648656
let bcx = match ccx.maps.root_map.find(&key) {
649657
None => bcx,
650-
Some(&root_info) => self.root(bcx, root_info)
658+
Some(&root_info) => self.root(bcx, span, root_info)
651659
};
652660

653661
// Perform the write guard, if necessary.

branches/try/src/librustc/middle/trans/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
828828
// at the end of the scope with id `scope_id`:
829829
let root_key = root_map_key { id: expr.id, derefs: 0u };
830830
for bcx.ccx().maps.root_map.find(&root_key).each |&root_info| {
831-
bcx = unrooted_datum.root(bcx, *root_info);
831+
bcx = unrooted_datum.root(bcx, expr.span, *root_info);
832832
}
833833

834834
return DatumBlock {bcx: bcx, datum: unrooted_datum};

branches/try/src/rt/rust_builtin.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,20 @@ rust_task_local_data_atexit(rust_task *task, void (*cleanup_fn)(void *data)) {
683683
task->task_local_data_cleanup = cleanup_fn;
684684
}
685685

686+
// set/get/atexit task_borrow_list can run on the rust stack for speed.
687+
extern "C" void *
688+
rust_take_task_borrow_list(rust_task *task) {
689+
void *r = task->borrow_list;
690+
task->borrow_list = NULL;
691+
return r;
692+
}
693+
extern "C" void
694+
rust_set_task_borrow_list(rust_task *task, void *data) {
695+
assert(task->borrow_list == NULL);
696+
assert(data != NULL);
697+
task->borrow_list = data;
698+
}
699+
686700
extern "C" void
687701
task_clear_event_reject(rust_task *task) {
688702
task->clear_event_reject();

branches/try/src/rt/rust_env.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#define RUST_SEED "RUST_SEED"
2525
#define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE"
2626
#define RUST_DEBUG_MEM "RUST_DEBUG_MEM"
27+
#define RUST_DEBUG_BORROWS "RUST_DEBUG_BORROWS"
2728

2829
#if defined(__WIN32__)
2930
static int
@@ -130,6 +131,7 @@ load_env(int argc, char **argv) {
130131
env->argc = argc;
131132
env->argv = argv;
132133
env->debug_mem = getenv(RUST_DEBUG_MEM) != NULL;
134+
env->debug_borrows = getenv(RUST_DEBUG_BORROWS) != NULL;
133135
return env;
134136
}
135137

branches/try/src/rt/rust_env.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct rust_env {
2828
int argc;
2929
char **argv;
3030
rust_bool debug_mem;
31+
rust_bool debug_borrows;
3132
};
3233

3334
rust_env* load_env(int argc, char **argv);

branches/try/src/rt/rust_task.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ rust_task::rust_task(rust_sched_loop *sched_loop, rust_task_state state,
4242
total_stack_sz(0),
4343
task_local_data(NULL),
4444
task_local_data_cleanup(NULL),
45+
borrow_list(NULL),
4546
state(state),
4647
cond(NULL),
4748
cond_name("none"),
@@ -75,6 +76,16 @@ rust_task::delete_this()
7576
assert(ref_count == 0); // ||
7677
// (ref_count == 1 && this == sched->root_task));
7778

79+
if (borrow_list) {
80+
// NOTE should free borrow_list from within rust code!
81+
// If there is a pointer in there, it is a ~[BorrowRecord] pointer,
82+
// which are currently allocated with LIBC malloc/free. But this is
83+
// not really the right way to do this, we should be freeing this
84+
// pointer from Rust code.
85+
free(borrow_list);
86+
borrow_list = NULL;
87+
}
88+
7889
sched_loop->release_task(this);
7990
}
8091

branches/try/src/rt/rust_task.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ rust_task : public kernel_owned<rust_task>
241241
void *task_local_data;
242242
void (*task_local_data_cleanup)(void *data);
243243

244+
// Contains a ~[BorrowRecord] pointer, or NULL.
245+
//
246+
// Used by borrow management code in libcore/unstable/lang.rs.
247+
void *borrow_list;
248+
244249
private:
245250

246251
// Protects state, cond, cond_name

0 commit comments

Comments
 (0)