v2 / vlib / builtin / map_d_gcboehm_opt.v
148 lines · 139 sloc · 4.85 KB · e2e5cf8db56f3562c7baa735061690be936bdf3e
Raw
1// "noscan" versions of `map` initialization routines
2//
3// They are used when the compiler can proof that either the keys or the values or both
4// do not contain any pointers. Such objects can be placed in a memory area that is not
5// scanned by the garbage collector
6
7module builtin
8
9@[inline]
10fn __malloc_at_least_one(how_many_bytes u64, noscan bool) &u8 {
11 if noscan {
12 return unsafe { malloc_noscan(__at_least_one(how_many_bytes)) }
13 }
14 return unsafe { malloc(__at_least_one(how_many_bytes)) }
15}
16
17@[inline]
18fn new_dense_array_noscan(key_bytes int, key_noscan bool, value_bytes int, value_noscan bool) DenseArray {
19 cap := 8
20 return DenseArray{
21 key_bytes: key_bytes
22 value_bytes: value_bytes
23 cap: cap
24 len: 0
25 deletes: 0
26 all_deleted: unsafe { nil }
27 keys: __malloc_at_least_one(u64(cap) * u64(key_bytes), key_noscan)
28 values: __malloc_at_least_one(u64(cap) * u64(value_bytes), value_noscan)
29 }
30}
31
32fn new_map_noscan_key(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn,
33 free_fn MapFreeFn) map {
34 metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
35 // for now assume anything bigger than a pointer is a string
36 has_string_keys := key_bytes > sizeof(voidptr)
37 return map{
38 key_bytes: key_bytes
39 value_bytes: value_bytes
40 even_index: init_even_index
41 cached_hashbits: max_cached_hashbits
42 shift: init_log_capicity
43 key_values: new_dense_array_noscan(key_bytes, true, value_bytes, false)
44 metas: unsafe { &u32(vcalloc_noscan(metasize)) }
45 extra_metas: extra_metas_inc
46 len: 0
47 has_string_keys: has_string_keys
48 hash_fn: hash_fn
49 key_eq_fn: key_eq_fn
50 clone_fn: clone_fn
51 free_fn: free_fn
52 }
53}
54
55fn new_map_noscan_value(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn,
56 free_fn MapFreeFn) map {
57 metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
58 // for now assume anything bigger than a pointer is a string
59 has_string_keys := key_bytes > sizeof(voidptr)
60 return map{
61 key_bytes: key_bytes
62 value_bytes: value_bytes
63 even_index: init_even_index
64 cached_hashbits: max_cached_hashbits
65 shift: init_log_capicity
66 key_values: new_dense_array_noscan(key_bytes, false, value_bytes, true)
67 metas: unsafe { &u32(vcalloc_noscan(metasize)) }
68 extra_metas: extra_metas_inc
69 len: 0
70 has_string_keys: has_string_keys
71 hash_fn: hash_fn
72 key_eq_fn: key_eq_fn
73 clone_fn: clone_fn
74 free_fn: free_fn
75 }
76}
77
78fn new_map_noscan_key_value(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn,
79 free_fn MapFreeFn) map {
80 metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
81 // for now assume anything bigger than a pointer is a string
82 has_string_keys := key_bytes > sizeof(voidptr)
83 return map{
84 key_bytes: key_bytes
85 value_bytes: value_bytes
86 even_index: init_even_index
87 cached_hashbits: max_cached_hashbits
88 shift: init_log_capicity
89 key_values: new_dense_array_noscan(key_bytes, true, value_bytes, true)
90 metas: unsafe { &u32(vcalloc_noscan(metasize)) }
91 extra_metas: extra_metas_inc
92 len: 0
93 has_string_keys: has_string_keys
94 hash_fn: hash_fn
95 key_eq_fn: key_eq_fn
96 clone_fn: clone_fn
97 free_fn: free_fn
98 }
99}
100
101fn new_map_init_noscan_key(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn,
102 n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
103 mut out := new_map_noscan_key(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, free_fn)
104 // TODO: pre-allocate n slots
105 mut pkey := &u8(keys)
106 mut pval := &u8(values)
107 for _ in 0 .. n {
108 unsafe {
109 out.set(pkey, pval)
110 pkey = pkey + key_bytes
111 pval = pval + value_bytes
112 }
113 }
114 return out
115}
116
117fn new_map_init_noscan_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn,
118 n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
119 mut out := new_map_noscan_value(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, free_fn)
120 // TODO: pre-allocate n slots
121 mut pkey := &u8(keys)
122 mut pval := &u8(values)
123 for _ in 0 .. n {
124 unsafe {
125 out.set(pkey, pval)
126 pkey = pkey + key_bytes
127 pval = pval + value_bytes
128 }
129 }
130 return out
131}
132
133fn new_map_init_noscan_key_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn,
134 n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
135 mut out := new_map_noscan_key_value(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn,
136 free_fn)
137 // TODO: pre-allocate n slots
138 mut pkey := &u8(keys)
139 mut pval := &u8(values)
140 for _ in 0 .. n {
141 unsafe {
142 out.set(pkey, pval)
143 pkey = pkey + key_bytes
144 pval = pval + value_bytes
145 }
146 }
147 return out
148}
149