VM: removes the template parameter from mark_bits

since mark_bits only deals with arithmetic on memory addresses, it
doesn't need to be specialized so it can be untemplateized
db4
Björn Lindqvist 2015-01-06 17:58:24 +01:00
parent af270cb4d8
commit 1beac119d8
8 changed files with 68 additions and 62 deletions

View File

@ -40,11 +40,11 @@ bool code_heap::uninitialized_p(code_block* compiled) {
} }
bool code_heap::marked_p(code_block* compiled) { bool code_heap::marked_p(code_block* compiled) {
return allocator->state.marked_p(compiled); return allocator->state.marked_p((cell)compiled);
} }
void code_heap::set_marked_p(code_block* compiled) { void code_heap::set_marked_p(code_block* compiled) {
allocator->state.set_marked_p(compiled); allocator->state.set_marked_p((cell)compiled, compiled->size());
} }
void code_heap::clear_mark_bits() { allocator->state.clear_mark_bits(); } void code_heap::clear_mark_bits() { allocator->state.clear_mark_bits(); }

View File

@ -5,13 +5,13 @@ namespace factor {
struct compaction_fixup { struct compaction_fixup {
static const bool translated_code_block_map = false; static const bool translated_code_block_map = false;
mark_bits<object>* data_forwarding_map; mark_bits* data_forwarding_map;
mark_bits<code_block>* code_forwarding_map; mark_bits* code_forwarding_map;
const object** data_finger; const object** data_finger;
const code_block** code_finger; const code_block** code_finger;
compaction_fixup(mark_bits<object>* data_forwarding_map, compaction_fixup(mark_bits* data_forwarding_map,
mark_bits<code_block>* code_forwarding_map, mark_bits* code_forwarding_map,
const object** data_finger, const object** data_finger,
const code_block** code_finger) const code_block** code_finger)
: data_forwarding_map(data_forwarding_map), : data_forwarding_map(data_forwarding_map),
@ -20,11 +20,11 @@ struct compaction_fixup {
code_finger(code_finger) {} code_finger(code_finger) {}
object* fixup_data(object* obj) { object* fixup_data(object* obj) {
return data_forwarding_map->forward_block(obj); return (object*)data_forwarding_map->forward_block((cell)obj);
} }
code_block* fixup_code(code_block* compiled) { code_block* fixup_code(code_block* compiled) {
return code_forwarding_map->forward_block(compiled); return (code_block*)code_forwarding_map->forward_block((cell)compiled);
} }
object* translate_data(const object* obj) { object* translate_data(const object* obj) {
@ -42,17 +42,17 @@ struct compaction_fixup {
} }
cell size(object* obj) { cell size(object* obj) {
if (data_forwarding_map->marked_p(obj)) if (data_forwarding_map->marked_p((cell)obj))
return obj->size(*this); return obj->size(*this);
else else
return data_forwarding_map->unmarked_block_size(obj); return data_forwarding_map->unmarked_block_size((cell)obj);
} }
cell size(code_block* compiled) { cell size(code_block* compiled) {
if (code_forwarding_map->marked_p(compiled)) if (code_forwarding_map->marked_p((cell)compiled))
return compiled->size(*this); return compiled->size(*this);
else else
return code_forwarding_map->unmarked_block_size(compiled); return code_forwarding_map->unmarked_block_size((cell)compiled);
} }
}; };
@ -152,18 +152,18 @@ void factor_vm::update_code_roots_for_compaction() {
std::vector<code_root*>::const_iterator iter = code_roots.begin(); std::vector<code_root*>::const_iterator iter = code_roots.begin();
std::vector<code_root*>::const_iterator end = code_roots.end(); std::vector<code_root*>::const_iterator end = code_roots.end();
mark_bits<code_block>* state = &code->allocator->state; mark_bits* state = &code->allocator->state;
for (; iter < end; iter++) { for (; iter < end; iter++) {
code_root* root = *iter; code_root* root = *iter;
code_block* block = (code_block*)(root->value & (~data_alignment + 1)); cell block = root->value & (~data_alignment + 1);
/* Offset of return address within 16-byte allocation line */ /* Offset of return address within 16-byte allocation line */
cell offset = root->value - (cell)block; cell offset = root->value - block;
if (root->valid && state->marked_p(block)) { if (root->valid && state->marked_p(block)) {
block = state->forward_block(block); block = state->forward_block(block);
root->value = (cell)block + offset; root->value = block + offset;
} else } else
root->valid = false; root->valid = false;
} }
@ -181,8 +181,8 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) {
event->started_compaction(); event->started_compaction();
tenured_space* tenured = data->tenured; tenured_space* tenured = data->tenured;
mark_bits<object>* data_forwarding_map = &tenured->state; mark_bits* data_forwarding_map = &tenured->state;
mark_bits<code_block>* code_forwarding_map = &code->allocator->state; mark_bits* code_forwarding_map = &code->allocator->state;
/* Figure out where blocks are going to go */ /* Figure out where blocks are going to go */
data_forwarding_map->compute_forwarding(); data_forwarding_map->compute_forwarding();
@ -237,17 +237,17 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) {
struct code_compaction_fixup { struct code_compaction_fixup {
static const bool translated_code_block_map = false; static const bool translated_code_block_map = false;
mark_bits<code_block>* code_forwarding_map; mark_bits* code_forwarding_map;
const code_block** code_finger; const code_block** code_finger;
code_compaction_fixup(mark_bits<code_block>* code_forwarding_map, code_compaction_fixup(mark_bits* code_forwarding_map,
const code_block** code_finger) const code_block** code_finger)
: code_forwarding_map(code_forwarding_map), code_finger(code_finger) {} : code_forwarding_map(code_forwarding_map), code_finger(code_finger) {}
object* fixup_data(object* obj) { return obj; } object* fixup_data(object* obj) { return obj; }
code_block* fixup_code(code_block* compiled) { code_block* fixup_code(code_block* compiled) {
return code_forwarding_map->forward_block(compiled); return (code_block*)code_forwarding_map->forward_block((cell)compiled);
} }
object* translate_data(const object* obj) { return fixup_data((object*)obj); } object* translate_data(const object* obj) { return fixup_data((object*)obj); }
@ -262,10 +262,10 @@ struct code_compaction_fixup {
cell size(object* obj) { return obj->size(); } cell size(object* obj) { return obj->size(); }
cell size(code_block* compiled) { cell size(code_block* compiled) {
if (code_forwarding_map->marked_p(compiled)) if (code_forwarding_map->marked_p((cell)compiled))
return compiled->size(*this); return compiled->size(*this);
else else
return code_forwarding_map->unmarked_block_size(compiled); return code_forwarding_map->unmarked_block_size((cell)compiled);
} }
}; };
@ -282,7 +282,7 @@ struct object_grow_heap_updater {
/* Compact just the code heap, after growing the data heap */ /* Compact just the code heap, after growing the data heap */
void factor_vm::collect_compact_code_impl(bool trace_contexts_p) { void factor_vm::collect_compact_code_impl(bool trace_contexts_p) {
/* Figure out where blocks are going to go */ /* Figure out where blocks are going to go */
mark_bits<code_block>* code_forwarding_map = &code->allocator->state; mark_bits* code_forwarding_map = &code->allocator->state;
code_forwarding_map->compute_forwarding(); code_forwarding_map->compute_forwarding();
const code_block* code_finger = code->allocator->first_block(); const code_block* code_finger = code->allocator->first_block();

View File

@ -13,7 +13,7 @@ template <typename Block> struct free_list_allocator {
cell start; cell start;
cell end; cell end;
free_list free_blocks; free_list free_blocks;
mark_bits<Block> state; mark_bits state;
free_list_allocator(cell size, cell start); free_list_allocator(cell size, cell start);
void initial_free_list(cell occupied); void initial_free_list(cell occupied);
@ -44,7 +44,7 @@ free_list_allocator<Block>::free_list_allocator(cell size, cell start)
: size(size), : size(size),
start(start), start(start),
end(start + size), end(start + size),
state(mark_bits<Block>(size, start)) { state(mark_bits(size, start)) {
initial_free_list(0); initial_free_list(0);
} }
@ -128,8 +128,8 @@ template <typename Iterator>
void free_list_allocator<Block>::sweep(Iterator& iter) { void free_list_allocator<Block>::sweep(Iterator& iter) {
free_blocks.clear_free_list(); free_blocks.clear_free_list();
Block* start = this->first_block(); cell start = (cell)this->first_block();
Block* end = this->last_block(); cell end = (cell)this->last_block();
while (start != end) { while (start != end) {
/* find next unmarked block */ /* find next unmarked block */
@ -143,9 +143,9 @@ void free_list_allocator<Block>::sweep(Iterator& iter) {
free_heap_block* free_block = (free_heap_block*)start; free_heap_block* free_block = (free_heap_block*)start;
free_block->make_free(size); free_block->make_free(size);
free_blocks.add_to_free_list(free_block); free_blocks.add_to_free_list(free_block);
iter(start, size); iter((Block*)start, size);
start = (Block*)((char*)start + size); start = start + size;
} }
} }
} }
@ -160,17 +160,17 @@ template <typename Block> void free_list_allocator<Block>::sweep() {
} }
template <typename Block, typename Iterator> struct heap_compactor { template <typename Block, typename Iterator> struct heap_compactor {
mark_bits<Block>* state; mark_bits* state;
char* address; char* address;
Iterator& iter; Iterator& iter;
const Block** finger; const Block** finger;
heap_compactor(mark_bits<Block>* state, Block* address, heap_compactor(mark_bits* state, Block* address,
Iterator& iter, const Block** finger) Iterator& iter, const Block** finger)
: state(state), address((char*)address), iter(iter), finger(finger) {} : state(state), address((char*)address), iter(iter), finger(finger) {}
void operator()(Block* block, cell size) { void operator()(Block* block, cell size) {
if (this->state->marked_p(block)) { if (this->state->marked_p((cell)block)) {
*finger = (Block*)((char*)block + size); *finger = (Block*)((char*)block + size);
memmove((Block*)address, block, size); memmove((Block*)address, block, size);
iter(block, (Block*)address, size); iter(block, (Block*)address, size);

View File

@ -21,11 +21,11 @@ void factor_vm::update_code_roots_for_sweep() {
std::vector<code_root*>::const_iterator iter = code_roots.begin(); std::vector<code_root*>::const_iterator iter = code_roots.begin();
std::vector<code_root*>::const_iterator end = code_roots.end(); std::vector<code_root*>::const_iterator end = code_roots.end();
mark_bits<code_block>* state = &code->allocator->state; mark_bits* state = &code->allocator->state;
for (; iter < end; iter++) { for (; iter < end; iter++) {
code_root* root = *iter; code_root* root = *iter;
code_block* block = (code_block*)(root->value & (~data_alignment - 1)); cell block = root->value & (~data_alignment - 1);
if (root->valid && !state->marked_p(block)) if (root->valid && !state->marked_p(block))
root->valid = false; root->valid = false;
} }

View File

@ -3,7 +3,7 @@ namespace factor {
const int mark_bits_granularity = sizeof(cell) * 8; const int mark_bits_granularity = sizeof(cell) * 8;
const int mark_bits_mask = sizeof(cell) * 8 - 1; const int mark_bits_mask = sizeof(cell) * 8 - 1;
template <typename Block> struct mark_bits { struct mark_bits {
cell size; cell size;
cell start; cell start;
cell bits_size; cell bits_size;
@ -31,33 +31,33 @@ template <typename Block> struct mark_bits {
forwarding = NULL; forwarding = NULL;
} }
cell block_line(const Block* address) { cell block_line(cell address) {
return (((cell)address - start) / data_alignment); return (address - start) / data_alignment;
} }
Block* line_block(cell line) { cell line_block(cell line) {
return (Block*)(line * data_alignment + start); return line * data_alignment + start;
} }
std::pair<cell, cell> bitmap_deref(const Block* address) { std::pair<cell, cell> bitmap_deref(const cell address) {
cell line_number = block_line(address); cell line_number = block_line(address);
cell word_index = (line_number / mark_bits_granularity); cell word_index = (line_number / mark_bits_granularity);
cell word_shift = (line_number & mark_bits_mask); cell word_shift = (line_number & mark_bits_mask);
return std::make_pair(word_index, word_shift); return std::make_pair(word_index, word_shift);
} }
bool bitmap_elt(cell* bits, const Block* address) { bool bitmap_elt(cell* bits, const cell address) {
std::pair<cell, cell> position = bitmap_deref(address); std::pair<cell, cell> position = bitmap_deref(address);
return (bits[position.first] & ((cell)1 << position.second)) != 0; return (bits[position.first] & ((cell)1 << position.second)) != 0;
} }
Block* next_block_after(const Block* block) { cell next_block_after(const cell block, const cell size) {
return (Block*)((cell)block + block->size()); return block + size;
} }
void set_bitmap_range(cell* bits, const Block* address) { void set_bitmap_range(cell* bits, const cell address, const cell size) {
std::pair<cell, cell> start = bitmap_deref(address); std::pair<cell, cell> start = bitmap_deref(address);
std::pair<cell, cell> end = bitmap_deref(next_block_after(address)); std::pair<cell, cell> end = bitmap_deref(next_block_after(address, size));
cell start_mask = ((cell)1 << start.second) - 1; cell start_mask = ((cell)1 << start.second) - 1;
cell end_mask = ((cell)1 << end.second) - 1; cell end_mask = ((cell)1 << end.second) - 1;
@ -78,9 +78,11 @@ template <typename Block> struct mark_bits {
} }
} }
bool marked_p(const Block* address) { return bitmap_elt(marked, address); } bool marked_p(const cell address) { return bitmap_elt(marked, address); }
void set_marked_p(const Block* address) { set_bitmap_range(marked, address); } void set_marked_p(const cell address, const cell size) {
set_bitmap_range(marked, address, size);
}
/* The eventual destination of a block after compaction is just the number /* The eventual destination of a block after compaction is just the number
of marked blocks before it. Live blocks must be marked on entry. */ of marked blocks before it. Live blocks must be marked on entry. */
@ -94,22 +96,22 @@ template <typename Block> struct mark_bits {
/* We have the popcount for every mark_bits_granularity entries; look /* We have the popcount for every mark_bits_granularity entries; look
up and compute the rest */ up and compute the rest */
Block* forward_block(const Block* original) { cell forward_block(const cell original) {
FACTOR_ASSERT(marked_p(original)); FACTOR_ASSERT(marked_p(original));
std::pair<cell, cell> position = bitmap_deref(original); std::pair<cell, cell> position = bitmap_deref(original);
cell offset = (cell)original & (data_alignment - 1); cell offset = original & (data_alignment - 1);
cell approx_popcount = forwarding[position.first]; cell approx_popcount = forwarding[position.first];
cell mask = ((cell)1 << position.second) - 1; cell mask = ((cell)1 << position.second) - 1;
cell new_line_number = cell new_line_number =
approx_popcount + popcount(marked[position.first] & mask); approx_popcount + popcount(marked[position.first] & mask);
Block* new_block = (Block*)((char*)line_block(new_line_number) + offset); cell new_block = line_block(new_line_number) + offset;
FACTOR_ASSERT(new_block <= original); FACTOR_ASSERT(new_block <= original);
return new_block; return new_block;
} }
Block* next_unmarked_block_after(const Block* original) { cell next_unmarked_block_after(const cell original) {
std::pair<cell, cell> position = bitmap_deref(original); std::pair<cell, cell> position = bitmap_deref(original);
cell bit_index = position.second; cell bit_index = position.second;
@ -127,10 +129,10 @@ template <typename Block> struct mark_bits {
} }
/* No unmarked blocks were found */ /* No unmarked blocks were found */
return (Block*)(this->start + this->size); return this->start + this->size;
} }
Block* next_marked_block_after(const Block* original) { cell next_marked_block_after(const cell original) {
std::pair<cell, cell> position = bitmap_deref(original); std::pair<cell, cell> position = bitmap_deref(original);
cell bit_index = position.second; cell bit_index = position.second;
@ -147,12 +149,12 @@ template <typename Block> struct mark_bits {
} }
/* No marked blocks were found */ /* No marked blocks were found */
return (Block*)(this->start + this->size); return this->start + this->size;
} }
cell unmarked_block_size(Block* original) { cell unmarked_block_size(cell original) {
Block* next_marked = next_marked_block_after(original); cell next_marked = next_marked_block_after(original);
return ((char*)next_marked - (char*)original); return next_marked - original;
} }
}; };

View File

@ -58,7 +58,7 @@ void object_start_map::update_card_for_sweep(cell index, uint16_t mask) {
} }
} }
void object_start_map::update_for_sweep(mark_bits<object>* state) { void object_start_map::update_for_sweep(mark_bits* state) {
for (cell index = 0; index < state->bits_size; index++) { for (cell index = 0; index < state->bits_size; index++) {
cell mask = state->marked[index]; cell mask = state->marked[index];
#ifdef FACTOR_64 #ifdef FACTOR_64

View File

@ -15,7 +15,7 @@ struct object_start_map {
void record_object_start_offset(object* obj); void record_object_start_offset(object* obj);
void clear_object_start_offsets(); void clear_object_start_offsets();
void update_card_for_sweep(cell index, uint16_t mask); void update_card_for_sweep(cell index, uint16_t mask);
void update_for_sweep(mark_bits<object>* state); void update_for_sweep(mark_bits* state);
}; };
} }

View File

@ -27,9 +27,13 @@ struct tenured_space : free_list_allocator<object> {
void clear_mark_bits() { state.clear_mark_bits(); } void clear_mark_bits() { state.clear_mark_bits(); }
bool marked_p(object* obj) { return this->state.marked_p(obj); } bool marked_p(object* obj) {
return this->state.marked_p((cell)obj);
}
void set_marked_p(object* obj) { this->state.set_marked_p(obj); } void set_marked_p(object* obj) {
this->state.set_marked_p((cell)obj, obj->size());
}
void sweep() { void sweep() {
free_list_allocator<object>::sweep(); free_list_allocator<object>::sweep();