+/* Size of the object pointed to by an untagged pointer */
+template<typename Fixup>
+cell object::size(Fixup fixup) const
+{
+ if(free_p()) return ((free_heap_block *)this)->size();
+
+ switch(type())
+ {
+ case ARRAY_TYPE:
+ return align(array_size((array*)this),data_alignment);
+ case BIGNUM_TYPE:
+ return align(array_size((bignum*)this),data_alignment);
+ case BYTE_ARRAY_TYPE:
+ return align(array_size((byte_array*)this),data_alignment);
+ case STRING_TYPE:
+ return align(string_size(string_capacity((string*)this)),data_alignment);
+ case TUPLE_TYPE:
+ {
+ tuple_layout *layout = (tuple_layout *)fixup.translate_data(untag<object>(((tuple *)this)->layout));
+ return align(tuple_size(layout),data_alignment);
+ }
+ case QUOTATION_TYPE:
+ return align(sizeof(quotation),data_alignment);
+ case WORD_TYPE:
+ return align(sizeof(word),data_alignment);
+ case FLOAT_TYPE:
+ return align(sizeof(boxed_float),data_alignment);
+ case DLL_TYPE:
+ return align(sizeof(dll),data_alignment);
+ case ALIEN_TYPE:
+ return align(sizeof(alien),data_alignment);
+ case WRAPPER_TYPE:
+ return align(sizeof(wrapper),data_alignment);
+ case CALLSTACK_TYPE:
+ return align(callstack_object_size(untag_fixnum(((callstack *)this)->length)),data_alignment);
+ default:
+ critical_error("Invalid header in size",(cell)this);
+ return 0; /* can't happen */
+ }
+}
+
+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 GC. Some types have a binary payload at the end (string, word, DLL) which
+we ignore. */
+template<typename Fixup>
+cell object::binary_payload_start(Fixup fixup) const
+{
+ if(free_p()) return 0;
+
+ switch(type())
+ {
+ /* these objects do not refer to other objects at all */
+ case FLOAT_TYPE:
+ case BYTE_ARRAY_TYPE:
+ case BIGNUM_TYPE:
+ case CALLSTACK_TYPE:
+ return 0;
+ /* these objects have some binary data at the end */
+ case WORD_TYPE:
+ return sizeof(word) - sizeof(cell) * 3;
+ case ALIEN_TYPE:
+ return sizeof(cell) * 3;
+ case DLL_TYPE:
+ return sizeof(cell) * 2;
+ case QUOTATION_TYPE:
+ return sizeof(quotation) - sizeof(cell) * 2;
+ case STRING_TYPE:
+ return sizeof(string);
+ /* everything else consists entirely of pointers */
+ case ARRAY_TYPE:
+ return array_size<array>(array_capacity((array*)this));
+ case TUPLE_TYPE:
+ {
+ tuple_layout *layout = (tuple_layout *)fixup.translate_data(untag<object>(((tuple *)this)->layout));
+ return tuple_size(layout);
+ }
+ 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
+{
+ return binary_payload_start(no_fixup());
+}
+