VM: replace binary_payload_start() with slot_count()

This should simplify a little the address calculations when visiting
slots of an object
db4
Björn Lindqvist 2015-07-04 20:57:02 +02:00
parent 46423dfebf
commit fce5d4353a
4 changed files with 54 additions and 68 deletions

View File

@ -95,14 +95,13 @@ template <typename TargetGeneration, typename Policy> struct collector {
} }
void trace_partial_objects(cell start, cell card_start, cell card_end) { void trace_partial_objects(cell start, cell card_start, cell card_end) {
object* obj = (object*)start; cell *scan_start = (cell*)start + 1;
cell end = start + obj->binary_payload_start(); cell *scan_end = scan_start + ((object*)start)->slot_count();
start += sizeof(cell);
start = std::max(start, card_start); scan_start = std::max(scan_start, (cell*)card_start);
end = std::min(end, card_end); scan_end = std::min(scan_end, (cell*)card_end);
visitor.visit_object_array((cell*)start, (cell*)end); visitor.visit_object_array(scan_start, scan_end);
} }
template <typename SourceGeneration> template <typename SourceGeneration>

View File

@ -121,8 +121,8 @@ struct object {
template <typename Fixup> cell size(Fixup fixup) const; template <typename Fixup> cell size(Fixup fixup) const;
cell size() const; cell size() const;
cell binary_payload_start() const; cell slot_count() const;
template <typename Fixup> cell binary_payload_start(Fixup fixup) const; template <typename Fixup> cell slot_count(Fixup fixup) const;
cell* slots() const { return (cell*)this; } cell* slots() const { return (cell*)this; }
@ -332,9 +332,12 @@ struct tuple : public object {
cell* data() const { return (cell*)(this + 1); } cell* data() const { return (cell*)(this + 1); }
}; };
inline static cell tuple_capacity(const tuple_layout *layout) {
return untag_fixnum(layout->size);
}
inline static cell tuple_size(const tuple_layout* layout) { inline static cell tuple_size(const tuple_layout* layout) {
cell size = untag_fixnum(layout->size); return sizeof(tuple) + tuple_capacity(layout) * sizeof(cell);
return sizeof(tuple) + size * sizeof(cell);
} }
inline static cell string_capacity(const string* str) { inline static cell string_capacity(const string* str) {

View File

@ -121,15 +121,12 @@ inline static bool save_special_p(cell i) {
} }
template <typename Iterator> void object::each_slot(Iterator& iter) { template <typename Iterator> void object::each_slot(Iterator& iter) {
cell scan = (cell)this; cell* start = (cell*)this + 1;
cell payload_start = binary_payload_start(); cell* end = start + slot_count();
cell end = scan + payload_start;
scan += sizeof(cell); while (start < end) {
iter(start);
while (scan < end) { start++;
iter((cell*)scan);
scan += sizeof(cell);
} }
} }

View File

@ -48,49 +48,45 @@ cell object::size(Fixup fixup) const {
inline cell object::size() const { return size(no_fixup()); } inline cell object::size() const { return size(no_fixup()); }
/* The number of cells from the start of the object which should be scanned by /* The number of slots (cells) in an object which should be scanned by
the GC. Some types have a binary payload at the end (string, word, DLL) which the GC. The number can vary in arrays and tuples, in all other
we ignore. */ types the number is a constant. */
template <typename Fixup> cell object::binary_payload_start(Fixup fixup) const { template <typename Fixup>
inline cell object::slot_count(Fixup fixup) const {
if (free_p()) if (free_p())
return 0; return 0;
switch (type()) { cell t = type();
/* these objects do not refer to other objects at all */ if (t == ARRAY_TYPE) {
case FLOAT_TYPE: /* capacity + n slots */
case BYTE_ARRAY_TYPE: return 1 + array_capacity((array*)this);
case BIGNUM_TYPE: } else if (t == TUPLE_TYPE) {
case CALLSTACK_TYPE: tuple_layout* layout = (tuple_layout*)fixup.translate_data(
return 0; untag<object>(((tuple*)this)->layout));
/* these objects have some binary data at the end */ /* layout + n slots */
case WORD_TYPE: return 1 + tuple_capacity(layout);
return sizeof(word) - sizeof(cell); } else {
case ALIEN_TYPE: switch (t) {
return sizeof(cell) * 3; /* these objects do not refer to other objects at all */
case DLL_TYPE: case FLOAT_TYPE:
return sizeof(cell) * 2; case BYTE_ARRAY_TYPE:
case QUOTATION_TYPE: case BIGNUM_TYPE:
return sizeof(quotation) - sizeof(cell); case CALLSTACK_TYPE: return 0;
case STRING_TYPE: case WORD_TYPE: return 8;
return sizeof(string); case ALIEN_TYPE: return 2;
/* everything else consists entirely of pointers */ case DLL_TYPE: return 1;
case ARRAY_TYPE: case QUOTATION_TYPE: return 3;
return array_size<array>(array_capacity((array*)this)); case STRING_TYPE: return 3;
case TUPLE_TYPE: { case WRAPPER_TYPE: return 1;
tuple_layout* layout = (tuple_layout*)fixup.translate_data( default:
untag<object>(((tuple*)this)->layout)); critical_error("Invalid header in slot_count", (cell)this);
return tuple_size(layout); return 0; /* can't happen */
} }
case WRAPPER_TYPE:
return sizeof(wrapper);
default:
critical_error("Invalid header in binary_payload_start", (cell)this);
return 0; /* can't happen */
} }
} }
inline cell object::binary_payload_start() const { inline cell object::slot_count() const {
return binary_payload_start(no_fixup()); return slot_count(no_fixup());
} }
/* Slot visitors iterate over the slots of an object, applying a functor to /* Slot visitors iterate over the slots of an object, applying a functor to
@ -130,7 +126,6 @@ template <typename Fixup> struct slot_visitor {
cell visit_pointer(cell pointer); cell visit_pointer(cell pointer);
void visit_handle(cell* handle); void visit_handle(cell* handle);
void visit_object_array(cell* start, cell* end); void visit_object_array(cell* start, cell* end);
void visit_slots(object* ptr, cell payload_start);
void visit_slots(object* ptr); void visit_slots(object* ptr);
void visit_stack_elements(segment* region, cell* top); void visit_stack_elements(segment* region, cell* top);
void visit_data_roots(); void visit_data_roots();
@ -172,22 +167,14 @@ void slot_visitor<Fixup>::visit_object_array(cell* start, cell* end) {
visit_handle(start++); visit_handle(start++);
} }
template <typename Fixup>
void slot_visitor<Fixup>::visit_slots(object* ptr, cell payload_start) {
cell* slot = (cell*)ptr;
cell* end = (cell*)((cell)ptr + payload_start);
if (slot != end) {
slot++;
visit_object_array(slot, end);
}
}
template <typename Fixup> void slot_visitor<Fixup>::visit_slots(object* obj) { template <typename Fixup> void slot_visitor<Fixup>::visit_slots(object* obj) {
if (obj->type() == CALLSTACK_TYPE) if (obj->type() == CALLSTACK_TYPE)
visit_callstack_object((callstack*)obj); visit_callstack_object((callstack*)obj);
else else {
visit_slots(obj, obj->binary_payload_start(fixup)); cell* start = (cell*)obj + 1;
cell* end = start + obj->slot_count(fixup);
visit_object_array(start, end);
}
} }
template <typename Fixup> template <typename Fixup>