@@ -7,19 +7,28 @@ use crate::ir441::nodes::*;
7
7
pub enum ExecMode {
8
8
Unlimited ,
9
9
MemCap { limit : u64 } ,
10
- GC { limit : u64 }
10
+ GC { limit : u64 } ,
11
+ LoggingGC { limit : u64 }
11
12
}
12
13
impl ExecMode {
13
14
fn effective_cap ( & self ) -> u64 {
14
15
match self {
15
16
ExecMode :: Unlimited => u64:: MAX ,
16
17
ExecMode :: MemCap { limit} => * limit,
17
- ExecMode :: GC { limit} => * limit
18
+ ExecMode :: GC { limit} => * limit,
19
+ ExecMode :: LoggingGC { limit} => * limit
18
20
}
19
21
}
20
22
fn is_gc ( & self ) -> bool {
21
23
match self {
22
24
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 ,
23
32
_ => false
24
33
}
25
34
}
@@ -107,7 +116,7 @@ impl <'a> Memory<'a> {
107
116
fn gc ( & mut self , locals : & mut Locals < ' a > ) -> Result < ( ) , RuntimeError < ' a > > {
108
117
if !self . slot_cap . is_gc ( ) {
109
118
panic ! ( "Error: GC triggered in a mode where GC header is not allocated!" ) ;
110
- } else {
119
+ } else if self . slot_cap . is_logging_gc ( ) {
111
120
println ! ( "Beginning GC" )
112
121
}
113
122
// Simple copying collector.
@@ -121,16 +130,22 @@ impl <'a> Memory<'a> {
121
130
self . allocations = HashSet :: new ( ) ;
122
131
self . slots_alloced = 0 ;
123
132
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
+ }
125
136
match v {
126
137
VirtualVal :: CodePtr { val} => ( ) ,
127
138
VirtualVal :: Data { val} => {
128
139
if old_allocations. contains ( val) {
129
140
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
+ }
131
144
* v = VirtualVal :: Data { val : newloc} ;
132
145
} 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
+ }
134
149
}
135
150
} ,
136
151
VirtualVal :: GCTombstone => panic ! ( "Found GCTombstone in local variable slot: %{}" , x)
@@ -142,8 +157,10 @@ impl <'a> Memory<'a> {
142
157
self . map . insert ( loc, VirtualVal :: GCTombstone ) ;
143
158
}
144
159
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
+ }
147
164
Ok ( ( ) )
148
165
}
149
166
fn reserve ( & mut self , slots_including_metadata : u64 ) -> Result < u64 , RuntimeError < ' a > > {
@@ -164,11 +181,15 @@ impl <'a> Memory<'a> {
164
181
let allocsize_loc = addr - 3 * 8 ;
165
182
let fwd_ptr_loc = addr - 2 * 8 ;
166
183
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
+ }
168
187
match self . map . get ( & fwd_ptr_loc) {
169
188
None => Err ( RuntimeError :: UnallocatedAddressRead { addr } ) ,
170
189
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
+ }
172
193
if * val != 0 {
173
194
assert ! ( self . map. contains_key( val) ) ;
174
195
Ok ( * val)
@@ -178,7 +199,9 @@ impl <'a> Memory<'a> {
178
199
let allocsize = allocsizev. as_u64_or_else ( |v| RuntimeError :: CorruptGCMetadata { val : * v } ) ?;
179
200
let slotmapv = * self . map . get ( & slotmap_loc) . ok_or_else ( || RuntimeError :: UnallocatedAddressRead { addr } ) ?;
180
201
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
+ }
182
205
let new_metadata_loc = self . reserve ( allocsize) ?;
183
206
self . mem_store ( new_metadata_loc, allocsizev) ?;
184
207
// Set new forwarding pointer to 0
@@ -200,7 +223,9 @@ impl <'a> Memory<'a> {
200
223
VirtualVal :: Data { val : to_trace} => self . trace ( to_trace)
201
224
} ?;
202
225
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
+ }
204
229
} else {
205
230
// blind copy
206
231
self . mem_store ( new_obj_base + i* 8 , orig) ?;
@@ -220,9 +245,12 @@ impl <'a> Memory<'a> {
220
245
ExecMode :: Unlimited => { return Ok ( 0 ) } , // unreachable since we checked it's not unlimited
221
246
ExecMode :: MemCap { ..} => { return Err ( RuntimeError :: OutOfMemory ) } ,
222
247
ExecMode :: GC { ..} => { return Err ( RuntimeError :: GCRequired ) } ,
248
+ ExecMode :: LoggingGC { ..} => { return Err ( RuntimeError :: GCRequired ) } ,
223
249
}
224
250
} 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
+ }
226
254
}
227
255
228
256
// Skip 8 bytes to catch some memory errors
@@ -421,12 +449,13 @@ fn run_code<'a>(prog: &'a IRProgram<'a>,
421
449
IRStatement :: Alloc { lhs : v, slots : n } => {
422
450
let result = m. alloc ( ( * n) . into ( ) ) ;
423
451
if ( result. is_ok ( ) ) {
424
- println ! ( "Successful alloc" ) ;
425
452
cycles. alloc ( ) ;
426
453
set_var ( & mut locs, v, VirtualVal :: Data { val : result. unwrap ( ) } )
427
454
} else if result. is_err_with ( |e| match e { RuntimeError :: GCRequired => true , _ => false } ) {
428
455
// GC, then try again
429
- println ! ( "Triggering GC" ) ;
456
+ if m. slot_cap . is_logging_gc ( ) {
457
+ println ! ( "Triggering GC" ) ;
458
+ }
430
459
m. gc ( & mut locs) ?;
431
460
let result = m. alloc ( ( * n) . into ( ) ) ;
432
461
match result {
0 commit comments