Skip to content

Commit

Permalink
new borrow checker (mass squash)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Apr 30, 2013
1 parent b5a7e8b commit a896440
Show file tree
Hide file tree
Showing 172 changed files with 6,449 additions and 4,277 deletions.
40 changes: 33 additions & 7 deletions src/libcore/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,29 @@ struct AnnihilateStats {
n_bytes_freed: uint
}

unsafe fn each_live_alloc(f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) {
unsafe fn each_live_alloc(read_next_before: bool,
f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) {
//! Walks the internal list of allocations

use managed;

let task: *Task = transmute(rustrt::rust_get_task());
let box = (*task).boxed_region.live_allocs;
let mut box: *mut BoxRepr = transmute(copy box);
while box != mut_null() {
let next = transmute(copy (*box).header.next);
let next_before = transmute(copy (*box).header.next);
let uniq =
(*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE;

if ! f(box, uniq) {
break
}

box = next
if read_next_before {
box = next_before;
} else {
box = transmute(copy (*box).header.next);
}
}
}

Expand All @@ -159,7 +166,7 @@ fn debug_mem() -> bool {
#[cfg(notest)]
#[lang="annihilate"]
pub unsafe fn annihilate() {
use unstable::lang::local_free;
use unstable::lang::{local_free, debug_ptr};
use io::WriterUtil;
use io;
use libc;
Expand All @@ -173,27 +180,46 @@ pub unsafe fn annihilate() {
};

// Pass 1: Make all boxes immortal.
for each_live_alloc |box, uniq| {
//
// In this pass, nothing gets freed, so it does not matter whether
// we read the next field before or after the callback.
for each_live_alloc(true) |box, uniq| {
stats.n_total_boxes += 1;
if uniq {
debug_ptr("Managed-uniq: ", &*box);
stats.n_unique_boxes += 1;
} else {
debug_ptr("Immortalizing: ", &*box);
(*box).header.ref_count = managed::raw::RC_IMMORTAL;
}
}

// Pass 2: Drop all boxes.
for each_live_alloc |box, uniq| {
//
// In this pass, unique-managed boxes may get freed, but not
// managed boxes, so we must read the `next` field *after* the
// callback, as the original value may have been freed.
for each_live_alloc(false) |box, uniq| {
if !uniq {
debug_ptr("Invoking tydesc/glue on: ", &*box);
let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
debug_ptr("Box data: ", &(*box).data);
debug_ptr("Type descriptor: ", tydesc);
drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));
debug_ptr("Dropped ", &*box);
}
}

// Pass 3: Free all boxes.
for each_live_alloc |box, uniq| {
//
// In this pass, managed boxes may get freed (but not
// unique-managed boxes, though I think that none of those are
// left), so we must read the `next` field before, since it will
// not be valid after.
for each_live_alloc(true) |box, uniq| {
if !uniq {
debug_ptr("About to free: ", &*box);
stats.n_bytes_freed +=
(*((*box).header.type_desc)).size
+ sys::size_of::<BoxRepr>();
Expand Down
14 changes: 7 additions & 7 deletions src/libcore/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ pub enum WriterType { Screen, File }
pub trait Writer {
/// Write all of the given bytes.
fn write(&self, v: &const [u8]);
fn write(&self, v: &[u8]);
/// Move the current position within the stream. The second parameter
/// determines the position that the first parameter is relative to.
Expand All @@ -1039,23 +1039,23 @@ pub trait Writer {
}
impl Writer for @Writer {
fn write(&self, v: &const [u8]) { self.write(v) }
fn write(&self, v: &[u8]) { self.write(v) }
fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) }
fn tell(&self) -> uint { self.tell() }
fn flush(&self) -> int { self.flush() }
fn get_type(&self) -> WriterType { self.get_type() }
}
impl<W:Writer,C> Writer for Wrapper<W, C> {
fn write(&self, bs: &const [u8]) { self.base.write(bs); }
fn write(&self, bs: &[u8]) { self.base.write(bs); }
fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); }
fn tell(&self) -> uint { self.base.tell() }
fn flush(&self) -> int { self.base.flush() }
fn get_type(&self) -> WriterType { File }
}
impl Writer for *libc::FILE {
fn write(&self, v: &const [u8]) {
fn write(&self, v: &[u8]) {
unsafe {
do vec::as_const_buf(v) |vbuf, len| {
let nout = libc::fwrite(vbuf as *c_void,
Expand Down Expand Up @@ -1105,7 +1105,7 @@ pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer {
}

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

pub fn u64_from_be_bytes(data: &const [u8],
pub fn u64_from_be_bytes(data: &[u8],
start: uint,
size: uint)
-> u64 {
Expand Down Expand Up @@ -1497,7 +1497,7 @@ pub struct BytesWriter {
}
impl Writer for BytesWriter {
fn write(&self, v: &const [u8]) {
fn write(&self, v: &[u8]) {
let v_len = v.len();
let bytes_len = vec::uniq_len(&const self.bytes);
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rt/sched/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ pub impl Scheduler {
unsafe {
let last_task = transmute::<Option<&Task>, Option<&mut Task>>(last_task);
let last_task_context = match last_task {
Some(ref t) => Some(&mut t.saved_context), None => None
Some(t) => Some(&mut t.saved_context), None => None
};
let next_task_context = match self.current_task {
Some(ref mut t) => Some(&mut t.saved_context), None => None
Expand Down
12 changes: 0 additions & 12 deletions src/libcore/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2356,9 +2356,6 @@ pub trait StrSlice<'self> {
fn any(&self, it: &fn(char) -> bool) -> bool;
fn contains<'a>(&self, needle: &'a str) -> bool;
fn contains_char(&self, needle: char) -> bool;
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn char_iter(&self) -> StrCharIterator<'self>;
fn each(&self, it: &fn(u8) -> bool);
fn eachi(&self, it: &fn(uint, u8) -> bool);
Expand Down Expand Up @@ -2420,9 +2417,6 @@ impl<'self> StrSlice<'self> for &'self str {
contains_char(*self, needle)
}

#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline]
fn char_iter(&self) -> StrCharIterator<'self> {
StrCharIterator {
Expand Down Expand Up @@ -2615,17 +2609,11 @@ impl Clone for ~str {
}
}

#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
pub struct StrCharIterator<'self> {
priv index: uint,
priv string: &'self str,
}

#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<'self> Iterator<char> for StrCharIterator<'self> {
#[inline]
fn next(&mut self) -> Option<char> {
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/to_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use io::Writer;
use option::{None, Option, Some};
use str;

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

/**
* A trait to implement in order to make a type hashable;
Expand Down
47 changes: 44 additions & 3 deletions src/libcore/unstable/lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! Runtime calls emitted by the compiler.

use cast::transmute;
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO};
use managed::raw::BoxRepr;
use str;
use sys;
Expand Down Expand Up @@ -74,7 +74,44 @@ pub fn fail_borrowed() {
#[lang="exchange_malloc"]
#[inline(always)]
pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
transmute(exchange_alloc::malloc(transmute(td), transmute(size)))
let result = transmute(exchange_alloc::malloc(transmute(td), transmute(size)));
debug_ptr("exchange_malloc: ", result);
return result;
}

/// Because this code is so perf. sensitive, use a static constant so that
/// debug printouts are compiled out most of the time.
static ENABLE_DEBUG_PTR: bool = false;

#[inline]
pub fn debug_ptr<T>(tag: &'static str, p: *T) {
//! A useful debugging function that prints a pointer + tag + newline
//! without allocating memory.

if ENABLE_DEBUG_PTR && ::rt::env::get().debug_mem {
debug_ptr_slow(tag, p);
}

fn debug_ptr_slow<T>(tag: &'static str, p: *T) {
use io;
let dbg = STDERR_FILENO as io::fd_t;
let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f'];
dbg.write_str(tag);

static uint_nibbles: uint = ::uint::bytes << 1;
let mut buffer = [0_u8, ..uint_nibbles+1];
let mut i = p as uint;
let mut c = uint_nibbles;
while c > 0 {
c -= 1;
buffer[c] = letters[i & 0xF] as u8;
i >>= 4;
}
dbg.write(buffer.slice(0, uint_nibbles));

dbg.write_str("\n");
}
}

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

#[lang="malloc"]
#[inline(always)]
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
return rustrt::rust_upcall_malloc_noswitch(td, size);
let result = rustrt::rust_upcall_malloc_noswitch(td, size);
debug_ptr("local_malloc: ", result);
return result;
}

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

Expand Down
11 changes: 1 addition & 10 deletions src/libcore/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
use clone::Clone;
use old_iter::BaseIter;
use old_iter;
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
use iterator::Iterator;
use kinds::Copy;
use libc;
Expand Down Expand Up @@ -1824,7 +1821,7 @@ pub trait CopyableVector<T> {
}

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

// could be implemented with &[T] with .slice(), but this avoids bounds checks
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
pub struct VecIterator<'self, T> {
priv ptr: *T,
priv end: *T,
priv lifetime: &'self T // FIXME: #5922
}

#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<'self, T> Iterator<&'self T> for VecIterator<'self, T> {
#[inline]
fn next(&mut self) -> Option<&'self T> {
Expand Down
21 changes: 9 additions & 12 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,38 +263,35 @@ pub fn compile_rest(sess: Session,
middle::check_loop::check_crate(ty_cx, crate));

let middle::moves::MoveMaps {moves_map, variable_moves_map,
capture_map} =
moved_variables_set, capture_map} =
time(time_passes, ~"compute moves", ||
middle::moves::compute_moves(ty_cx, method_map, crate));

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

let last_use_map =
time(time_passes, ~"liveness checking", ||
middle::liveness::check_crate(ty_cx, method_map,
variable_moves_map,
capture_map, crate));
time(time_passes, ~"liveness checking", ||
middle::liveness::check_crate(ty_cx, method_map,
variable_moves_map,
capture_map, crate));

let (root_map, mutbl_map, write_guard_map) =
let (root_map, write_guard_map) =
time(time_passes, ~"borrow checking", ||
middle::borrowck::check_crate(ty_cx, method_map,
moves_map, capture_map,
crate));
moves_map, moved_variables_set,
capture_map, crate));

time(time_passes, ~"kind checking", ||
kind::check_crate(ty_cx, method_map, last_use_map, crate));
kind::check_crate(ty_cx, method_map, crate));

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

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

let maps = astencode::Maps {
mutbl_map: mutbl_map,
root_map: root_map,
last_use_map: last_use_map,
method_map: method_map,
vtable_map: vtable_map,
write_guard_map: write_guard_map,
Expand Down
Loading

0 comments on commit a896440

Please sign in to comment.