vm: debugging mark and sweep

db4
Slava Pestov 2009-10-21 23:24:35 -05:00
parent 40351d40be
commit 606a805d7d
7 changed files with 24 additions and 28 deletions

View File

@ -15,7 +15,6 @@ inline void factor_vm::set_array_nth(array *array, cell slot, cell value)
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
assert(slot < array_capacity(array)); assert(slot < array_capacity(array));
assert(array->h.hi_tag() == ARRAY_TYPE); assert(array->h.hi_tag() == ARRAY_TYPE);
check_tagged_pointer(value);
#endif #endif
cell *slot_ptr = &array->data()[slot]; cell *slot_ptr = &array->data()[slot];
*slot_ptr = value; *slot_ptr = value;

View File

@ -22,7 +22,7 @@ template<typename Block> struct free_list_allocator {
Block *next_block_after(Block *block); Block *next_block_after(Block *block);
void clear_free_list(); void clear_free_list();
void add_to_free_list(free_heap_block *block); void add_to_free_list(free_heap_block *block);
void build_free_list(cell size); void initial_free_list(cell size);
void assert_free_block(free_heap_block *block); void assert_free_block(free_heap_block *block);
free_heap_block *find_free_block(cell size); free_heap_block *find_free_block(cell size);
free_heap_block *split_free_block(free_heap_block *block, cell size); free_heap_block *split_free_block(free_heap_block *block, cell size);
@ -40,7 +40,7 @@ template<typename Block>
free_list_allocator<Block>::free_list_allocator(cell size_, cell start_) : free_list_allocator<Block>::free_list_allocator(cell size_, cell start_) :
size(size_), start(start_), end(start_ + size_), state(mark_bits<Block>(size_,start_)) size(size_), start(start_), end(start_ + size_), state(mark_bits<Block>(size_,start_))
{ {
clear_free_list(); initial_free_list(0);
} }
template<typename Block> void free_list_allocator<Block>::clear_free_list() template<typename Block> void free_list_allocator<Block>::clear_free_list()
@ -85,7 +85,7 @@ template<typename Block> void free_list_allocator<Block>::add_to_free_list(free_
/* Called after reading the heap from the image file, and after heap compaction. /* Called after reading the heap from the image file, and after heap compaction.
Makes a free list consisting of one free block, at the very end. */ Makes a free list consisting of one free block, at the very end. */
template<typename Block> void free_list_allocator<Block>::build_free_list(cell size) template<typename Block> void free_list_allocator<Block>::initial_free_list(cell size)
{ {
clear_free_list(); clear_free_list();
if(size != this->size) if(size != this->size)
@ -345,7 +345,7 @@ void free_list_allocator<Block>::compact(Iterator &iter)
/* Now update the free list; there will be a single free block at /* Now update the free list; there will be a single free block at
the end */ the end */
this->build_free_list((cell)compactor.address - this->start); this->initial_free_list((cell)compactor.address - this->start);
} }
template<typename Block> template<typename Block>

View File

@ -60,12 +60,12 @@ void factor_vm::gc(gc_op op,
current_gc->op = collect_growing_heap_op; current_gc->op = collect_growing_heap_op;
break; break;
default: default:
critical_error("Bad GC op\n",op); critical_error("Bad GC op",current_gc->op);
break; break;
} }
if(verbosegc) if(verbosegc)
std::cout << "GC rewind, op=" << op << std::endl; std::cout << "GC rewind, op=" << current_gc->op << std::endl;
} }
switch(current_gc->op) switch(current_gc->op)
@ -91,20 +91,20 @@ void factor_vm::gc(gc_op op,
record_gc_stats(&gc_stats.full_stats); record_gc_stats(&gc_stats.full_stats);
break; break;
default: default:
critical_error("Bad GC op\n",op); critical_error("Bad GC op\n",current_gc->op);
break; break;
} }
if(verbosegc)
std::cout << "GC done, op=" << current_gc->op << std::endl;
delete current_gc; delete current_gc;
current_gc = NULL; current_gc = NULL;
if(verbosegc)
std::cout << "GC done, op=" << op << std::endl;
} }
void factor_vm::primitive_minor_gc() void factor_vm::primitive_minor_gc()
{ {
gc(collect_full_op, gc(collect_nursery_op,
0, /* requested size */ 0, /* requested size */
true, /* trace contexts? */ true, /* trace contexts? */
false /* compact code heap? */); false /* compact code heap? */);

View File

@ -36,7 +36,7 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
fatal_error("load_data_heap failed",0); fatal_error("load_data_heap failed",0);
} }
data->tenured->build_free_list(h->data_size); data->tenured->initial_free_list(h->data_size);
} }
void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p) void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p)
@ -57,7 +57,7 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p)
} }
} }
code->allocator->build_free_list(h->code_size); code->allocator->initial_free_list(h->code_size);
} }
void factor_vm::data_fixup(cell *handle, cell data_relocation_base) void factor_vm::data_fixup(cell *handle, cell data_relocation_base)

View File

@ -6,7 +6,7 @@ struct gc_root : public tagged<Type>
{ {
factor_vm *parent; factor_vm *parent;
void push() { parent->check_tagged_pointer(tagged<Type>::value()); parent->gc_locals.push_back((cell)this); } void push() { parent->gc_locals.push_back((cell)this); }
explicit gc_root(cell value_,factor_vm *vm) : tagged<Type>(value_),parent(vm) { push(); } explicit gc_root(cell value_,factor_vm *vm) : tagged<Type>(value_),parent(vm) { push(); }
explicit gc_root(Type *value_, factor_vm *vm) : tagged<Type>(value_),parent(vm) { push(); } explicit gc_root(Type *value_, factor_vm *vm) : tagged<Type>(value_),parent(vm) { push(); }

View File

@ -81,14 +81,23 @@ template<typename Block> struct mark_bits {
bits[start.first] |= start_mask ^ end_mask; bits[start.first] |= start_mask ^ end_mask;
else else
{ {
#ifdef FACTOR_DEBUG
assert(start.first < bits_size);
#endif
bits[start.first] |= ~start_mask; bits[start.first] |= ~start_mask;
for(cell index = start.first + 1; index < end.first; index++) for(cell index = start.first + 1; index < end.first; index++)
bits[index] = (u64)-1; bits[index] = (u64)-1;
if(end_mask != 0)
{
#ifdef FACTOR_DEBUG
assert(end.first < bits_size);
#endif
bits[end.first] |= end_mask; bits[end.first] |= end_mask;
} }
} }
}
bool marked_p(Block *address) bool marked_p(Block *address)
{ {

View File

@ -280,18 +280,6 @@ struct factor_vm
#endif #endif
} }
inline void check_tagged_pointer(cell tagged)
{
#ifdef FACTOR_DEBUG
if(!immediate_p(tagged))
{
object *obj = untag<object>(tagged);
check_data_pointer(obj);
obj->h.hi_tag();
}
#endif
}
// generic arrays // generic arrays
template<typename Array> Array *allot_uninitialized_array(cell capacity); template<typename Array> Array *allot_uninitialized_array(cell capacity);
template<typename Array> bool reallot_array_in_place_p(Array *array, cell capacity); template<typename Array> bool reallot_array_in_place_p(Array *array, cell capacity);