]> gitweb.factorcode.org Git - factor.git/blob - vm/generic_arrays.hpp
VM: get rid of the duplicated nursery instance in vm->data->nursery
[factor.git] / vm / generic_arrays.hpp
1 namespace factor {
2
3 template <typename Array> cell array_capacity(const Array* array) {
4   FACTOR_ASSERT(array->type() == Array::type_number);
5   return array->capacity >> TAG_BITS;
6 }
7
8 template <typename Array> cell array_size(cell capacity) {
9   return sizeof(Array) + capacity * Array::element_size;
10 }
11
12 template <typename Array> cell array_size(Array* array) {
13   return array_size<Array>(array_capacity(array));
14 }
15
16 /* Allocates memory */
17 template <typename Array>
18 Array* factor_vm::allot_uninitialized_array(cell capacity) {
19   Array* array = allot<Array>(array_size<Array>(capacity));
20   array->capacity = tag_fixnum(capacity);
21   return array;
22 }
23
24 template <typename Array>
25 bool factor_vm::reallot_array_in_place_p(Array* array, cell capacity) {
26   return data->nursery->contains_p(array) &&
27       capacity <= array_capacity(array);
28 }
29
30 /* Allocates memory (sometimes) */
31 template <typename Array>
32 Array* factor_vm::reallot_array(Array* array_, cell capacity) {
33   data_root<Array> array(array_, this);
34
35   if (array_capacity(array.untagged()) == capacity)
36     return array.untagged();
37
38   if (reallot_array_in_place_p(array.untagged(), capacity)) {
39     array->capacity = tag_fixnum(capacity);
40     return array.untagged();
41   } else {
42     cell to_copy = array_capacity(array.untagged());
43     if (capacity < to_copy)
44       to_copy = capacity;
45
46     Array* new_array = allot_uninitialized_array<Array>(capacity);
47
48     memcpy(new_array + 1, array.untagged() + 1, to_copy * Array::element_size);
49     memset((char*)(new_array + 1) + to_copy * Array::element_size, 0,
50            (capacity - to_copy) * Array::element_size);
51
52     return new_array;
53   }
54 }
55
56 }