mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
use capacity instead of length in list deinit
This commit is contained in:
parent
b8a6e05ed9
commit
4e5b106f98
3 changed files with 40 additions and 9 deletions
|
@ -76,7 +76,7 @@ pub const RocList = extern struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: RocList, comptime T: type) void {
|
pub fn deinit(self: RocList, comptime T: type) void {
|
||||||
utils.decref(self.bytes, self.len(), @alignOf(T));
|
utils.decref(self.bytes, self.capacity, @alignOf(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elements(self: RocList, comptime T: type) ?[*]T {
|
pub fn elements(self: RocList, comptime T: type) ?[*]T {
|
||||||
|
@ -84,14 +84,21 @@ pub const RocList = extern struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isUnique(self: RocList) bool {
|
pub fn isUnique(self: RocList) bool {
|
||||||
// the empty list is unique (in the sense that copying it will not leak memory)
|
return self.refcountMachine() == utils.REFCOUNT_ONE;
|
||||||
if (self.isEmpty()) {
|
}
|
||||||
return true;
|
|
||||||
|
fn refcountMachine(self: RocList) usize {
|
||||||
|
if (self.capacity == 0) {
|
||||||
|
// the zero-capacity is Clone, copying it will not leak memory
|
||||||
|
return utils.REFCOUNT_ONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, check if the refcount is one
|
|
||||||
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(@alignOf(usize), self.bytes));
|
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(@alignOf(usize), self.bytes));
|
||||||
return (ptr - 1)[0] == utils.REFCOUNT_ONE;
|
return (ptr - 1)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refcountHuman(self: RocList) usize {
|
||||||
|
return self.refcountMachine() - utils.REFCOUNT_ONE + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn makeUniqueExtra(self: RocList, alignment: u32, element_width: usize, update_mode: UpdateMode) RocList {
|
pub fn makeUniqueExtra(self: RocList, alignment: u32, element_width: usize, update_mode: UpdateMode) RocList {
|
||||||
|
@ -740,10 +747,14 @@ fn swapElements(source_ptr: [*]u8, element_width: usize, index_1: usize, index_2
|
||||||
pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_width: usize) callconv(.C) RocList {
|
pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_width: usize) callconv(.C) RocList {
|
||||||
// NOTE we always use list_a! because it is owned, we must consume it, and it may have unused capacity
|
// NOTE we always use list_a! because it is owned, we must consume it, and it may have unused capacity
|
||||||
if (list_b.isEmpty()) {
|
if (list_b.isEmpty()) {
|
||||||
|
if (list_a.capacity == 0) {
|
||||||
|
return list_b;
|
||||||
|
} else {
|
||||||
// we must consume this list. Even though it has no elements, it could still have capacity
|
// we must consume this list. Even though it has no elements, it could still have capacity
|
||||||
list_b.deinit(usize);
|
list_b.deinit(usize);
|
||||||
|
|
||||||
return list_a;
|
return list_a;
|
||||||
|
}
|
||||||
} else if (list_a.isUnique()) {
|
} else if (list_a.isUnique()) {
|
||||||
const total_length: usize = list_a.len() + list_b.len();
|
const total_length: usize = list_a.len() + list_b.len();
|
||||||
|
|
||||||
|
|
|
@ -324,6 +324,10 @@ pub const RocStr = extern struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refcountMachine(self: RocStr) usize {
|
fn refcountMachine(self: RocStr) usize {
|
||||||
|
if (self.getCapacity() == 0 or self.isSmallStr()) {
|
||||||
|
return utils.REFCOUNT_ONE;
|
||||||
|
}
|
||||||
|
|
||||||
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(@alignOf(usize), self.str_bytes));
|
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(@alignOf(usize), self.str_bytes));
|
||||||
return (ptr - 1)[0];
|
return (ptr - 1)[0];
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,22 @@ fn list_concat_consumes_first_argument() {
|
||||||
valgrind_test("List.concat (List.withCapacity 1024) [1,2,3] |> List.len |> Num.toStr");
|
valgrind_test("List.concat (List.withCapacity 1024) [1,2,3] |> List.len |> Num.toStr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn list_concat_consumes_second_argument() {
|
||||||
|
valgrind_test(indoc!(
|
||||||
|
r#"
|
||||||
|
(
|
||||||
|
a : List U8
|
||||||
|
a = []
|
||||||
|
b = List.reserve [] 11
|
||||||
|
List.concat a b
|
||||||
|
|> List.len
|
||||||
|
|> Num.toStr
|
||||||
|
)
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn str_capacity_concat() {
|
fn str_capacity_concat() {
|
||||||
valgrind_test(r#"Str.withCapacity 42 |> Str.concat "foobar""#);
|
valgrind_test(r#"Str.withCapacity 42 |> Str.concat "foobar""#);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue