1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00
v/vlib/builtin/map_d_gcboehm_opt.v

145 lines
4.5 KiB
V
Raw Permalink Normal View History

// "noscan" versions of `map` initialization routines
//
// They are used when the compiler can proof that either the keys or the values or both
// do not contain any pointers. Such objects can be placed in a memory area that is not
// scanned by the garbage collector
module builtin
[inline]
fn __malloc_at_least_one(how_many_bytes u64, noscan bool) &u8 {
if noscan {
return unsafe { malloc_noscan(__at_least_one(how_many_bytes)) }
}
return unsafe { malloc(__at_least_one(how_many_bytes)) }
}
[inline]
fn new_dense_array_noscan(key_bytes int, key_noscan bool, value_bytes int, value_noscan bool) DenseArray {
cap := 8
return DenseArray{
key_bytes: key_bytes
value_bytes: value_bytes
cap: cap
len: 0
deletes: 0
all_deleted: 0
keys: __malloc_at_least_one(u64(cap) * u64(key_bytes), key_noscan)
values: __malloc_at_least_one(u64(cap) * u64(value_bytes), value_noscan)
}
}
fn new_map_noscan_key(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map {
metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
// for now assume anything bigger than a pointer is a string
has_string_keys := key_bytes > sizeof(voidptr)
return map{
key_bytes: key_bytes
value_bytes: value_bytes
even_index: init_even_index
cached_hashbits: max_cached_hashbits
shift: init_log_capicity
key_values: new_dense_array_noscan(key_bytes, true, value_bytes, false)
metas: unsafe { &u32(vcalloc_noscan(metasize)) }
extra_metas: extra_metas_inc
len: 0
has_string_keys: has_string_keys
hash_fn: hash_fn
key_eq_fn: key_eq_fn
clone_fn: clone_fn
free_fn: free_fn
}
}
fn new_map_noscan_value(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map {
metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
// for now assume anything bigger than a pointer is a string
has_string_keys := key_bytes > sizeof(voidptr)
return map{
key_bytes: key_bytes
value_bytes: value_bytes
even_index: init_even_index
cached_hashbits: max_cached_hashbits
shift: init_log_capicity
key_values: new_dense_array_noscan(key_bytes, false, value_bytes, true)
metas: unsafe { &u32(vcalloc_noscan(metasize)) }
extra_metas: extra_metas_inc
len: 0
has_string_keys: has_string_keys
hash_fn: hash_fn
key_eq_fn: key_eq_fn
clone_fn: clone_fn
free_fn: free_fn
}
}
fn new_map_noscan_key_value(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map {
metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
// for now assume anything bigger than a pointer is a string
has_string_keys := key_bytes > sizeof(voidptr)
return map{
key_bytes: key_bytes
value_bytes: value_bytes
even_index: init_even_index
cached_hashbits: max_cached_hashbits
shift: init_log_capicity
key_values: new_dense_array_noscan(key_bytes, true, value_bytes, true)
metas: unsafe { &u32(vcalloc_noscan(metasize)) }
extra_metas: extra_metas_inc
len: 0
has_string_keys: has_string_keys
hash_fn: hash_fn
key_eq_fn: key_eq_fn
clone_fn: clone_fn
free_fn: free_fn
}
}
fn new_map_init_noscan_key(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
mut out := new_map_noscan_key(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn,
free_fn)
// TODO pre-allocate n slots
2022-04-15 14:58:56 +03:00
mut pkey := &u8(keys)
mut pval := &u8(values)
for _ in 0 .. n {
unsafe {
out.set(pkey, pval)
pkey = pkey + key_bytes
pval = pval + value_bytes
}
}
return out
}
fn new_map_init_noscan_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
mut out := new_map_noscan_value(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn,
free_fn)
// TODO pre-allocate n slots
2022-04-15 14:58:56 +03:00
mut pkey := &u8(keys)
mut pval := &u8(values)
for _ in 0 .. n {
unsafe {
out.set(pkey, pval)
pkey = pkey + key_bytes
pval = pval + value_bytes
}
}
return out
}
fn new_map_init_noscan_key_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
mut out := new_map_noscan_key_value(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn,
free_fn)
// TODO pre-allocate n slots
2022-04-15 14:58:56 +03:00
mut pkey := &u8(keys)
mut pval := &u8(values)
for _ in 0 .. n {
unsafe {
out.set(pkey, pval)
pkey = pkey + key_bytes
pval = pval + value_bytes
}
}
return out
}