Skip to content

Commit a896440

Browse files
committed
new borrow checker (mass squash)
1 parent b5a7e8b commit a896440

File tree

172 files changed

+6449
-4277
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

172 files changed

+6449
-4277
lines changed

src/libcore/cleanup.rs

+33-7
Original file line numberDiff line numberDiff line change
@@ -126,22 +126,29 @@ struct AnnihilateStats {
126126
n_bytes_freed: uint
127127
}
128128

129-
unsafe fn each_live_alloc(f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) {
129+
unsafe fn each_live_alloc(read_next_before: bool,
130+
f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) {
131+
//! Walks the internal list of allocations
132+
130133
use managed;
131134

132135
let task: *Task = transmute(rustrt::rust_get_task());
133136
let box = (*task).boxed_region.live_allocs;
134137
let mut box: *mut BoxRepr = transmute(copy box);
135138
while box != mut_null() {
136-
let next = transmute(copy (*box).header.next);
139+
let next_before = transmute(copy (*box).header.next);
137140
let uniq =
138141
(*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE;
139142

140143
if ! f(box, uniq) {
141144
break
142145
}
143146

144-
box = next
147+
if read_next_before {
148+
box = next_before;
149+
} else {
150+
box = transmute(copy (*box).header.next);
151+
}
145152
}
146153
}
147154

@@ -159,7 +166,7 @@ fn debug_mem() -> bool {
159166
#[cfg(notest)]
160167
#[lang="annihilate"]
161168
pub unsafe fn annihilate() {
162-
use unstable::lang::local_free;
169+
use unstable::lang::{local_free, debug_ptr};
163170
use io::WriterUtil;
164171
use io;
165172
use libc;
@@ -173,27 +180,46 @@ pub unsafe fn annihilate() {
173180
};
174181

175182
// Pass 1: Make all boxes immortal.
176-
for each_live_alloc |box, uniq| {
183+
//
184+
// In this pass, nothing gets freed, so it does not matter whether
185+
// we read the next field before or after the callback.
186+
for each_live_alloc(true) |box, uniq| {
177187
stats.n_total_boxes += 1;
178188
if uniq {
189+
debug_ptr("Managed-uniq: ", &*box);
179190
stats.n_unique_boxes += 1;
180191
} else {
192+
debug_ptr("Immortalizing: ", &*box);
181193
(*box).header.ref_count = managed::raw::RC_IMMORTAL;
182194
}
183195
}
184196

185197
// Pass 2: Drop all boxes.
186-
for each_live_alloc |box, uniq| {
198+
//
199+
// In this pass, unique-managed boxes may get freed, but not
200+
// managed boxes, so we must read the `next` field *after* the
201+
// callback, as the original value may have been freed.
202+
for each_live_alloc(false) |box, uniq| {
187203
if !uniq {
204+
debug_ptr("Invoking tydesc/glue on: ", &*box);
188205
let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
189206
let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
207+
debug_ptr("Box data: ", &(*box).data);
208+
debug_ptr("Type descriptor: ", tydesc);
190209
drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));
210+
debug_ptr("Dropped ", &*box);
191211
}
192212
}
193213

194214
// Pass 3: Free all boxes.
195-
for each_live_alloc |box, uniq| {
215+
//
216+
// In this pass, managed boxes may get freed (but not
217+
// unique-managed boxes, though I think that none of those are
218+
// left), so we must read the `next` field before, since it will
219+
// not be valid after.
220+
for each_live_alloc(true) |box, uniq| {
196221
if !uniq {
222+
debug_ptr("About to free: ", &*box);
197223
stats.n_bytes_freed +=
198224
(*((*box).header.type_desc)).size
199225
+ sys::size_of::<BoxRepr>();

src/libcore/io.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ pub enum WriterType { Screen, File }
10221022
pub trait Writer {
10231023
10241024
/// Write all of the given bytes.
1025-
fn write(&self, v: &const [u8]);
1025+
fn write(&self, v: &[u8]);
10261026
10271027
/// Move the current position within the stream. The second parameter
10281028
/// determines the position that the first parameter is relative to.
@@ -1039,23 +1039,23 @@ pub trait Writer {
10391039
}
10401040
10411041
impl Writer for @Writer {
1042-
fn write(&self, v: &const [u8]) { self.write(v) }
1042+
fn write(&self, v: &[u8]) { self.write(v) }
10431043
fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) }
10441044
fn tell(&self) -> uint { self.tell() }
10451045
fn flush(&self) -> int { self.flush() }
10461046
fn get_type(&self) -> WriterType { self.get_type() }
10471047
}
10481048
10491049
impl<W:Writer,C> Writer for Wrapper<W, C> {
1050-
fn write(&self, bs: &const [u8]) { self.base.write(bs); }
1050+
fn write(&self, bs: &[u8]) { self.base.write(bs); }
10511051
fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); }
10521052
fn tell(&self) -> uint { self.base.tell() }
10531053
fn flush(&self) -> int { self.base.flush() }
10541054
fn get_type(&self) -> WriterType { File }
10551055
}
10561056
10571057
impl Writer for *libc::FILE {
1058-
fn write(&self, v: &const [u8]) {
1058+
fn write(&self, v: &[u8]) {
10591059
unsafe {
10601060
do vec::as_const_buf(v) |vbuf, len| {
10611061
let nout = libc::fwrite(vbuf as *c_void,
@@ -1105,7 +1105,7 @@ pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer {
11051105
}
11061106

11071107
impl Writer for fd_t {
1108-
fn write(&self, v: &const [u8]) {
1108+
fn write(&self, v: &[u8]) {
11091109
unsafe {
11101110
let mut count = 0u;
11111111
do vec::as_const_buf(v) |vbuf, len| {
@@ -1262,7 +1262,7 @@ pub fn u64_to_be_bytes<T>(n: u64, size: uint,
12621262
}
12631263
}
12641264

1265-
pub fn u64_from_be_bytes(data: &const [u8],
1265+
pub fn u64_from_be_bytes(data: &[u8],
12661266
start: uint,
12671267
size: uint)
12681268
-> u64 {
@@ -1497,7 +1497,7 @@ pub struct BytesWriter {
14971497
}
14981498
14991499
impl Writer for BytesWriter {
1500-
fn write(&self, v: &const [u8]) {
1500+
fn write(&self, v: &[u8]) {
15011501
let v_len = v.len();
15021502
let bytes_len = vec::uniq_len(&const self.bytes);
15031503

src/libcore/rt/sched/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ pub impl Scheduler {
304304
unsafe {
305305
let last_task = transmute::<Option<&Task>, Option<&mut Task>>(last_task);
306306
let last_task_context = match last_task {
307-
Some(ref t) => Some(&mut t.saved_context), None => None
307+
Some(t) => Some(&mut t.saved_context), None => None
308308
};
309309
let next_task_context = match self.current_task {
310310
Some(ref mut t) => Some(&mut t.saved_context), None => None

src/libcore/str.rs

-12
Original file line numberDiff line numberDiff line change
@@ -2356,9 +2356,6 @@ pub trait StrSlice<'self> {
23562356
fn any(&self, it: &fn(char) -> bool) -> bool;
23572357
fn contains<'a>(&self, needle: &'a str) -> bool;
23582358
fn contains_char(&self, needle: char) -> bool;
2359-
#[cfg(stage1)]
2360-
#[cfg(stage2)]
2361-
#[cfg(stage3)]
23622359
fn char_iter(&self) -> StrCharIterator<'self>;
23632360
fn each(&self, it: &fn(u8) -> bool);
23642361
fn eachi(&self, it: &fn(uint, u8) -> bool);
@@ -2420,9 +2417,6 @@ impl<'self> StrSlice<'self> for &'self str {
24202417
contains_char(*self, needle)
24212418
}
24222419
2423-
#[cfg(stage1)]
2424-
#[cfg(stage2)]
2425-
#[cfg(stage3)]
24262420
#[inline]
24272421
fn char_iter(&self) -> StrCharIterator<'self> {
24282422
StrCharIterator {
@@ -2615,17 +2609,11 @@ impl Clone for ~str {
26152609
}
26162610
}
26172611
2618-
#[cfg(stage1)]
2619-
#[cfg(stage2)]
2620-
#[cfg(stage3)]
26212612
pub struct StrCharIterator<'self> {
26222613
priv index: uint,
26232614
priv string: &'self str,
26242615
}
26252616
2626-
#[cfg(stage1)]
2627-
#[cfg(stage2)]
2628-
#[cfg(stage3)]
26292617
impl<'self> Iterator<char> for StrCharIterator<'self> {
26302618
#[inline]
26312619
fn next(&mut self) -> Option<char> {

src/libcore/to_bytes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use io::Writer;
1919
use option::{None, Option, Some};
2020
use str;
2121

22-
pub type Cb<'self> = &'self fn(buf: &const [u8]) -> bool;
22+
pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool;
2323

2424
/**
2525
* A trait to implement in order to make a type hashable;

src/libcore/unstable/lang.rs

+44-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! Runtime calls emitted by the compiler.
1212
1313
use cast::transmute;
14-
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
14+
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO};
1515
use managed::raw::BoxRepr;
1616
use str;
1717
use sys;
@@ -74,7 +74,44 @@ pub fn fail_borrowed() {
7474
#[lang="exchange_malloc"]
7575
#[inline(always)]
7676
pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
77-
transmute(exchange_alloc::malloc(transmute(td), transmute(size)))
77+
let result = transmute(exchange_alloc::malloc(transmute(td), transmute(size)));
78+
debug_ptr("exchange_malloc: ", result);
79+
return result;
80+
}
81+
82+
/// Because this code is so perf. sensitive, use a static constant so that
83+
/// debug printouts are compiled out most of the time.
84+
static ENABLE_DEBUG_PTR: bool = false;
85+
86+
#[inline]
87+
pub fn debug_ptr<T>(tag: &'static str, p: *T) {
88+
//! A useful debugging function that prints a pointer + tag + newline
89+
//! without allocating memory.
90+
91+
if ENABLE_DEBUG_PTR && ::rt::env::get().debug_mem {
92+
debug_ptr_slow(tag, p);
93+
}
94+
95+
fn debug_ptr_slow<T>(tag: &'static str, p: *T) {
96+
use io;
97+
let dbg = STDERR_FILENO as io::fd_t;
98+
let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8',
99+
'9', 'a', 'b', 'c', 'd', 'e', 'f'];
100+
dbg.write_str(tag);
101+
102+
static uint_nibbles: uint = ::uint::bytes << 1;
103+
let mut buffer = [0_u8, ..uint_nibbles+1];
104+
let mut i = p as uint;
105+
let mut c = uint_nibbles;
106+
while c > 0 {
107+
c -= 1;
108+
buffer[c] = letters[i & 0xF] as u8;
109+
i >>= 4;
110+
}
111+
dbg.write(buffer.slice(0, uint_nibbles));
112+
113+
dbg.write_str("\n");
114+
}
78115
}
79116

80117
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
@@ -83,13 +120,16 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
83120
#[lang="exchange_free"]
84121
#[inline(always)]
85122
pub unsafe fn exchange_free(ptr: *c_char) {
123+
debug_ptr("exchange_free: ", ptr);
86124
exchange_alloc::free(transmute(ptr))
87125
}
88126

89127
#[lang="malloc"]
90128
#[inline(always)]
91129
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
92-
return rustrt::rust_upcall_malloc_noswitch(td, size);
130+
let result = rustrt::rust_upcall_malloc_noswitch(td, size);
131+
debug_ptr("local_malloc: ", result);
132+
return result;
93133
}
94134

95135
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
@@ -98,6 +138,7 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
98138
#[lang="free"]
99139
#[inline(always)]
100140
pub unsafe fn local_free(ptr: *c_char) {
141+
debug_ptr("local_free: ", ptr);
101142
rustrt::rust_upcall_free_noswitch(ptr);
102143
}
103144

src/libcore/vec.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
1919
use clone::Clone;
2020
use old_iter::BaseIter;
2121
use old_iter;
22-
#[cfg(stage1)]
23-
#[cfg(stage2)]
24-
#[cfg(stage3)]
2522
use iterator::Iterator;
2623
use kinds::Copy;
2724
use libc;
@@ -1824,7 +1821,7 @@ pub trait CopyableVector<T> {
18241821
}
18251822

18261823
/// Extension methods for vectors
1827-
impl<'self,T:Copy> CopyableVector<T> for &'self const [T] {
1824+
impl<'self,T:Copy> CopyableVector<T> for &'self [T] {
18281825
/// Returns a copy of `v`.
18291826
#[inline]
18301827
fn to_owned(&self) -> ~[T] {
@@ -2710,18 +2707,12 @@ impl<A:Clone> Clone for ~[A] {
27102707
}
27112708

27122709
// could be implemented with &[T] with .slice(), but this avoids bounds checks
2713-
#[cfg(stage1)]
2714-
#[cfg(stage2)]
2715-
#[cfg(stage3)]
27162710
pub struct VecIterator<'self, T> {
27172711
priv ptr: *T,
27182712
priv end: *T,
27192713
priv lifetime: &'self T // FIXME: #5922
27202714
}
27212715

2722-
#[cfg(stage1)]
2723-
#[cfg(stage2)]
2724-
#[cfg(stage3)]
27252716
impl<'self, T> Iterator<&'self T> for VecIterator<'self, T> {
27262717
#[inline]
27272718
fn next(&mut self) -> Option<&'self T> {

src/librustc/driver/driver.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -263,38 +263,35 @@ pub fn compile_rest(sess: Session,
263263
middle::check_loop::check_crate(ty_cx, crate));
264264

265265
let middle::moves::MoveMaps {moves_map, variable_moves_map,
266-
capture_map} =
266+
moved_variables_set, capture_map} =
267267
time(time_passes, ~"compute moves", ||
268268
middle::moves::compute_moves(ty_cx, method_map, crate));
269269

270270
time(time_passes, ~"match checking", ||
271271
middle::check_match::check_crate(ty_cx, method_map,
272272
moves_map, crate));
273273

274-
let last_use_map =
275-
time(time_passes, ~"liveness checking", ||
276-
middle::liveness::check_crate(ty_cx, method_map,
277-
variable_moves_map,
278-
capture_map, crate));
274+
time(time_passes, ~"liveness checking", ||
275+
middle::liveness::check_crate(ty_cx, method_map,
276+
variable_moves_map,
277+
capture_map, crate));
279278

280-
let (root_map, mutbl_map, write_guard_map) =
279+
let (root_map, write_guard_map) =
281280
time(time_passes, ~"borrow checking", ||
282281
middle::borrowck::check_crate(ty_cx, method_map,
283-
moves_map, capture_map,
284-
crate));
282+
moves_map, moved_variables_set,
283+
capture_map, crate));
285284

286285
time(time_passes, ~"kind checking", ||
287-
kind::check_crate(ty_cx, method_map, last_use_map, crate));
286+
kind::check_crate(ty_cx, method_map, crate));
288287

289288
time(time_passes, ~"lint checking", ||
290289
lint::check_crate(ty_cx, crate));
291290

292291
if upto == cu_no_trans { return (crate, Some(ty_cx)); }
293292

294293
let maps = astencode::Maps {
295-
mutbl_map: mutbl_map,
296294
root_map: root_map,
297-
last_use_map: last_use_map,
298295
method_map: method_map,
299296
vtable_map: vtable_map,
300297
write_guard_map: write_guard_map,

0 commit comments

Comments
 (0)