]> gitweb.factorcode.org Git - factor.git/blob - vm/generic_arrays.hpp
Move vmpp to vm
[factor.git] / vm / generic_arrays.hpp
1 template<typename T> CELL array_capacity(T *array)
2 {
3 #ifdef FACTOR_DEBUG
4         CELL header = untag_header(array->header);
5         assert(header == T::type_number);
6 #endif
7         return array->capacity >> TAG_BITS;
8 }
9
10 #define AREF(array,index) ((CELL)(array) + sizeof(F_ARRAY) + (index) * CELLS)
11 #define UNAREF(array,ptr) (((CELL)(ptr)-(CELL)(array)-sizeof(F_ARRAY)) / CELLS)
12
13 template <typename T> CELL array_nth(T *array, CELL slot)
14 {
15 #ifdef FACTOR_DEBUG
16         assert(slot < array_capacity<T>(array));
17         assert(untag_header(array->header) == T::type_number);
18 #endif
19         return get(AREF(array,slot));
20 }
21
22 template <typename T> void set_array_nth(T *array, CELL slot, CELL value)
23 {
24 #ifdef FACTOR_DEBUG
25         assert(slot < array_capacity<T>(array));
26         assert(untag_header(array->header) == T::type_number);
27 #endif
28         put(AREF(array,slot),value);
29         write_barrier((CELL)array);
30 }
31
32 template <typename T> CELL array_size(CELL capacity)
33 {
34         return sizeof(T) + capacity * T::element_size;
35 }
36
37 template <typename T> CELL array_size(T *array)
38 {
39         return array_size<T>(array_capacity(array));
40 }
41
42 template <typename T> T *allot_array_internal(CELL capacity)
43 {
44         T *array = allot<T>(array_size<T>(capacity));
45         array->capacity = tag_fixnum(capacity);
46         return array;
47 }
48
49 template <typename T> bool reallot_array_in_place_p(T *array, CELL capacity)
50 {
51         return in_zone(&nursery,(CELL)array) && capacity <= array_capacity(array);
52 }
53
54 template <typename T> T *reallot_array(T *array_, CELL capacity)
55 {
56         gc_root<T> array(array_);
57
58         if(reallot_array_in_place_p(array.untagged(),capacity))
59         {
60                 array->capacity = tag_fixnum(capacity);
61                 return array.untagged();
62         }
63         else
64         {
65                 CELL to_copy = array_capacity(array.untagged());
66                 if(capacity < to_copy)
67                         to_copy = capacity;
68
69                 T *new_array = allot_array_internal<T>(capacity);
70         
71                 memcpy(new_array + 1,array.untagged() + 1,to_copy * T::element_size);
72                 memset((char *)(new_array + 1) + to_copy * T::element_size,
73                         0,(capacity - to_copy) * T::element_size);
74
75                 return new_array;
76         }
77 }