Skip to content

Implement the new for-loop protocol #6223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 11, 2013
32 changes: 30 additions & 2 deletions src/libcore/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ struct AnnihilateStats {
n_bytes_freed: uint
}

#[cfg(stage0)]
unsafe fn each_live_alloc(read_next_before: bool,
f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) {
//! Walks the internal list of allocations
Expand All @@ -141,8 +142,8 @@ unsafe fn each_live_alloc(read_next_before: bool,
let uniq =
(*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE;

if ! f(box, uniq) {
break
if !f(box, uniq) {
return;
}

if read_next_before {
Expand All @@ -152,6 +153,33 @@ unsafe fn each_live_alloc(read_next_before: bool,
}
}
}
#[cfg(not(stage0))]
unsafe fn each_live_alloc(read_next_before: bool,
f: &fn(box: *mut BoxRepr, uniq: bool) -> 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_before = transmute(copy (*box).header.next);
let uniq =
(*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE;

if !f(box, uniq) {
return false;
}

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

#[cfg(unix)]
fn debug_mem() -> bool {
Expand Down
53 changes: 53 additions & 0 deletions src/libcore/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,32 @@ pub trait Map<K, V>: Mutable {
fn contains_key(&self, key: &K) -> bool;

// Visits all keys and values
#[cfg(stage0)]
fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool);
// Visits all keys and values
#[cfg(not(stage0))]
fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool) -> bool;

/// Visit all keys
#[cfg(stage0)]
fn each_key(&self, f: &fn(&K) -> bool);
/// Visit all keys
#[cfg(not(stage0))]
fn each_key(&self, f: &fn(&K) -> bool) -> bool;

/// Visit all values
#[cfg(stage0)]
fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool);
/// Visit all values
#[cfg(not(stage0))]
fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool;

/// Iterate over the map and mutate the contained values
#[cfg(stage0)]
fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool);
/// Iterate over the map and mutate the contained values
#[cfg(not(stage0))]
fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool;

/// Return a reference to the value corresponding to the key
fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
Expand All @@ -65,6 +81,7 @@ pub trait Map<K, V>: Mutable {
fn pop(&mut self, k: &K) -> Option<V>;
}

#[cfg(stage0)]
pub trait Set<T>: Mutable {
/// Return true if the set contains a value
fn contains(&self, value: &T) -> bool;
Expand Down Expand Up @@ -99,3 +116,39 @@ pub trait Set<T>: Mutable {
/// Visit the values representing the union
fn union(&self, other: &Self, f: &fn(&T) -> bool);
}

#[cfg(not(stage0))]
pub trait Set<T>: Mutable {
/// Return true if the set contains a value
fn contains(&self, value: &T) -> bool;

/// Add a value to the set. Return true if the value was not already
/// present in the set.
fn insert(&mut self, value: T) -> bool;

/// Remove a value from the set. Return true if the value was
/// present in the set.
fn remove(&mut self, value: &T) -> bool;

/// Return true if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
fn is_disjoint(&self, other: &Self) -> bool;

/// Return true if the set is a subset of another
fn is_subset(&self, other: &Self) -> bool;

/// Return true if the set is a superset of another
fn is_superset(&self, other: &Self) -> bool;

/// Visit the values representing the difference
fn difference(&self, other: &Self, f: &fn(&T) -> bool) -> bool;

/// Visit the values representing the symmetric difference
fn symmetric_difference(&self, other: &Self, f: &fn(&T) -> bool) -> bool;

/// Visit the values representing the intersection
fn intersection(&self, other: &Self, f: &fn(&T) -> bool) -> bool;

/// Visit the values representing the union
fn union(&self, other: &Self, f: &fn(&T) -> bool) -> bool;
}
Binary file added src/libcore/core
Binary file not shown.
31 changes: 25 additions & 6 deletions src/libcore/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ type Visitor<'self> = &'self fn(root: **Word, tydesc: *Word) -> bool;

// Walks the list of roots for the given safe point, and calls visitor
// on each root.
unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
let fp_bytes: *u8 = cast::transmute(fp);
let sp_meta: *u32 = cast::transmute(sp.sp_meta);

Expand All @@ -155,7 +155,7 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
} else {
ptr::null()
};
if !visitor(root, tydesc) { return; }
if !visitor(root, tydesc) { return false; }
}
sri += 1;
}
Expand All @@ -168,6 +168,16 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
}
rri += 1;
}
return true;
}

#[cfg(stage0)]
unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
_walk_safe_point(fp, sp, visitor);
}
#[cfg(not(stage0))]
unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
_walk_safe_point(fp, sp, visitor)
}

// Is fp contained in segment?
Expand Down Expand Up @@ -222,7 +232,7 @@ static need_cleanup: Memory = exchange_heap | stack;

// Walks stack, searching for roots of the requested type, and passes
// each root to the visitor.
unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool {
let mut segment = rustrt::rust_get_stack_segment();
let mut last_ret: *Word = ptr::null();
// To avoid collecting memory used by the GC itself, skip stack
Expand Down Expand Up @@ -274,14 +284,14 @@ unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
// Root is a generic box.
let refcount = **root;
if mem | task_local_heap != 0 && refcount != -1 {
if !visitor(root, tydesc) { return; }
if !visitor(root, tydesc) { return false; }
} else if mem | exchange_heap != 0 && refcount == -1 {
if !visitor(root, tydesc) { return; }
if !visitor(root, tydesc) { return false; }
}
} else {
// Root is a non-immediate.
if mem | stack != 0 {
if !visitor(root, tydesc) { return; }
if !visitor(root, tydesc) { return false; }
}
}
}
Expand All @@ -290,8 +300,17 @@ unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
}
reached_sentinel = delay_reached_sentinel;
}
return true;
}

#[cfg(stage0)]
unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
_walk_gc_roots(mem, sentinel, visitor);
}
#[cfg(not(stage0))]
unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool {
_walk_gc_roots(mem, sentinel, visitor)
}
pub fn gc() {
unsafe {
// Abort when GC is disabled.
Expand Down
Loading