Skip to content

Commit

Permalink
Some more progress on my experiments here.
Browse files Browse the repository at this point in the history
Still waiting for the latest variant of cheney to build (or rather,
the rust libstd changes it is based upon).  But I want to checkpoint
and go home.
  • Loading branch information
pnkfelix committed Dec 20, 2013
1 parent 2229de5 commit 7db759d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ BUILD_DIR=./objdir-dbgopt
RUSTC=$(BUILD_DIR)/x86_64-apple-darwin/stage2/bin/rustc

cheney-test: cheney-play-debug cheney-play
./cheney-play
RUST_LOG=cheney-play ./cheney-play

sro-test: sro-play-debug sro-play
./sro-play-debug
Expand Down
67 changes: 53 additions & 14 deletions cheney-play.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
#[feature(managed_boxes)];

#[allow(dead_code)]; // reenable check after done with dev.
#[allow(unused_imports)];
use std::cast;
use std::mem;
use std::ptr;
use std::rt::local_heap::{Box};
use RawBox = std::unstable::raw::Box;
use std::rt::global_heap;
use std::unstable::intrinsics;
use std::unstable::intrinsics::{TyDesc};

// Reminder:
// struct Box<T> { refc: uint, desc: *TyDesc, links: Lnx<T>, data: T }
// where
// struct Lnx<T> { prev: *mut Box<T>, next: *mut Box<T> }
// struct Box<T> {
// ref_count: uint, type_desc: *TyDesc,
// prev: *mut Box<T>, next: *mut Box<T>, data: T }

/// A Span holds the span `[start, limit)` for contiguous area of memory.
struct Span {
Expand All @@ -22,12 +22,15 @@ struct Span {

impl Span {
fn new(start: *uint, limit: *uint) -> Span{
Span{ start: start, limit: limit }
let ret = Span{ start: start, limit: limit };
debug!("Span::new({}, {})", start, limit);
ret
}
fn tup(&self) -> (*uint, *uint) { (self.start, self.limit) }
fn from((start, limit): (*uint, *uint)) -> Span { Span::new(start, limit) }
fn size_bytes(&self) -> uint { (self.limit as uint) - (self.start as uint) }
fn can_fit(&self, bytes: uint) -> bool { bytes <= self.size_bytes() }
fn would_exhaust(&self, bytes: uint) -> bool { ! self.can_fit(bytes) }
unsafe fn shift_start(&mut self, bytes: uint) {
assert!(self.can_fit(bytes));
assert!(bytes as int >= 0);
Expand Down Expand Up @@ -62,11 +65,16 @@ impl Chunk {
assert!(size >= mem::size_of::<FutureBox<()>>());
assert!(size >= mem::size_of::<ForwardedBox<()>>());

let word_size = mem::size_of::<uint>();
if 0 != size % word_size {
fail!("chunks must be multiples of machine words.");
}

unsafe {
let chunk_mem = global_heap::malloc_raw(size);
let start : *uint = cast::transmute(chunk_mem);
assert!((size as int) >= 0);
let limit : *uint = ptr::offset(start, size as int);
let limit : *uint = ptr::offset(start, (size / word_size) as int);
let block : *mut BigBlock = cast::transmute(start);
(*block).next = ptr::null();
(*block).limit = limit;
Expand All @@ -90,6 +98,18 @@ impl Chunk {
let limit = (*b).limit;
Span::new(start, limit)
}

unsafe fn free_all(&mut self) {
let mut ptr = self.span.start;
let mut next = self.next;
loop {
global_heap::free_raw(ptr);
match next {
None => break,
Some(p) => { ptr = (*p).span.start; next = (*p).next; }
}
}
}
}

/// A Block is a contiguous slice of memory within a Chunk. When
Expand Down Expand Up @@ -158,18 +178,24 @@ impl Gc {
}

pub fn alloc<T>(&mut self, arg:T) -> @T {
#[allow(unused_variable)];

unsafe {
let tydesc = intrinsics::get_tydesc::<T>();
let obj = self.alloc_ty_instance(tydesc);
fail!("GC::alloc not yet implemented");
let obj : *mut RawBox<T> = cast::transmute(obj);
// artificially pump up ref-count so that cheney will manage this object.
(*obj).ref_count += 1;
(*obj).type_desc = tydesc;
(*obj).prev = ptr::mut_null();
(*obj).next = ptr::mut_null();
(*obj).data = arg;
let obj : @T = cast::transmute(obj);
return obj;
}
}

unsafe fn alloc_ty_instance(&mut self, tydesc: *TyDesc) -> *uint {
let total_size = global_heap::get_box_size((*tydesc).size, (*tydesc).align);
if self.avail.can_fit(total_size) {
if self.avail.would_exhaust(total_size) {
// TODO: if total_size is large enough, consider
// allocating a separate chunk for it rather than
// immediately jumping into a Gc attempt.
Expand All @@ -186,9 +212,11 @@ impl Gc {
fn fill_remaining_space(&mut self) {
// TODO: inject placeholder object with fixed-size header as
// to spend O(1) effort rather than O(|remainingspace|).
let mut a = self.avail.start;
let lim = self.avail.limit;
println!("fill_remaining_space: a: {} lim: {} lim-a: {} bytes",
a, lim, (lim as uint) - (a as uint));
unsafe {
let mut a = self.avail.start;
let lim = self.avail.limit;
while a < lim {
{
let a : *mut uint = cast::transmute(a);
Expand All @@ -204,7 +232,7 @@ impl Gc {
#[allow(unused_variable)];

let owned_objects_to_scan : ~[*()] = ~[];
let pinned_shared_to_scan : ~[*Box] = ~[];
let pinned_shared_to_scan : ~[*RawBox<()>] = ~[];
let scan_ptr : *uint;
let to_ptr : *uint;
let limit : *uint;
Expand Down Expand Up @@ -272,3 +300,14 @@ fn main() {
let i3 = gc.alloc::<int>(3);
println!("i3: {:?}", i3);
}

impl Drop for Gc {
fn drop(&mut self) {
unsafe {
self.normal_chunks.free_all();
match self.large_objects.take() {
None => {}, Some(c) => c.free_all(),
}
}
}
}
29 changes: 18 additions & 11 deletions sro-play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use std::cast;
use std::libc;
use std::local_data;
use std::os;
use std::ptr;
use std::rt::local_heap;
use std::rt::local_heap::{MemoryRegion, Box};
Expand Down Expand Up @@ -161,23 +162,29 @@ extern "C" fn do_walk(mut regs: &mut Registers, mut ctxt: &mut ctxt, _:*()) {
println!("got to do_walk");
}

fn traverse_local_heap_structure() {
Local::borrow(|task: &mut Task| {
traverse_local_heap_structure();

struct MyLocalHeap { // XXX keep synced w/ local_heap::LocalHeap
memory_region: MemoryRegion,
poison_on_free: bool,
live_allocs: *mut Box,
}
fn traverse_local_heap_structure() {
let mut borrowed_task = Local::borrow(None::<Task>);
{
let task = borrowed_task.get();
struct MyLocalHeap { // XXX keep synced w/ local_heap::LocalHeap
memory_region: MemoryRegion,
poison_on_free: bool,
live_allocs: *mut Box,
}

let hp : &MyLocalHeap = unsafe { cast::transmute(&task.heap) };
println!("hp: {:?}", hp);
});
let hp : &MyLocalHeap = unsafe { cast::transmute(&task.heap) };
println!("hp: {:?}", hp);
}
}
}

fn main() {
println!("Hello world.");
let ctxt = ~ctxt { verbose: false, id: 100, info: () };
let mut ctxt = ~ctxt { verbose: false, id: 100, info: () };
if os::args().contains(&~"--verbose") {
ctxt.verbose = true;
}
walk_managed(ctxt);
}

0 comments on commit 7db759d

Please sign in to comment.