namespace factor { template cell array_capacity(const Array* array) { FACTOR_ASSERT(array->type() == Array::type_number); return array->capacity >> TAG_BITS; } template cell array_size(cell capacity) { return sizeof(Array) + capacity * Array::element_size; } template cell array_size(Array* array) { return array_size(array_capacity(array)); } // Allocates memory template Array* factor_vm::allot_uninitialized_array(cell capacity) { Array* array = allot(array_size(capacity)); array->capacity = tag_fixnum(capacity); return array; } template bool factor_vm::reallot_array_in_place_p(Array* array, cell capacity) { return data->nursery->contains_p(array) && capacity <= array_capacity(array); } // Allocates memory (sometimes) template Array* factor_vm::reallot_array(Array* array_, cell capacity) { data_root array(array_, this); if (array_capacity(array.untagged()) == capacity) return array.untagged(); if (reallot_array_in_place_p(array.untagged(), capacity)) { array->capacity = tag_fixnum(capacity); return array.untagged(); } cell to_copy = array_capacity(array.untagged()); if (capacity < to_copy) to_copy = capacity; Array* new_array = allot_uninitialized_array(capacity); memcpy(new_array + 1, array.untagged() + 1, to_copy * Array::element_size); memset((char*)(new_array + 1) + to_copy * Array::element_size, 0, (capacity - to_copy) * Array::element_size); return new_array; } }