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

all: gc: provide optimized mode (#9716)

This commit is contained in:
Uwe Krüger
2021-04-14 00:40:26 +02:00
committed by GitHub
parent 8c95f07509
commit 10bf974cda
26 changed files with 11724 additions and 49 deletions

View File

@ -96,7 +96,7 @@ fn (mut a array) ensure_cap(required int) {
}
new_size := cap * a.element_size
mut new_data := &byte(0)
if a.cap > 0 {
if a.data != voidptr(0) {
new_data = unsafe { realloc_data(a.data, a.cap * a.element_size, new_size) }
} else {
new_data = vcalloc(new_size)
@ -656,3 +656,167 @@ pub fn (data voidptr) vbytes(len int) []byte {
pub fn (data &byte) vbytes(len int) []byte {
return unsafe { voidptr(data).vbytes(len) }
}
// non-pub "noscan" versions of some above functions
fn __new_array_noscan(mylen int, cap int, elm_size int) array {
cap_ := if cap < mylen { mylen } else { cap }
arr := array{
element_size: elm_size
data: vcalloc_noscan(cap_ * elm_size)
len: mylen
cap: cap_
}
return arr
}
fn __new_array_with_default_noscan(mylen int, cap int, elm_size int, val voidptr) array {
cap_ := if cap < mylen { mylen } else { cap }
mut arr := array{
element_size: elm_size
data: vcalloc_noscan(cap_ * elm_size)
len: mylen
cap: cap_
}
if val != 0 {
for i in 0 .. arr.len {
unsafe { arr.set_unsafe(i, val) }
}
}
return arr
}
fn __new_array_with_array_default_noscan(mylen int, cap int, elm_size int, val array) array {
cap_ := if cap < mylen { mylen } else { cap }
mut arr := array{
element_size: elm_size
data: vcalloc_noscan(cap_ * elm_size)
len: mylen
cap: cap_
}
for i in 0 .. arr.len {
val_clone := val.clone()
unsafe { arr.set_unsafe(i, &val_clone) }
}
return arr
}
// Private function, used by V (`nums := [1, 2, 3]`)
fn new_array_from_c_array_noscan(len int, cap int, elm_size int, c_array voidptr) array {
cap_ := if cap < len { len } else { cap }
arr := array{
element_size: elm_size
data: vcalloc_noscan(cap_ * elm_size)
len: len
cap: cap_
}
// TODO Write all memory functions (like memcpy) in V
unsafe { C.memcpy(arr.data, c_array, len * elm_size) }
return arr
}
fn (a array) repeat_noscan(count int) array {
if count < 0 {
panic('array.repeat: count is negative: $count')
}
mut size := count * a.len * a.element_size
if size == 0 {
size = a.element_size
}
arr := array{
element_size: a.element_size
data: vcalloc_noscan(size)
len: count * a.len
cap: count * a.len
}
size_of_array := int(sizeof(array))
for i in 0 .. count {
if a.len > 0 && a.element_size == size_of_array {
ary := array{}
unsafe { C.memcpy(&ary, a.data, size_of_array) }
ary_clone := ary.clone()
unsafe { C.memcpy(arr.get_unsafe(i * a.len), &ary_clone, a.len * a.element_size) }
} else {
unsafe { C.memcpy(arr.get_unsafe(i * a.len), &byte(a.data), a.len * a.element_size) }
}
}
return arr
}
pub fn (a &array) clone_noscan() array {
mut size := a.cap * a.element_size
if size == 0 {
size++
}
mut arr := array{
element_size: a.element_size
data: vcalloc_noscan(size)
len: a.len
cap: a.cap
}
// Recursively clone-generated elements if array element is array type
size_of_array := int(sizeof(array))
if a.element_size == size_of_array {
mut is_elem_array := true
for i in 0 .. a.len {
ar := array{}
unsafe { C.memcpy(&ar, a.get_unsafe(i), size_of_array) }
if ar.len > ar.cap || ar.cap <= 0 || ar.element_size <= 0 {
is_elem_array = false
break
}
ar_clone := ar.clone()
unsafe { arr.set_unsafe(i, &ar_clone) }
}
if is_elem_array {
return arr
}
}
if !isnil(a.data) {
unsafe { C.memcpy(&byte(arr.data), a.data, a.cap * a.element_size) }
}
return arr
}
fn (a &array) slice_clone_noscan(start int, _end int) array {
mut end := _end
$if !no_bounds_checking ? {
if start > end {
panic('array.slice: invalid slice index ($start > $end)')
}
if end > a.len {
panic('array.slice: slice bounds out of range ($end >= $a.len)')
}
if start < 0 {
panic('array.slice: slice bounds out of range ($start < 0)')
}
}
mut data := &byte(0)
unsafe {
data = &byte(a.data) + start * a.element_size
}
l := end - start
res := array{
element_size: a.element_size
data: data
len: l
cap: l
}
return res.clone_noscan()
}
fn (a array) reverse_noscan() array {
if a.len < 2 {
return a
}
mut arr := array{
element_size: a.element_size
data: vcalloc_noscan(a.cap * a.element_size)
len: a.len
cap: a.cap
}
for i in 0 .. a.len {
unsafe { arr.set_unsafe(i, a.get_unsafe(a.len - 1 - i)) }
}
return arr
}