VM: Refactor data_heap* to Factor style
parent
fb34be6fa7
commit
75e6c88534
233
vm/data_heap.cpp
233
vm/data_heap.cpp
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue