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"
|
#include "master.hpp"
|
||||||
|
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
void factor_vm::init_card_decks()
|
void factor_vm::init_card_decks() {
|
||||||
{
|
cards_offset = (cell) data->cards - addr_to_card(data->start);
|
||||||
cards_offset = (cell)data->cards - addr_to_card(data->start);
|
decks_offset = (cell) data->decks - addr_to_deck(data->start);
|
||||||
decks_offset = (cell)data->decks - addr_to_deck(data->start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data_heap::data_heap(cell young_size_,
|
data_heap::data_heap(cell young_size_, cell aging_size_, cell tenured_size_) {
|
||||||
cell aging_size_,
|
young_size_ = align(young_size_, deck_size);
|
||||||
cell tenured_size_)
|
aging_size_ = align(aging_size_, deck_size);
|
||||||
{
|
tenured_size_ = align(tenured_size_, deck_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_;
|
young_size = young_size_;
|
||||||
aging_size = aging_size_;
|
aging_size = aging_size_;
|
||||||
tenured_size = tenured_size_;
|
tenured_size = tenured_size_;
|
||||||
|
|
||||||
cell total_size = young_size + 2 * aging_size + tenured_size + deck_size;
|
cell total_size = young_size + 2 * aging_size + tenured_size + deck_size;
|
||||||
seg = new segment(total_size,false);
|
seg = new segment(total_size, false);
|
||||||
|
|
||||||
cell cards_size = addr_to_card(total_size);
|
cell cards_size = addr_to_card(total_size);
|
||||||
cards = new card[cards_size];
|
cards = new card[cards_size];
|
||||||
cards_end = cards + cards_size;
|
cards_end = cards + cards_size;
|
||||||
memset(cards,0,cards_size);
|
memset(cards, 0, cards_size);
|
||||||
|
|
||||||
cell decks_size = addr_to_deck(total_size);
|
cell decks_size = addr_to_deck(total_size);
|
||||||
decks = new card_deck[decks_size];
|
decks = new card_deck[decks_size];
|
||||||
decks_end = decks + decks_size;
|
decks_end = decks + decks_size;
|
||||||
memset(decks,0,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 = new aging_space(aging_size, tenured->end);
|
||||||
aging_semispace = new aging_space(aging_size,aging->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()
|
data_heap::~data_heap() {
|
||||||
{
|
delete seg;
|
||||||
delete seg;
|
delete nursery;
|
||||||
delete nursery;
|
delete aging;
|
||||||
delete aging;
|
delete aging_semispace;
|
||||||
delete aging_semispace;
|
delete tenured;
|
||||||
delete tenured;
|
delete[] cards;
|
||||||
delete[] cards;
|
delete[] decks;
|
||||||
delete[] decks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data_heap *data_heap::grow(cell requested_bytes)
|
data_heap* data_heap::grow(cell requested_bytes) {
|
||||||
{
|
cell new_tenured_size = (tenured_size * 2) + requested_bytes;
|
||||||
cell new_tenured_size = (tenured_size * 2) + requested_bytes;
|
return new data_heap(young_size, aging_size, new_tenured_size);
|
||||||
return new data_heap(young_size,
|
|
||||||
aging_size,
|
|
||||||
new_tenured_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Generation> void data_heap::clear_cards(Generation *gen)
|
template <typename Generation> void data_heap::clear_cards(Generation* gen) {
|
||||||
{
|
cell first_card = addr_to_card(gen->start - start);
|
||||||
cell first_card = addr_to_card(gen->start - start);
|
cell last_card = addr_to_card(gen->end - start);
|
||||||
cell last_card = addr_to_card(gen->end - start);
|
memset(&cards[first_card], 0, last_card - first_card);
|
||||||
memset(&cards[first_card],0,last_card - first_card);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Generation> void data_heap::clear_decks(Generation *gen)
|
template <typename Generation> void data_heap::clear_decks(Generation* gen) {
|
||||||
{
|
cell first_deck = addr_to_deck(gen->start - start);
|
||||||
cell first_deck = addr_to_deck(gen->start - start);
|
cell last_deck = addr_to_deck(gen->end - start);
|
||||||
cell last_deck = addr_to_deck(gen->end - start);
|
memset(&decks[first_deck], 0, last_deck - first_deck);
|
||||||
memset(&decks[first_deck],0,last_deck - first_deck);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void data_heap::reset_generation(nursery_space *gen)
|
void data_heap::reset_generation(nursery_space* gen) { gen->here = gen->start; }
|
||||||
{
|
|
||||||
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)
|
void data_heap::reset_generation(tenured_space* gen) {
|
||||||
{
|
clear_cards(gen);
|
||||||
gen->here = gen->start;
|
clear_decks(gen);
|
||||||
clear_cards(gen);
|
|
||||||
clear_decks(gen);
|
|
||||||
gen->starts.clear_object_start_offsets();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void data_heap::reset_generation(tenured_space *gen)
|
bool data_heap::high_fragmentation_p() {
|
||||||
{
|
return (tenured->largest_free_block() <= high_water_mark());
|
||||||
clear_cards(gen);
|
|
||||||
clear_decks(gen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool data_heap::high_fragmentation_p()
|
bool data_heap::low_memory_p() {
|
||||||
{
|
return (tenured->free_space() <= high_water_mark());
|
||||||
return (tenured->largest_free_block() <= high_water_mark());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool data_heap::low_memory_p()
|
void data_heap::mark_all_cards() {
|
||||||
{
|
memset(cards, -1, cards_end - cards);
|
||||||
return (tenured->free_space() <= high_water_mark());
|
memset(decks, -1, decks_end - decks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void data_heap::mark_all_cards()
|
void factor_vm::set_data_heap(data_heap* data_) {
|
||||||
{
|
data = data_;
|
||||||
memset(cards,-1,cards_end - cards);
|
nursery = *data->nursery;
|
||||||
memset(decks,-1,decks_end - decks);
|
init_card_decks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::set_data_heap(data_heap *data_)
|
void factor_vm::init_data_heap(cell young_size, cell aging_size,
|
||||||
{
|
cell tenured_size) {
|
||||||
data = data_;
|
set_data_heap(new data_heap(young_size, aging_size, tenured_size));
|
||||||
nursery = *data->nursery;
|
|
||||||
init_card_decks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size)
|
data_heap_room factor_vm::data_room() {
|
||||||
{
|
data_heap_room room;
|
||||||
set_data_heap(new data_heap(young_size,aging_size,tenured_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
data_heap_room factor_vm::data_room()
|
room.nursery_size = nursery.size;
|
||||||
{
|
room.nursery_occupied = nursery.occupied_space();
|
||||||
data_heap_room room;
|
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;
|
return room;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
void factor_vm::primitive_data_room()
|
void factor_vm::primitive_data_room() {
|
||||||
{
|
data_heap_room room = data_room();
|
||||||
data_heap_room room = 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 {
|
struct object_accumulator {
|
||||||
cell type;
|
cell type;
|
||||||
std::vector<cell> objects;
|
std::vector<cell> objects;
|
||||||
|
|
||||||
explicit object_accumulator(cell type_) : type(type_) {}
|
explicit object_accumulator(cell type_) : type(type_) {}
|
||||||
|
|
||||||
void operator()(object *obj)
|
void operator()(object* obj) {
|
||||||
{
|
if (type == TYPE_COUNT || obj->type() == type)
|
||||||
if(type == TYPE_COUNT || obj->type() == type)
|
objects.push_back(tag_dynamic(obj));
|
||||||
objects.push_back(tag_dynamic(obj));
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
cell factor_vm::instances(cell type)
|
cell factor_vm::instances(cell type) {
|
||||||
{
|
object_accumulator accum(type);
|
||||||
object_accumulator accum(type);
|
each_object(accum);
|
||||||
each_object(accum);
|
return std_vector_to_array(accum.objects);
|
||||||
return std_vector_to_array(accum.objects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
void factor_vm::primitive_all_instances()
|
void factor_vm::primitive_all_instances() {
|
||||||
{
|
primitive_full_gc();
|
||||||
primitive_full_gc();
|
ctx->push(instances(TYPE_COUNT));
|
||||||
ctx->push(instances(TYPE_COUNT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +1,54 @@
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
struct data_heap {
|
struct data_heap {
|
||||||
cell start;
|
cell start;
|
||||||
|
|
||||||
cell young_size;
|
cell young_size;
|
||||||
cell aging_size;
|
cell aging_size;
|
||||||
cell tenured_size;
|
cell tenured_size;
|
||||||
|
|
||||||
segment *seg;
|
segment* seg;
|
||||||
|
|
||||||
nursery_space *nursery;
|
nursery_space* nursery;
|
||||||
aging_space *aging;
|
aging_space* aging;
|
||||||
aging_space *aging_semispace;
|
aging_space* aging_semispace;
|
||||||
tenured_space *tenured;
|
tenured_space* tenured;
|
||||||
|
|
||||||
card *cards;
|
card* cards;
|
||||||
card *cards_end;
|
card* cards_end;
|
||||||
|
|
||||||
card_deck *decks;
|
card_deck* decks;
|
||||||
card_deck *decks_end;
|
card_deck* decks_end;
|
||||||
|
|
||||||
explicit data_heap(cell young_size, cell aging_size, cell tenured_size);
|
explicit data_heap(cell young_size, cell aging_size, cell tenured_size);
|
||||||
~data_heap();
|
~data_heap();
|
||||||
data_heap *grow(cell requested_size);
|
data_heap* grow(cell requested_size);
|
||||||
template<typename Generation> void clear_cards(Generation *gen);
|
template <typename Generation> void clear_cards(Generation* gen);
|
||||||
template<typename Generation> void clear_decks(Generation *gen);
|
template <typename Generation> void clear_decks(Generation* gen);
|
||||||
void reset_generation(nursery_space *gen);
|
void reset_generation(nursery_space* gen);
|
||||||
void reset_generation(aging_space *gen);
|
void reset_generation(aging_space* gen);
|
||||||
void reset_generation(tenured_space *gen);
|
void reset_generation(tenured_space* gen);
|
||||||
bool high_fragmentation_p();
|
bool high_fragmentation_p();
|
||||||
bool low_memory_p();
|
bool low_memory_p();
|
||||||
void mark_all_cards();
|
void mark_all_cards();
|
||||||
cell high_water_mark() {
|
cell high_water_mark() { return nursery->size + aging->size; }
|
||||||
return nursery->size + aging->size;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct data_heap_room {
|
struct data_heap_room {
|
||||||
cell nursery_size;
|
cell nursery_size;
|
||||||
cell nursery_occupied;
|
cell nursery_occupied;
|
||||||
cell nursery_free;
|
cell nursery_free;
|
||||||
cell aging_size;
|
cell aging_size;
|
||||||
cell aging_occupied;
|
cell aging_occupied;
|
||||||
cell aging_free;
|
cell aging_free;
|
||||||
cell tenured_size;
|
cell tenured_size;
|
||||||
cell tenured_occupied;
|
cell tenured_occupied;
|
||||||
cell tenured_total_free;
|
cell tenured_total_free;
|
||||||
cell tenured_contiguous_free;
|
cell tenured_contiguous_free;
|
||||||
cell tenured_free_block_count;
|
cell tenured_free_block_count;
|
||||||
cell cards;
|
cell cards;
|
||||||
cell decks;
|
cell decks;
|
||||||
cell mark_stack;
|
cell mark_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,99 +3,95 @@
|
||||||
/* A tool to debug write barriers. Call check_data_heap() to ensure that all
|
/* A tool to debug write barriers. Call check_data_heap() to ensure that all
|
||||||
cards that should be marked are actually marked. */
|
cards that should be marked are actually marked. */
|
||||||
|
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
enum generation {
|
enum generation {
|
||||||
nursery_generation,
|
nursery_generation,
|
||||||
aging_generation,
|
aging_generation,
|
||||||
tenured_generation
|
tenured_generation
|
||||||
};
|
};
|
||||||
|
|
||||||
inline generation generation_of(factor_vm *parent, object *obj)
|
inline generation generation_of(factor_vm* parent, object* obj) {
|
||||||
{
|
if (parent->data->nursery->contains_p(obj))
|
||||||
if(parent->data->nursery->contains_p(obj))
|
return nursery_generation;
|
||||||
return nursery_generation;
|
else if (parent->data->aging->contains_p(obj))
|
||||||
else if(parent->data->aging->contains_p(obj))
|
return aging_generation;
|
||||||
return aging_generation;
|
else if (parent->data->tenured->contains_p(obj))
|
||||||
else if(parent->data->tenured->contains_p(obj))
|
return tenured_generation;
|
||||||
return tenured_generation;
|
else {
|
||||||
else
|
critical_error("Bad object", (cell) obj);
|
||||||
{
|
return (generation) - 1;
|
||||||
critical_error("Bad object",(cell)obj);
|
}
|
||||||
return (generation)-1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct slot_checker {
|
struct slot_checker {
|
||||||
factor_vm *parent;
|
factor_vm* parent;
|
||||||
object *obj;
|
object* obj;
|
||||||
generation gen;
|
generation gen;
|
||||||
|
|
||||||
explicit slot_checker(factor_vm *parent_, object *obj_, generation gen_) :
|
explicit slot_checker(factor_vm* parent_, object* obj_, generation gen_)
|
||||||
parent(parent_), obj(obj_), gen(gen_) {}
|
: parent(parent_), obj(obj_), gen(gen_) {}
|
||||||
|
|
||||||
void check_write_barrier(cell *slot_ptr, generation target, char mask)
|
void check_write_barrier(cell* slot_ptr, generation target, char mask) {
|
||||||
{
|
cell object_card_pointer = parent->cards_offset + ((cell) obj >> card_bits);
|
||||||
cell object_card_pointer = parent->cards_offset + ((cell)obj >> card_bits);
|
cell slot_card_pointer =
|
||||||
cell slot_card_pointer = parent->cards_offset + ((cell)slot_ptr >> card_bits);
|
parent->cards_offset + ((cell) slot_ptr >> card_bits);
|
||||||
char slot_card_value = *(char *)slot_card_pointer;
|
char slot_card_value = *(char*)slot_card_pointer;
|
||||||
if((slot_card_value & mask) != mask)
|
if ((slot_card_value & mask) != mask) {
|
||||||
{
|
std::cout << "card not marked" << std::endl;
|
||||||
std::cout << "card not marked" << std::endl;
|
std::cout << "source generation: " << gen << std::endl;
|
||||||
std::cout << "source generation: " << gen << std::endl;
|
std::cout << "target generation: " << target << std::endl;
|
||||||
std::cout << "target generation: " << target << std::endl;
|
std::cout << "object: 0x" << std::hex << (cell)
|
||||||
std::cout << "object: 0x" << std::hex << (cell)obj << std::dec << std::endl;
|
obj << std::dec << std::endl;
|
||||||
std::cout << "object type: " << obj->type() << 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 pointer: 0x" << std::hex << (cell)
|
||||||
std::cout << "slot value: 0x" << std::hex << *slot_ptr << std::dec << std::endl;
|
slot_ptr << std::dec << std::endl;
|
||||||
std::cout << "card of object: 0x" << std::hex << object_card_pointer << std::dec << std::endl;
|
std::cout << "slot value: 0x" << std::hex << *slot_ptr << std::dec
|
||||||
std::cout << "card of slot: 0x" << std::hex << slot_card_pointer << std::dec << std::endl;
|
<< std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << "card of object: 0x" << std::hex << object_card_pointer
|
||||||
parent->factorbug();
|
<< 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)
|
void operator()(cell* slot_ptr) {
|
||||||
{
|
if (!immediate_p(*slot_ptr)) {
|
||||||
if(!immediate_p(*slot_ptr))
|
generation target = generation_of(parent, untag<object>(*slot_ptr));
|
||||||
{
|
switch (gen) {
|
||||||
generation target = generation_of(parent,untag<object>(*slot_ptr));
|
case nursery_generation:
|
||||||
switch(gen)
|
break;
|
||||||
{
|
case aging_generation:
|
||||||
case nursery_generation:
|
if (target == nursery_generation)
|
||||||
break;
|
check_write_barrier(slot_ptr, target, card_points_to_nursery);
|
||||||
case aging_generation:
|
break;
|
||||||
if(target == nursery_generation)
|
case tenured_generation:
|
||||||
check_write_barrier(slot_ptr,target,card_points_to_nursery);
|
if (target == nursery_generation)
|
||||||
break;
|
check_write_barrier(slot_ptr, target, card_points_to_nursery);
|
||||||
case tenured_generation:
|
else if (target == aging_generation)
|
||||||
if(target == nursery_generation)
|
check_write_barrier(slot_ptr, target, card_points_to_aging);
|
||||||
check_write_barrier(slot_ptr,target,card_points_to_nursery);
|
break;
|
||||||
else if(target == aging_generation)
|
}
|
||||||
check_write_barrier(slot_ptr,target,card_points_to_aging);
|
}
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct object_checker {
|
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)
|
void operator()(object* obj) {
|
||||||
{
|
slot_checker checker(parent, obj, generation_of(parent, obj));
|
||||||
slot_checker checker(parent,obj,generation_of(parent,obj));
|
obj->each_slot(checker);
|
||||||
obj->each_slot(checker);
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void factor_vm::check_data_heap()
|
void factor_vm::check_data_heap() {
|
||||||
{
|
object_checker checker(this);
|
||||||
object_checker checker(this);
|
each_object(checker);
|
||||||
each_object(checker);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue