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:
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user