/* push a new tuple on the stack */ tuple *factorvm::allot_tuple(cell layout_) { gc_root<tuple_layout> layout(layout_,this); gc_root<tuple> t(allot<tuple>(tuple_size(layout.untagged())),this); t->layout = layout.value(); return t.untagged(); }
rc_t lgdata_p::append(const vec_t& data, uint4_t start, uint4_t amount) { FUNC(lgdata_p::append); // new vector at correct start and with correct size if(data.is_zvec()) { const zvec_t amt_vec_tmp(amount); W_DO(splice(0, (slot_length_t) tuple_size(0), 0, amt_vec_tmp)); } else { vec_t new_data(data, u4i(start), u4i(amount)); w_assert9(amount == new_data.size()); W_DO(splice(0, (slot_length_t) tuple_size(0), 0, new_data)); } return RCOK; }
/* 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. */ cell factor_vm::binary_payload_start(object *pointer) { switch(pointer->h.hi_tag()) { /* 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*)pointer)); case TUPLE_TYPE: return tuple_size(untag<tuple_layout>(((tuple *)pointer)->layout)); case WRAPPER_TYPE: return sizeof(wrapper); default: critical_error("Invalid header",(cell)pointer); return 0; /* can't happen */ } }
/* Size of the data area of an object pointed to by an untagged pointer */ cell factor_vm::unaligned_object_size(object *pointer) { switch(pointer->h.hi_tag()) { case ARRAY_TYPE: return array_size((array*)pointer); case BIGNUM_TYPE: return array_size((bignum*)pointer); case BYTE_ARRAY_TYPE: return array_size((byte_array*)pointer); case STRING_TYPE: return string_size(string_capacity((string*)pointer)); case TUPLE_TYPE: return tuple_size(untag<tuple_layout>(((tuple *)pointer)->layout)); case QUOTATION_TYPE: return sizeof(quotation); case WORD_TYPE: return sizeof(word); case FLOAT_TYPE: return sizeof(boxed_float); case DLL_TYPE: return sizeof(dll); case ALIEN_TYPE: return sizeof(alien); case WRAPPER_TYPE: return sizeof(wrapper); case CALLSTACK_TYPE: return callstack_size(untag_fixnum(((callstack *)pointer)->length)); default: critical_error("Invalid header",(cell)pointer); return 0; /* can't happen */ } }
rc_t lgindex_p::truncate(uint4_t num_pages) { vec_t empty; // zero length vector int bytes_to_trunc = u4i(num_pages) * sizeof(shpid_t); W_DO(splice(0, (slot_length_t)(tuple_size(0)-bytes_to_trunc), bytes_to_trunc, empty)); return RCOK; }
rc_t lgindex_p::append(uint4_t num_pages, const shpid_t new_pids[]) { // new vector at correct start and with correct size vec_t data(new_pids, u4i(num_pages)*sizeof(new_pids[0])); W_DO(splice(0, (slot_length_t)(tuple_size(0)), 0, data)); return RCOK; }
rc_t lgdata_p::truncate(uint4_t amount) { FUNC(lgdata_p::truncate); vec_t empty; // zero length vector W_DO(splice(0, (slot_length_t)(tuple_size(0)-u4i(amount)), u4i(amount), empty)); return RCOK; }
inline void factorvm::vmprim_tuple() { gc_root<tuple_layout> layout(dpop(),this); tuple *t = allot_tuple(layout.value()); fixnum i; for(i = tuple_size(layout.untagged()) - 1; i >= 0; i--) t->data()[i] = F; dpush(tag<tuple>(t)); }
/* 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 */ } }
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 */ } }
static inline cell tuple_size_with_fixup(cell offset, object *obj) { tuple_layout *layout = (tuple_layout *)((char *)UNTAG(((tuple *)obj)->layout) + offset); return tuple_size(layout); }