Skip to content

Commit 7db759d

Browse files
committed
Some more progress on my experiments here.
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.
1 parent 2229de5 commit 7db759d

File tree

3 files changed

+72
-26
lines changed

3 files changed

+72
-26
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ BUILD_DIR=./objdir-dbgopt
22
RUSTC=$(BUILD_DIR)/x86_64-apple-darwin/stage2/bin/rustc
33

44
cheney-test: cheney-play-debug cheney-play
5-
./cheney-play
5+
RUST_LOG=cheney-play ./cheney-play
66

77
sro-test: sro-play-debug sro-play
88
./sro-play-debug

cheney-play.rs

+53-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
#[feature(managed_boxes)];
2-
2+
#[allow(dead_code)]; // reenable check after done with dev.
33
#[allow(unused_imports)];
44
use std::cast;
55
use std::mem;
66
use std::ptr;
7-
use std::rt::local_heap::{Box};
7+
use RawBox = std::unstable::raw::Box;
88
use std::rt::global_heap;
99
use std::unstable::intrinsics;
1010
use std::unstable::intrinsics::{TyDesc};
1111

1212
// Reminder:
13-
// struct Box<T> { refc: uint, desc: *TyDesc, links: Lnx<T>, data: T }
14-
// where
15-
// struct Lnx<T> { prev: *mut Box<T>, next: *mut Box<T> }
13+
// struct Box<T> {
14+
// ref_count: uint, type_desc: *TyDesc,
15+
// prev: *mut Box<T>, next: *mut Box<T>, data: T }
1616

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

2323
impl Span {
2424
fn new(start: *uint, limit: *uint) -> Span{
25-
Span{ start: start, limit: limit }
25+
let ret = Span{ start: start, limit: limit };
26+
debug!("Span::new({}, {})", start, limit);
27+
ret
2628
}
2729
fn tup(&self) -> (*uint, *uint) { (self.start, self.limit) }
2830
fn from((start, limit): (*uint, *uint)) -> Span { Span::new(start, limit) }
2931
fn size_bytes(&self) -> uint { (self.limit as uint) - (self.start as uint) }
3032
fn can_fit(&self, bytes: uint) -> bool { bytes <= self.size_bytes() }
33+
fn would_exhaust(&self, bytes: uint) -> bool { ! self.can_fit(bytes) }
3134
unsafe fn shift_start(&mut self, bytes: uint) {
3235
assert!(self.can_fit(bytes));
3336
assert!(bytes as int >= 0);
@@ -62,11 +65,16 @@ impl Chunk {
6265
assert!(size >= mem::size_of::<FutureBox<()>>());
6366
assert!(size >= mem::size_of::<ForwardedBox<()>>());
6467

68+
let word_size = mem::size_of::<uint>();
69+
if 0 != size % word_size {
70+
fail!("chunks must be multiples of machine words.");
71+
}
72+
6573
unsafe {
6674
let chunk_mem = global_heap::malloc_raw(size);
6775
let start : *uint = cast::transmute(chunk_mem);
6876
assert!((size as int) >= 0);
69-
let limit : *uint = ptr::offset(start, size as int);
77+
let limit : *uint = ptr::offset(start, (size / word_size) as int);
7078
let block : *mut BigBlock = cast::transmute(start);
7179
(*block).next = ptr::null();
7280
(*block).limit = limit;
@@ -90,6 +98,18 @@ impl Chunk {
9098
let limit = (*b).limit;
9199
Span::new(start, limit)
92100
}
101+
102+
unsafe fn free_all(&mut self) {
103+
let mut ptr = self.span.start;
104+
let mut next = self.next;
105+
loop {
106+
global_heap::free_raw(ptr);
107+
match next {
108+
None => break,
109+
Some(p) => { ptr = (*p).span.start; next = (*p).next; }
110+
}
111+
}
112+
}
93113
}
94114

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

160180
pub fn alloc<T>(&mut self, arg:T) -> @T {
161-
#[allow(unused_variable)];
162-
163181
unsafe {
164182
let tydesc = intrinsics::get_tydesc::<T>();
165183
let obj = self.alloc_ty_instance(tydesc);
166-
fail!("GC::alloc not yet implemented");
184+
let obj : *mut RawBox<T> = cast::transmute(obj);
185+
// artificially pump up ref-count so that cheney will manage this object.
186+
(*obj).ref_count += 1;
187+
(*obj).type_desc = tydesc;
188+
(*obj).prev = ptr::mut_null();
189+
(*obj).next = ptr::mut_null();
190+
(*obj).data = arg;
191+
let obj : @T = cast::transmute(obj);
192+
return obj;
167193
}
168194
}
169195

170196
unsafe fn alloc_ty_instance(&mut self, tydesc: *TyDesc) -> *uint {
171197
let total_size = global_heap::get_box_size((*tydesc).size, (*tydesc).align);
172-
if self.avail.can_fit(total_size) {
198+
if self.avail.would_exhaust(total_size) {
173199
// TODO: if total_size is large enough, consider
174200
// allocating a separate chunk for it rather than
175201
// immediately jumping into a Gc attempt.
@@ -186,9 +212,11 @@ impl Gc {
186212
fn fill_remaining_space(&mut self) {
187213
// TODO: inject placeholder object with fixed-size header as
188214
// to spend O(1) effort rather than O(|remainingspace|).
215+
let mut a = self.avail.start;
216+
let lim = self.avail.limit;
217+
println!("fill_remaining_space: a: {} lim: {} lim-a: {} bytes",
218+
a, lim, (lim as uint) - (a as uint));
189219
unsafe {
190-
let mut a = self.avail.start;
191-
let lim = self.avail.limit;
192220
while a < lim {
193221
{
194222
let a : *mut uint = cast::transmute(a);
@@ -204,7 +232,7 @@ impl Gc {
204232
#[allow(unused_variable)];
205233

206234
let owned_objects_to_scan : ~[*()] = ~[];
207-
let pinned_shared_to_scan : ~[*Box] = ~[];
235+
let pinned_shared_to_scan : ~[*RawBox<()>] = ~[];
208236
let scan_ptr : *uint;
209237
let to_ptr : *uint;
210238
let limit : *uint;
@@ -272,3 +300,14 @@ fn main() {
272300
let i3 = gc.alloc::<int>(3);
273301
println!("i3: {:?}", i3);
274302
}
303+
304+
impl Drop for Gc {
305+
fn drop(&mut self) {
306+
unsafe {
307+
self.normal_chunks.free_all();
308+
match self.large_objects.take() {
309+
None => {}, Some(c) => c.free_all(),
310+
}
311+
}
312+
}
313+
}

sro-play.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::cast;
55
use std::libc;
66
use std::local_data;
7+
use std::os;
78
use std::ptr;
89
use std::rt::local_heap;
910
use std::rt::local_heap::{MemoryRegion, Box};
@@ -161,23 +162,29 @@ extern "C" fn do_walk(mut regs: &mut Registers, mut ctxt: &mut ctxt, _:*()) {
161162
println!("got to do_walk");
162163
}
163164

164-
fn traverse_local_heap_structure() {
165-
Local::borrow(|task: &mut Task| {
165+
traverse_local_heap_structure();
166166

167-
struct MyLocalHeap { // XXX keep synced w/ local_heap::LocalHeap
168-
memory_region: MemoryRegion,
169-
poison_on_free: bool,
170-
live_allocs: *mut Box,
171-
}
167+
fn traverse_local_heap_structure() {
168+
let mut borrowed_task = Local::borrow(None::<Task>);
169+
{
170+
let task = borrowed_task.get();
171+
struct MyLocalHeap { // XXX keep synced w/ local_heap::LocalHeap
172+
memory_region: MemoryRegion,
173+
poison_on_free: bool,
174+
live_allocs: *mut Box,
175+
}
172176

173-
let hp : &MyLocalHeap = unsafe { cast::transmute(&task.heap) };
174-
println!("hp: {:?}", hp);
175-
});
177+
let hp : &MyLocalHeap = unsafe { cast::transmute(&task.heap) };
178+
println!("hp: {:?}", hp);
179+
}
176180
}
177181
}
178182

179183
fn main() {
180184
println!("Hello world.");
181-
let ctxt = ~ctxt { verbose: false, id: 100, info: () };
185+
let mut ctxt = ~ctxt { verbose: false, id: 100, info: () };
186+
if os::args().contains(&~"--verbose") {
187+
ctxt.verbose = true;
188+
}
182189
walk_managed(ctxt);
183190
}

0 commit comments

Comments
 (0)