Skip to content

Commit 3ba8a99

Browse files
committed
move gc logging under exec-gc-logging mode
1 parent 479be70 commit 3ba8a99

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

src/ir441/exec.rs

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,28 @@ use crate::ir441::nodes::*;
77
pub enum ExecMode {
88
Unlimited,
99
MemCap { limit: u64 },
10-
GC { limit: u64 }
10+
GC { limit: u64 },
11+
LoggingGC { limit: u64 }
1112
}
1213
impl ExecMode {
1314
fn effective_cap(&self) -> u64 {
1415
match self {
1516
ExecMode::Unlimited => u64::MAX,
1617
ExecMode::MemCap {limit} => *limit,
17-
ExecMode::GC {limit} => *limit
18+
ExecMode::GC {limit} => *limit,
19+
ExecMode::LoggingGC {limit} => *limit
1820
}
1921
}
2022
fn is_gc(&self) -> bool {
2123
match self {
2224
ExecMode::GC{..} => true,
25+
ExecMode::LoggingGC{..} => true,
26+
_ => false
27+
}
28+
}
29+
fn is_logging_gc(&self) -> bool {
30+
match self {
31+
ExecMode::LoggingGC{..} => true,
2332
_ => false
2433
}
2534
}
@@ -107,7 +116,7 @@ impl <'a> Memory<'a> {
107116
fn gc(&mut self, locals: &mut Locals<'a>) -> Result<(),RuntimeError<'a>> {
108117
if !self.slot_cap.is_gc() {
109118
panic!("Error: GC triggered in a mode where GC header is not allocated!");
110-
} else {
119+
} else if self.slot_cap.is_logging_gc() {
111120
println!("Beginning GC")
112121
}
113122
// Simple copying collector.
@@ -121,16 +130,22 @@ impl <'a> Memory<'a> {
121130
self.allocations = HashSet::new();
122131
self.slots_alloced = 0;
123132
for (x,v) in locals.iter_mut() {
124-
println!("Tracing from root: {}={}", x, v);
133+
if self.slot_cap.is_logging_gc() {
134+
println!("Tracing from root: {}={}", x, v);
135+
}
125136
match v {
126137
VirtualVal::CodePtr {val} => (),
127138
VirtualVal::Data {val} => {
128139
if old_allocations.contains(val) {
129140
let newloc = self.trace(*val)?;
130-
println!("Moved {} from {} to {}", x, val, newloc);
141+
if self.slot_cap.is_logging_gc() {
142+
println!("Moved {} from {} to {}", x, val, newloc);
143+
}
131144
*v = VirtualVal::Data {val : newloc};
132145
} else {
133-
println!("Skipping {}={} b/c it does not appear to be a valid allocation", x, val);
146+
if self.slot_cap.is_logging_gc() {
147+
println!("Skipping {}={} b/c it does not appear to be a valid allocation", x, val);
148+
}
134149
}
135150
},
136151
VirtualVal::GCTombstone => panic!("Found GCTombstone in local variable slot: %{}", x)
@@ -142,8 +157,10 @@ impl <'a> Memory<'a> {
142157
self.map.insert(loc, VirtualVal::GCTombstone);
143158
}
144159
self.base = new_base;
145-
println!("Updated semispace base to {}, next alloc at {}", self.base, self.next_alloc);
146-
println!("Reduced memory consumption from {} to {} slots", was_alloced, self.slots_alloced);
160+
if self.slot_cap.is_logging_gc() {
161+
println!("Updated semispace base to {}, next alloc at {}", self.base, self.next_alloc);
162+
println!("Reduced memory consumption from {} to {} slots", was_alloced, self.slots_alloced);
163+
}
147164
Ok(())
148165
}
149166
fn reserve(&mut self, slots_including_metadata: u64) -> Result<u64,RuntimeError<'a>> {
@@ -164,11 +181,15 @@ impl <'a> Memory<'a> {
164181
let allocsize_loc = addr - 3*8;
165182
let fwd_ptr_loc = addr - 2*8;
166183
let slotmap_loc = addr - 8;
167-
println!("GC Tracing of {}", addr);
184+
if self.slot_cap.is_logging_gc() {
185+
println!("GC Tracing of {}", addr);
186+
}
168187
match self.map.get(&fwd_ptr_loc) {
169188
None => Err(RuntimeError::UnallocatedAddressRead { addr }),
170189
Some(VirtualVal::Data {val}) => {
171-
println!("Found address {} forwarded to {}", addr, val);
190+
if self.slot_cap.is_logging_gc() {
191+
println!("Found address {} forwarded to {}", addr, val);
192+
}
172193
if *val != 0 {
173194
assert!(self.map.contains_key(val));
174195
Ok(*val)
@@ -178,7 +199,9 @@ impl <'a> Memory<'a> {
178199
let allocsize = allocsizev.as_u64_or_else(|v| RuntimeError::CorruptGCMetadata {val:*v })?;
179200
let slotmapv = *self.map.get(&slotmap_loc).ok_or_else(|| RuntimeError::UnallocatedAddressRead { addr })?;
180201
let mut slotmap = slotmapv.as_u64_or_else(|v| RuntimeError::CorruptGCMetadata {val:*v })?;
181-
println!("Tracing {} with alloc size {} and slotmap {:X}", addr, allocsize, slotmap);
202+
if self.slot_cap.is_logging_gc() {
203+
println!("Tracing {} with alloc size {} and slotmap {:X}", addr, allocsize, slotmap);
204+
}
182205
let new_metadata_loc = self.reserve(allocsize)?;
183206
self.mem_store(new_metadata_loc, allocsizev)?;
184207
// Set new forwarding pointer to 0
@@ -200,7 +223,9 @@ impl <'a> Memory<'a> {
200223
VirtualVal::Data{val:to_trace} => self.trace(to_trace)
201224
}?;
202225
self.mem_store(new_obj_base + i*8, VirtualVal::Data { val: moved_to })?;
203-
println!("Rewrote slot {} from {} to {}", i, orig, moved_to);
226+
if self.slot_cap.is_logging_gc() {
227+
println!("Rewrote slot {} from {} to {}", i, orig, moved_to);
228+
}
204229
} else {
205230
// blind copy
206231
self.mem_store(new_obj_base + i*8, orig)?;
@@ -220,9 +245,12 @@ impl <'a> Memory<'a> {
220245
ExecMode::Unlimited => {return Ok(0)}, // unreachable since we checked it's not unlimited
221246
ExecMode::MemCap{..} => {return Err(RuntimeError::OutOfMemory)},
222247
ExecMode::GC{..} => {return Err(RuntimeError::GCRequired)},
248+
ExecMode::LoggingGC{..} => {return Err(RuntimeError::GCRequired)},
223249
}
224250
} else {
225-
println!("Alloc'ing {} slots on top of {} with cap {}", n, self.slots_alloced, self.slot_cap.effective_cap());
251+
if self.slot_cap.is_logging_gc() {
252+
println!("Alloc'ing {} slots on top of {} with cap {}", n, self.slots_alloced, self.slot_cap.effective_cap());
253+
}
226254
}
227255

228256
// Skip 8 bytes to catch some memory errors
@@ -421,12 +449,13 @@ fn run_code<'a>(prog: &'a IRProgram<'a>,
421449
IRStatement::Alloc { lhs: v, slots: n } => {
422450
let result = m.alloc((*n).into());
423451
if (result.is_ok()) {
424-
println!("Successful alloc");
425452
cycles.alloc();
426453
set_var(&mut locs, v, VirtualVal::Data { val: result.unwrap() })
427454
} else if result.is_err_with(|e| match e { RuntimeError::GCRequired => true, _ => false}){
428455
// GC, then try again
429-
println!("Triggering GC");
456+
if m.slot_cap.is_logging_gc() {
457+
println!("Triggering GC");
458+
}
430459
m.gc(&mut locs)?;
431460
let result = m.alloc((*n).into());
432461
match result {

src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ fn main() -> Result<(),Box<dyn std::error::Error>> {
9595
println!("Parsed: {}", prog);
9696
check_warnings(&prog);
9797
let _fresult = run_prog(&prog, false, &mut cycles, ExecMode::GC {limit:100});
98+
} else if cmd_str == "exec-gc-logging" {
99+
println!("Parsed: {}", prog);
100+
check_warnings(&prog);
101+
let _fresult = run_prog(&prog, false, &mut cycles, ExecMode::GC {limit:100});
98102
} else if cmd_str == "trace" {
99103
println!("Parsed: {}", prog);
100104
check_warnings(&prog);
@@ -105,7 +109,8 @@ fn main() -> Result<(),Box<dyn std::error::Error>> {
105109
let _ = run_prog(&prog, false, &mut cycles, ExecMode::Unlimited);
106110
println!("Execution stats:\n{:?}", cycles);
107111
} else {
108-
panic!("Unsupported command (possibly not-yet-implemented): {}", cmd);
112+
println!("Unsupported command (possibly not-yet-implemented): {}", cmd);
113+
panic!("Usage: ir441 (check|exec|exec-fixedmem|exec-gc|exec-gc-logging|trace|perf)");
109114
}
110115

111116
Ok(())

0 commit comments

Comments
 (0)