VM: move changes of structs to lambda functions

db4
Björn Lindqvist 2015-07-06 18:31:44 +02:00
parent 365b39e0cc
commit 4dfac78fc1
5 changed files with 63 additions and 138 deletions

View File

@ -49,43 +49,25 @@ void code_heap::free(code_block* compiled) {
void code_heap::flush_icache() { factor::flush_icache(seg->start, seg->size); } void code_heap::flush_icache() { factor::flush_icache(seg->start, seg->size); }
struct clear_free_blocks_from_all_blocks_iterator {
code_heap* code;
clear_free_blocks_from_all_blocks_iterator(code_heap* code) : code(code) {}
void operator()(code_block* free_block, cell size) {
std::set<cell>::iterator erase_from =
code->all_blocks.lower_bound((cell)free_block);
std::set<cell>::iterator erase_to =
code->all_blocks.lower_bound((cell)free_block + size);
code->all_blocks.erase(erase_from, erase_to);
}
};
void code_heap::sweep() { void code_heap::sweep() {
clear_free_blocks_from_all_blocks_iterator clearer(this); auto clear_free_blocks_from_all_blocks = [&](code_block* block, cell size) {
allocator->sweep(clearer); std::set<cell>::iterator erase_from =
all_blocks.lower_bound((cell)block);
std::set<cell>::iterator erase_to =
all_blocks.lower_bound((cell)block + size);
all_blocks.erase(erase_from, erase_to);
};
allocator->sweep(clear_free_blocks_from_all_blocks);
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
verify_all_blocks_set(); verify_all_blocks_set();
#endif #endif
} }
struct all_blocks_set_verifier {
std::set<cell>* all_blocks;
all_blocks_set_verifier(std::set<cell>* all_blocks)
: all_blocks(all_blocks) {}
void operator()(code_block* block, cell size) {
FACTOR_ASSERT(all_blocks->find((cell)block) != all_blocks->end());
}
};
void code_heap::verify_all_blocks_set() { void code_heap::verify_all_blocks_set() {
all_blocks_set_verifier verifier(&all_blocks); auto all_blocks_set_verifier = [&](code_block* block, cell size) {
allocator->iterate(verifier); all_blocks.find((cell)block) != all_blocks.end();
};
allocator->iterate(all_blocks_set_verifier);
} }
code_block* code_heap::code_block_for_address(cell address) { code_block* code_heap::code_block_for_address(cell address) {
@ -101,20 +83,12 @@ code_block* code_heap::code_block_for_address(cell address) {
return found_block; return found_block;
} }
struct all_blocks_set_inserter {
code_heap* code;
all_blocks_set_inserter(code_heap* code) : code(code) {}
void operator()(code_block* block, cell size) {
code->all_blocks.insert((cell)block);
}
};
void code_heap::initialize_all_blocks_set() { void code_heap::initialize_all_blocks_set() {
all_blocks.clear(); all_blocks.clear();
all_blocks_set_inserter inserter(this); auto all_blocks_set_inserter = [&](code_block* block, cell size) {
allocator->iterate(inserter); all_blocks.insert((cell)block);
};
allocator->iterate(all_blocks_set_inserter);
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
verify_all_blocks_set(); verify_all_blocks_set();
#endif #endif
@ -123,24 +97,14 @@ void code_heap::initialize_all_blocks_set() {
/* Allocate a code heap during startup */ /* Allocate a code heap during startup */
void factor_vm::init_code_heap(cell size) { code = new code_heap(size); } void factor_vm::init_code_heap(cell size) { code = new code_heap(size); }
struct word_updater {
factor_vm* parent;
bool reset_inline_caches;
word_updater(factor_vm* parent, bool reset_inline_caches)
: parent(parent), reset_inline_caches(reset_inline_caches) {}
void operator()(code_block* compiled, cell size) {
parent->update_word_references(compiled, reset_inline_caches);
}
};
/* Update pointers to words referenced from all code blocks. /* Update pointers to words referenced from all code blocks.
Only needed after redefining an existing word. Only needed after redefining an existing word.
If generic words were redefined, inline caches need to be reset. */ If generic words were redefined, inline caches need to be reset. */
void factor_vm::update_code_heap_words(bool reset_inline_caches) { void factor_vm::update_code_heap_words(bool reset_inline_caches) {
word_updater updater(this, reset_inline_caches); auto word_updater = [&](code_block* block, cell size) {
each_code_block(updater); update_word_references(block, reset_inline_caches);
};
each_code_block(word_updater);
} }
/* Fix up new words only. /* Fix up new words only.
@ -207,29 +171,24 @@ void factor_vm::primitive_code_room() {
ctx->push(tag<byte_array>(byte_array_from_value(&room))); ctx->push(tag<byte_array>(byte_array_from_value(&room)));
} }
struct stack_trace_stripper {
stack_trace_stripper() {}
void operator()(code_block* compiled, cell size) {
compiled->owner = false_object;
}
};
void factor_vm::primitive_strip_stack_traces() { void factor_vm::primitive_strip_stack_traces() {
stack_trace_stripper stripper; auto stack_trace_stripper = [](code_block* block, cell size) {
each_code_block(stripper); block->owner = false_object;
};
each_code_block(stack_trace_stripper);
} }
struct code_block_accumulator { /* Allocates memory */
cell factor_vm::code_blocks() {
std::vector<cell> objects; std::vector<cell> objects;
void operator()(code_block* compiled, cell size) { auto code_block_accumulator = [&](code_block* block, cell size) {
objects.push_back(compiled->owner); objects.push_back(block->owner);
objects.push_back(compiled->parameters); objects.push_back(block->parameters);
objects.push_back(compiled->relocation); objects.push_back(block->relocation);
objects.push_back(tag_fixnum(compiled->type())); objects.push_back(tag_fixnum(block->type()));
objects.push_back(tag_fixnum(compiled->size())); objects.push_back(tag_fixnum(block->size()));
/* Note: the entry point is always a multiple of the heap /* Note: the entry point is always a multiple of the heap
alignment (16 bytes). We cannot allocate while iterating alignment (16 bytes). We cannot allocate while iterating
@ -237,18 +196,13 @@ struct code_block_accumulator {
from_unsigned_cell() here. It is OK, however, to add it as from_unsigned_cell() here. It is OK, however, to add it as
if it were a fixnum, and have library code shift it to the if it were a fixnum, and have library code shift it to the
left by 4. */ left by 4. */
cell entry_point = compiled->entry_point(); cell entry_point = block->entry_point();
FACTOR_ASSERT((entry_point & (data_alignment - 1)) == 0); FACTOR_ASSERT((entry_point & (data_alignment - 1)) == 0);
FACTOR_ASSERT((entry_point & TAG_MASK) == FIXNUM_TYPE); FACTOR_ASSERT((entry_point & TAG_MASK) == FIXNUM_TYPE);
objects.push_back(entry_point); objects.push_back(entry_point);
} };
}; each_code_block(code_block_accumulator);
return std_vector_to_array(objects);
/* Allocates memory */
cell factor_vm::code_blocks() {
code_block_accumulator accum;
each_code_block(accum);
return std_vector_to_array(accum.objects);
} }
/* Allocates memory */ /* Allocates memory */

View File

@ -143,24 +143,17 @@ void factor_vm::primitive_data_room() {
ctx->push(tag<byte_array>(byte_array_from_value(&room))); ctx->push(tag<byte_array>(byte_array_from_value(&room)));
} }
struct object_accumulator {
cell type;
std::vector<cell> objects;
explicit object_accumulator(cell type) : type(type) {}
void operator()(object* obj) {
if (type == TYPE_COUNT || obj->type() == type)
objects.push_back(tag_dynamic(obj));
}
};
/* Allocates memory */ /* Allocates memory */
cell factor_vm::instances(cell type) { cell factor_vm::instances(cell type) {
primitive_full_gc(); primitive_full_gc();
object_accumulator accum(type);
each_object(accum); std::vector<cell> objects;
return std_vector_to_array(accum.objects); auto object_accumulator = [&](object* obj) {
if (type == TYPE_COUNT || obj->type() == type)
objects.push_back(tag_dynamic(obj));
};
each_object(object_accumulator);
return std_vector_to_array(objects);
} }
/* Allocates memory */ /* Allocates memory */

View File

@ -74,20 +74,12 @@ struct slot_checker {
} }
}; };
struct object_checker {
factor_vm* parent;
object_checker(factor_vm* parent) : parent(parent) {}
void operator()(object* obj) {
generation obj_gen = generation_of(parent, obj);
slot_checker checker(parent, obj, obj_gen);
obj->each_slot(checker);
}
};
void factor_vm::check_data_heap() { void factor_vm::check_data_heap() {
object_checker checker(this); auto checker = [&](object* obj){
generation obj_gen = generation_of(this, obj);
slot_checker s_checker(this, obj, obj_gen);
obj->each_slot(s_checker);
};
each_object(checker); each_object(checker);
} }

View File

@ -286,27 +286,16 @@ void factor_vm::dump_generations(ostream& out) {
out << dec; out << dec;
} }
struct object_dumper {
factor_vm* parent;
cell type;
ostream& out;
object_dumper(factor_vm* parent, cell type, ostream& out)
: parent(parent), type(type), out(out) {}
void operator()(object* obj) {
if (type == TYPE_COUNT || obj->type() == type) {
out << padded_address((cell)obj) << " ";
parent->print_nested_obj(out, tag_dynamic(obj), 2);
out << endl;
}
}
};
void factor_vm::dump_objects(ostream& out, cell type) { void factor_vm::dump_objects(ostream& out, cell type) {
primitive_full_gc(); primitive_full_gc();
object_dumper dumper(this, type, out); auto object_dumper = [&](object* obj) {
each_object(dumper); if (type == TYPE_COUNT || obj->type() == type) {
out << padded_address((cell)obj) << " ";
print_nested_obj(out, tag_dynamic(obj), 2);
out << endl;
}
};
each_object(object_dumper);
} }
struct find_data_reference_slot_visitor { struct find_data_reference_slot_visitor {

View File

@ -120,13 +120,9 @@ void free_list_allocator<Block>::sweep(Iterator& iter) {
} }
} }
template <typename Block> struct null_sweep_iterator {
void operator()(Block* free_block, cell size) {}
};
template <typename Block> void free_list_allocator<Block>::sweep() { template <typename Block> void free_list_allocator<Block>::sweep() {
null_sweep_iterator<Block> none; auto null_sweep = [](Block* free_block, cell size) { };
sweep(none); sweep(null_sweep);
} }
template <typename Block, typename Iterator> struct heap_compactor { template <typename Block, typename Iterator> struct heap_compactor {
@ -170,9 +166,10 @@ template <typename Iterator, typename Fixup>
void free_list_allocator<Block>::iterate(Iterator& iter, Fixup fixup) { void free_list_allocator<Block>::iterate(Iterator& iter, Fixup fixup) {
cell scan = this->start; cell scan = this->start;
while (scan != this->end) { while (scan != this->end) {
cell size = fixup.size((Block*)scan); Block* block = (Block*)scan;
if (!((Block*)scan)->free_p()) cell size = fixup.size(block);
iter((Block*)scan, size); if (!block->free_p())
iter(block, size);
scan += size; scan += size;
} }
} }