2013-05-11 22:04:22 -04:00
|
|
|
namespace factor {
|
2009-05-04 02:46:13 -04:00
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
template <typename Array> cell array_capacity(const Array* array) {
|
|
|
|
FACTOR_ASSERT(array->type() == Array::type_number);
|
|
|
|
return array->capacity >> TAG_BITS;
|
2009-05-02 05:43:58 -04:00
|
|
|
}
|
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
template <typename Array> cell array_size(cell capacity) {
|
|
|
|
return sizeof(Array) + capacity * Array::element_size;
|
2009-05-02 05:43:58 -04:00
|
|
|
}
|
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
template <typename Array> cell array_size(Array* array) {
|
|
|
|
return array_size<Array>(array_capacity(array));
|
2009-05-02 05:43:58 -04:00
|
|
|
}
|
|
|
|
|
2016-08-21 10:26:04 -04:00
|
|
|
// Allocates memory
|
2013-05-11 22:04:22 -04:00
|
|
|
template <typename Array>
|
|
|
|
Array* factor_vm::allot_uninitialized_array(cell capacity) {
|
|
|
|
Array* array = allot<Array>(array_size<Array>(capacity));
|
|
|
|
array->capacity = tag_fixnum(capacity);
|
|
|
|
return array;
|
2009-09-29 14:53:10 -04:00
|
|
|
}
|
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
template <typename Array>
|
|
|
|
bool factor_vm::reallot_array_in_place_p(Array* array, cell capacity) {
|
2014-11-21 02:52:33 -05:00
|
|
|
return data->nursery->contains_p(array) &&
|
|
|
|
capacity <= array_capacity(array);
|
2009-09-29 14:53:10 -04:00
|
|
|
}
|
|
|
|
|
2016-08-21 10:26:04 -04:00
|
|
|
// Allocates memory (sometimes)
|
2013-05-11 22:04:22 -04:00
|
|
|
template <typename Array>
|
|
|
|
Array* factor_vm::reallot_array(Array* array_, cell capacity) {
|
|
|
|
data_root<Array> array(array_, this);
|
2009-09-29 14:53:10 -04:00
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
if (array_capacity(array.untagged()) == capacity)
|
|
|
|
return array.untagged();
|
2011-10-12 15:34:30 -04:00
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
if (reallot_array_in_place_p(array.untagged(), capacity)) {
|
|
|
|
array->capacity = tag_fixnum(capacity);
|
|
|
|
return array.untagged();
|
|
|
|
} else {
|
|
|
|
cell to_copy = array_capacity(array.untagged());
|
|
|
|
if (capacity < to_copy)
|
|
|
|
to_copy = capacity;
|
2009-10-13 22:16:04 -04:00
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
Array* new_array = allot_uninitialized_array<Array>(capacity);
|
2009-10-13 22:16:04 -04:00
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
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);
|
2009-10-13 22:16:04 -04:00
|
|
|
|
2013-05-11 22:04:22 -04:00
|
|
|
return new_array;
|
|
|
|
}
|
2009-09-29 14:53:10 -04:00
|
|
|
}
|
|
|
|
|
2009-05-04 02:46:13 -04:00
|
|
|
}
|