VM: Refactor data_heap* to Factor style

db4
Erik Charlebois 2013-05-11 21:56:29 -04:00
parent fb34be6fa7
commit 75e6c88534
3 changed files with 217 additions and 249 deletions

View File

@ -1,186 +1,161 @@
#include "master.hpp"
namespace factor
{
namespace factor {
void factor_vm::init_card_decks()
{
cards_offset = (cell)data->cards - addr_to_card(data->start);
decks_offset = (cell)data->decks - addr_to_deck(data->start);
void factor_vm::init_card_decks() {
cards_offset = (cell) data->cards - addr_to_card(data->start);
decks_offset = (cell) data->decks - addr_to_deck(data->start);
}
data_heap::data_heap(cell young_size_,
cell aging_size_,
cell tenured_size_)
{
young_size_ = align(young_size_,deck_size);
aging_size_ = align(aging_size_,deck_size);
tenured_size_ = align(tenured_size_,deck_size);
data_heap::data_heap(cell young_size_, cell aging_size_, cell tenured_size_) {
young_size_ = align(young_size_, deck_size);
aging_size_ = align(aging_size_, deck_size);
tenured_size_ = align(tenured_size_, deck_size);
young_size = young_size_;
aging_size = aging_size_;
tenured_size = tenured_size_;
young_size = young_size_;
aging_size = aging_size_;
tenured_size = tenured_size_;
cell total_size = young_size + 2 * aging_size + tenured_size + deck_size;
seg = new segment(total_size,false);
cell total_size = young_size + 2 * aging_size + tenured_size + deck_size;
seg = new segment(total_size, false);
cell cards_size = addr_to_card(total_size);
cards = new card[cards_size];
cards_end = cards + cards_size;
memset(cards,0,cards_size);
cell cards_size = addr_to_card(total_size);
cards = new card[cards_size];
cards_end = cards + cards_size;
memset(cards, 0, cards_size);
cell decks_size = addr_to_deck(total_size);
decks = new card_deck[decks_size];
decks_end = decks + decks_size;
memset(decks,0,decks_size);
cell decks_size = addr_to_deck(total_size);
decks = new card_deck[decks_size];
decks_end = decks + decks_size;
memset(decks, 0, decks_size);
start = align(seg->start,deck_size);
start = align(seg->start, deck_size);
tenured = new tenured_space(tenured_size,start);
tenured = new tenured_space(tenured_size, start);
aging = new aging_space(aging_size,tenured->end);
aging_semispace = new aging_space(aging_size,aging->end);
aging = new aging_space(aging_size, tenured->end);
aging_semispace = new aging_space(aging_size, aging->end);
nursery = new nursery_space(young_size,aging_semispace->end);
nursery = new nursery_space(young_size, aging_semispace->end);
FACTOR_ASSERT(seg->end - nursery->end <= deck_size);
FACTOR_ASSERT(seg->end - nursery->end <= deck_size);
}
data_heap::~data_heap()
{
delete seg;
delete nursery;
delete aging;
delete aging_semispace;
delete tenured;
delete[] cards;
delete[] decks;
data_heap::~data_heap() {
delete seg;
delete nursery;
delete aging;
delete aging_semispace;
delete tenured;
delete[] cards;
delete[] decks;
}
data_heap *data_heap::grow(cell requested_bytes)
{
cell new_tenured_size = (tenured_size * 2) + requested_bytes;
return new data_heap(young_size,
aging_size,
new_tenured_size);
data_heap* data_heap::grow(cell requested_bytes) {
cell new_tenured_size = (tenured_size * 2) + requested_bytes;
return new data_heap(young_size, aging_size, new_tenured_size);
}
template<typename Generation> void data_heap::clear_cards(Generation *gen)
{
cell first_card = addr_to_card(gen->start - start);
cell last_card = addr_to_card(gen->end - start);
memset(&cards[first_card],0,last_card - first_card);
template <typename Generation> void data_heap::clear_cards(Generation* gen) {
cell first_card = addr_to_card(gen->start - start);
cell last_card = addr_to_card(gen->end - start);
memset(&cards[first_card], 0, last_card - first_card);
}
template<typename Generation> void data_heap::clear_decks(Generation *gen)
{
cell first_deck = addr_to_deck(gen->start - start);
cell last_deck = addr_to_deck(gen->end - start);
memset(&decks[first_deck],0,last_deck - first_deck);
template <typename Generation> void data_heap::clear_decks(Generation* gen) {
cell first_deck = addr_to_deck(gen->start - start);
cell last_deck = addr_to_deck(gen->end - start);
memset(&decks[first_deck], 0, last_deck - first_deck);
}
void data_heap::reset_generation(nursery_space *gen)
{
gen->here = gen->start;
void data_heap::reset_generation(nursery_space* gen) { gen->here = gen->start; }
void data_heap::reset_generation(aging_space* gen) {
gen->here = gen->start;
clear_cards(gen);
clear_decks(gen);
gen->starts.clear_object_start_offsets();
}
void data_heap::reset_generation(aging_space *gen)
{
gen->here = gen->start;
clear_cards(gen);
clear_decks(gen);
gen->starts.clear_object_start_offsets();
void data_heap::reset_generation(tenured_space* gen) {
clear_cards(gen);
clear_decks(gen);
}
void data_heap::reset_generation(tenured_space *gen)
{
clear_cards(gen);
clear_decks(gen);
bool data_heap::high_fragmentation_p() {
return (tenured->largest_free_block() <= high_water_mark());
}
bool data_heap::high_fragmentation_p()
{
return (tenured->largest_free_block() <= high_water_mark());
bool data_heap::low_memory_p() {
return (tenured->free_space() <= high_water_mark());
}
bool data_heap::low_memory_p()
{
return (tenured->free_space() <= high_water_mark());
void data_heap::mark_all_cards() {
memset(cards, -1, cards_end - cards);
memset(decks, -1, decks_end - decks);
}
void data_heap::mark_all_cards()
{
memset(cards,-1,cards_end - cards);
memset(decks,-1,decks_end - decks);
void factor_vm::set_data_heap(data_heap* data_) {
data = data_;
nursery = *data->nursery;
init_card_decks();
}
void factor_vm::set_data_heap(data_heap *data_)
{
data = data_;
nursery = *data->nursery;
init_card_decks();
void factor_vm::init_data_heap(cell young_size, cell aging_size,
cell tenured_size) {
set_data_heap(new data_heap(young_size, aging_size, tenured_size));
}
void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size)
{
set_data_heap(new data_heap(young_size,aging_size,tenured_size));
}
data_heap_room factor_vm::data_room() {
data_heap_room room;
data_heap_room factor_vm::data_room()
{
data_heap_room room;
room.nursery_size = nursery.size;
room.nursery_occupied = nursery.occupied_space();
room.nursery_free = nursery.free_space();
room.aging_size = data->aging->size;
room.aging_occupied = data->aging->occupied_space();
room.aging_free = data->aging->free_space();
room.tenured_size = data->tenured->size;
room.tenured_occupied = data->tenured->occupied_space();
room.tenured_total_free = data->tenured->free_space();
room.tenured_contiguous_free = data->tenured->largest_free_block();
room.tenured_free_block_count = data->tenured->free_block_count();
room.cards = data->cards_end - data->cards;
room.decks = data->decks_end - data->decks;
room.mark_stack = mark_stack.capacity() * sizeof(cell);
room.nursery_size = nursery.size;
room.nursery_occupied = nursery.occupied_space();
room.nursery_free = nursery.free_space();
room.aging_size = data->aging->size;
room.aging_occupied = data->aging->occupied_space();
room.aging_free = data->aging->free_space();
room.tenured_size = data->tenured->size;
room.tenured_occupied = data->tenured->occupied_space();
room.tenured_total_free = data->tenured->free_space();
room.tenured_contiguous_free = data->tenured->largest_free_block();
room.tenured_free_block_count = data->tenured->free_block_count();
room.cards = data->cards_end - data->cards;
room.decks = data->decks_end - data->decks;
room.mark_stack = mark_stack.capacity() * sizeof(cell);
return room;
return room;
}
/* Allocates memory */
void factor_vm::primitive_data_room()
{
data_heap_room room = data_room();
ctx->push(tag<byte_array>(byte_array_from_value(&room)));
void factor_vm::primitive_data_room() {
data_heap_room room = data_room();
ctx->push(tag<byte_array>(byte_array_from_value(&room)));
}
struct object_accumulator {
cell type;
std::vector<cell> objects;
cell type;
std::vector<cell> objects;
explicit object_accumulator(cell type_) : type(type_) {}
explicit object_accumulator(cell type_) : type(type_) {}
void operator()(object *obj)
{
if(type == TYPE_COUNT || obj->type() == type)
objects.push_back(tag_dynamic(obj));
}
void operator()(object* obj) {
if (type == TYPE_COUNT || obj->type() == type)
objects.push_back(tag_dynamic(obj));
}
};
/* Allocates memory */
cell factor_vm::instances(cell type)
{
object_accumulator accum(type);
each_object(accum);
return std_vector_to_array(accum.objects);
cell factor_vm::instances(cell type) {
object_accumulator accum(type);
each_object(accum);
return std_vector_to_array(accum.objects);
}
/* Allocates memory */
void factor_vm::primitive_all_instances()
{
primitive_full_gc();
ctx->push(instances(TYPE_COUNT));
void factor_vm::primitive_all_instances() {
primitive_full_gc();
ctx->push(instances(TYPE_COUNT));
}
}

View File

@ -1,57 +1,54 @@
namespace factor
{
namespace factor {
struct data_heap {
cell start;
cell start;
cell young_size;
cell aging_size;
cell tenured_size;
cell young_size;
cell aging_size;
cell tenured_size;
segment *seg;
segment* seg;
nursery_space *nursery;
aging_space *aging;
aging_space *aging_semispace;
tenured_space *tenured;
nursery_space* nursery;
aging_space* aging;
aging_space* aging_semispace;
tenured_space* tenured;
card *cards;
card *cards_end;
card* cards;
card* cards_end;
card_deck *decks;
card_deck *decks_end;
explicit data_heap(cell young_size, cell aging_size, cell tenured_size);
~data_heap();
data_heap *grow(cell requested_size);
template<typename Generation> void clear_cards(Generation *gen);
template<typename Generation> void clear_decks(Generation *gen);
void reset_generation(nursery_space *gen);
void reset_generation(aging_space *gen);
void reset_generation(tenured_space *gen);
bool high_fragmentation_p();
bool low_memory_p();
void mark_all_cards();
cell high_water_mark() {
return nursery->size + aging->size;
}
card_deck* decks;
card_deck* decks_end;
explicit data_heap(cell young_size, cell aging_size, cell tenured_size);
~data_heap();
data_heap* grow(cell requested_size);
template <typename Generation> void clear_cards(Generation* gen);
template <typename Generation> void clear_decks(Generation* gen);
void reset_generation(nursery_space* gen);
void reset_generation(aging_space* gen);
void reset_generation(tenured_space* gen);
bool high_fragmentation_p();
bool low_memory_p();
void mark_all_cards();
cell high_water_mark() { return nursery->size + aging->size; }
};
struct data_heap_room {
cell nursery_size;
cell nursery_occupied;
cell nursery_free;
cell aging_size;
cell aging_occupied;
cell aging_free;
cell tenured_size;
cell tenured_occupied;
cell tenured_total_free;
cell tenured_contiguous_free;
cell tenured_free_block_count;
cell cards;
cell decks;
cell mark_stack;
cell nursery_size;
cell nursery_occupied;
cell nursery_free;
cell aging_size;
cell aging_occupied;
cell aging_free;
cell tenured_size;
cell tenured_occupied;
cell tenured_total_free;
cell tenured_contiguous_free;
cell tenured_free_block_count;
cell cards;
cell decks;
cell mark_stack;
};
}

View File

@ -3,99 +3,95 @@
/* A tool to debug write barriers. Call check_data_heap() to ensure that all
cards that should be marked are actually marked. */
namespace factor
{
namespace factor {
enum generation {
nursery_generation,
aging_generation,
tenured_generation
nursery_generation,
aging_generation,
tenured_generation
};
inline generation generation_of(factor_vm *parent, object *obj)
{
if(parent->data->nursery->contains_p(obj))
return nursery_generation;
else if(parent->data->aging->contains_p(obj))
return aging_generation;
else if(parent->data->tenured->contains_p(obj))
return tenured_generation;
else
{
critical_error("Bad object",(cell)obj);
return (generation)-1;
}
inline generation generation_of(factor_vm* parent, object* obj) {
if (parent->data->nursery->contains_p(obj))
return nursery_generation;
else if (parent->data->aging->contains_p(obj))
return aging_generation;
else if (parent->data->tenured->contains_p(obj))
return tenured_generation;
else {
critical_error("Bad object", (cell) obj);
return (generation) - 1;
}
}
struct slot_checker {
factor_vm *parent;
object *obj;
generation gen;
factor_vm* parent;
object* obj;
generation gen;
explicit slot_checker(factor_vm *parent_, object *obj_, generation gen_) :
parent(parent_), obj(obj_), gen(gen_) {}
explicit slot_checker(factor_vm* parent_, object* obj_, generation gen_)
: parent(parent_), obj(obj_), gen(gen_) {}
void check_write_barrier(cell *slot_ptr, generation target, char mask)
{
cell object_card_pointer = parent->cards_offset + ((cell)obj >> card_bits);
cell slot_card_pointer = parent->cards_offset + ((cell)slot_ptr >> card_bits);
char slot_card_value = *(char *)slot_card_pointer;
if((slot_card_value & mask) != mask)
{
std::cout << "card not marked" << std::endl;
std::cout << "source generation: " << gen << std::endl;
std::cout << "target generation: " << target << std::endl;
std::cout << "object: 0x" << std::hex << (cell)obj << std::dec << std::endl;
std::cout << "object type: " << obj->type() << std::endl;
std::cout << "slot pointer: 0x" << std::hex << (cell)slot_ptr << std::dec << std::endl;
std::cout << "slot value: 0x" << std::hex << *slot_ptr << std::dec << std::endl;
std::cout << "card of object: 0x" << std::hex << object_card_pointer << std::dec << std::endl;
std::cout << "card of slot: 0x" << std::hex << slot_card_pointer << std::dec << std::endl;
std::cout << std::endl;
parent->factorbug();
}
}
void check_write_barrier(cell* slot_ptr, generation target, char mask) {
cell object_card_pointer = parent->cards_offset + ((cell) obj >> card_bits);
cell slot_card_pointer =
parent->cards_offset + ((cell) slot_ptr >> card_bits);
char slot_card_value = *(char*)slot_card_pointer;
if ((slot_card_value & mask) != mask) {
std::cout << "card not marked" << std::endl;
std::cout << "source generation: " << gen << std::endl;
std::cout << "target generation: " << target << std::endl;
std::cout << "object: 0x" << std::hex << (cell)
obj << std::dec << std::endl;
std::cout << "object type: " << obj->type() << std::endl;
std::cout << "slot pointer: 0x" << std::hex << (cell)
slot_ptr << std::dec << std::endl;
std::cout << "slot value: 0x" << std::hex << *slot_ptr << std::dec
<< std::endl;
std::cout << "card of object: 0x" << std::hex << object_card_pointer
<< std::dec << std::endl;
std::cout << "card of slot: 0x" << std::hex << slot_card_pointer
<< std::dec << std::endl;
std::cout << std::endl;
parent->factorbug();
}
}
void operator()(cell *slot_ptr)
{
if(!immediate_p(*slot_ptr))
{
generation target = generation_of(parent,untag<object>(*slot_ptr));
switch(gen)
{
case nursery_generation:
break;
case aging_generation:
if(target == nursery_generation)
check_write_barrier(slot_ptr,target,card_points_to_nursery);
break;
case tenured_generation:
if(target == nursery_generation)
check_write_barrier(slot_ptr,target,card_points_to_nursery);
else if(target == aging_generation)
check_write_barrier(slot_ptr,target,card_points_to_aging);
break;
}
}
}
void operator()(cell* slot_ptr) {
if (!immediate_p(*slot_ptr)) {
generation target = generation_of(parent, untag<object>(*slot_ptr));
switch (gen) {
case nursery_generation:
break;
case aging_generation:
if (target == nursery_generation)
check_write_barrier(slot_ptr, target, card_points_to_nursery);
break;
case tenured_generation:
if (target == nursery_generation)
check_write_barrier(slot_ptr, target, card_points_to_nursery);
else if (target == aging_generation)
check_write_barrier(slot_ptr, target, card_points_to_aging);
break;
}
}
}
};
struct object_checker {
factor_vm *parent;
factor_vm* parent;
explicit object_checker(factor_vm *parent_) : parent(parent_) {}
explicit object_checker(factor_vm* parent_) : parent(parent_) {}
void operator()(object *obj)
{
slot_checker checker(parent,obj,generation_of(parent,obj));
obj->each_slot(checker);
}
void operator()(object* obj) {
slot_checker checker(parent, obj, generation_of(parent, obj));
obj->each_slot(checker);
}
};
void factor_vm::check_data_heap()
{
object_checker checker(this);
each_object(checker);
void factor_vm::check_data_heap() {
object_checker checker(this);
each_object(checker);
}
}