typed alloc
This commit is contained in:
@@ -1,5 +1,32 @@
|
||||
mem :: import "@std/mem"
|
||||
|
||||
_probe_count func(context ?*mut anyopaque) void {
|
||||
if context |raw| {
|
||||
counts *mut usize :: ptr_cast(usize, raw)
|
||||
counts[0] += 1
|
||||
}
|
||||
}
|
||||
|
||||
_probe_alloc func(context ?*mut anyopaque, _ usize, _ usize) ?*mut u8 {
|
||||
_probe_count(context)
|
||||
return none
|
||||
}
|
||||
|
||||
_probe_realloc func(context ?*mut anyopaque, _ ?*mut u8, _ usize, _ usize, _ usize) ?*mut u8 {
|
||||
_probe_count(context)
|
||||
return none
|
||||
}
|
||||
|
||||
_probe_free func(context ?*mut anyopaque, _ ?*mut u8, _ usize, _ usize) void {
|
||||
_probe_count(context)
|
||||
}
|
||||
|
||||
_probe_vtable mem.AllocatorVTable :: mem.AllocatorVTable {
|
||||
alloc = _probe_alloc,
|
||||
realloc = _probe_realloc,
|
||||
free = _probe_free,
|
||||
}
|
||||
|
||||
TaskList :: struct {
|
||||
ids ?[]mut i32
|
||||
priorities ?[]mut i32
|
||||
@@ -21,17 +48,19 @@ task_list_init func(allocator mem.Allocator) TaskList {
|
||||
}
|
||||
|
||||
alloc_i32s func(allocator mem.Allocator, count usize) ?[]mut i32 {
|
||||
raw ?*mut u8 = mem.alloc(allocator, count * size_of(i32), align_of(i32))
|
||||
if raw |bytes| {
|
||||
values *mut i32 = ptr_cast(i32, bytes)
|
||||
return values[..count]
|
||||
fallback [1]mut i32 = undefined
|
||||
failed bool = false
|
||||
values []mut i32 = mem.alloc(i32, allocator, count) catch |_| {
|
||||
failed = true
|
||||
yield (&fallback).ptr[..0]
|
||||
}
|
||||
return none
|
||||
if (failed) return none
|
||||
return values
|
||||
}
|
||||
|
||||
free_i32s func(allocator mem.Allocator, values ?[]mut i32) void {
|
||||
if values |slice| {
|
||||
mem.free(allocator, ptr_cast(u8, slice.ptr), slice.len * size_of(i32), align_of(i32))
|
||||
mem.raw_free(allocator, ptr_cast(u8, slice.ptr), slice.len * size_of(i32), align_of(i32))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +179,68 @@ task_list_deinit func(list @mut TaskList) void {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
resized ?*mut u8 = mem.realloc(mem.c_allocator, none, 0, 4, 1)
|
||||
if (size_of(mem.Allocator) != 16) return 31
|
||||
|
||||
first_calls [1]mut usize = [0]
|
||||
second_calls [1]mut usize = [0]
|
||||
first_allocator mem.Allocator :: mem.Allocator {
|
||||
context = (&first_calls).ptr,
|
||||
vtable = &_probe_vtable,
|
||||
}
|
||||
second_allocator mem.Allocator :: mem.Allocator {
|
||||
context = (&second_calls).ptr,
|
||||
vtable = &_probe_vtable,
|
||||
}
|
||||
|
||||
_ = mem.raw_alloc(first_allocator, 1, 1)
|
||||
_ = mem.raw_realloc(first_allocator, none, 0, 1, 1)
|
||||
mem.raw_free(first_allocator, none, 0, 1)
|
||||
_ = mem.raw_alloc(second_allocator, 1, 1)
|
||||
if (first_calls[0] != 3 or second_calls[0] != 1) return 32
|
||||
|
||||
i32_fallback [1]mut i32 = undefined
|
||||
empty_failed bool = false
|
||||
empty []mut i32 = mem.alloc(i32, first_allocator, 0) catch |_| {
|
||||
empty_failed = true
|
||||
yield (&i32_fallback).ptr[..0]
|
||||
}
|
||||
if (empty_failed or empty.len != 0 or first_calls[0] != 3) return 34
|
||||
|
||||
zero_sized_fallback [1]mut [0]u8 = undefined
|
||||
zero_sized_failed bool = false
|
||||
zero_sized []mut [0]u8 = mem.alloc([0]u8, first_allocator, 3) catch |_| {
|
||||
zero_sized_failed = true
|
||||
yield (&zero_sized_fallback).ptr[..0]
|
||||
}
|
||||
if (zero_sized_failed or zero_sized.len != 3 or first_calls[0] != 3) return 36
|
||||
_ = zero_sized[2]
|
||||
|
||||
u64_fallback [1]mut u64 = undefined
|
||||
overflow_fallback_failed bool = false
|
||||
overflow_fallback []mut u64 = mem.alloc(u64, first_allocator, 0) catch |_| {
|
||||
overflow_fallback_failed = true
|
||||
yield (&u64_fallback).ptr[..0]
|
||||
}
|
||||
if (overflow_fallback_failed) return 37
|
||||
overflow_failed bool = false
|
||||
_ = mem.alloc(u64, first_allocator, max_value(usize)) catch |_| {
|
||||
overflow_failed = true
|
||||
yield overflow_fallback
|
||||
}
|
||||
if (overflow_failed == false or first_calls[0] != 3) return 40
|
||||
|
||||
typed_failed bool = false
|
||||
typed []mut i32 = mem.alloc(i32, mem.c_allocator, 4) catch |_| {
|
||||
typed_failed = true
|
||||
yield (&i32_fallback).ptr[..0]
|
||||
}
|
||||
if (typed_failed) return 38
|
||||
defer mem.raw_free(mem.c_allocator, ptr_cast(u8, typed.ptr), typed.len * size_of(i32), align_of(i32))
|
||||
typed[0] = 10
|
||||
typed[3] = 20
|
||||
if (typed[0] + typed[3] != 30) return 39
|
||||
|
||||
resized ?*mut u8 = mem.raw_realloc(mem.c_allocator, none, 0, 4, 1)
|
||||
if resized |bytes| {
|
||||
bytes[0] = 10
|
||||
bytes[1] = 20
|
||||
@@ -160,82 +250,82 @@ main func() i32 {
|
||||
return 20
|
||||
}
|
||||
|
||||
grown ?*mut u8 = mem.realloc(mem.c_allocator, resized, 4, 8, 1)
|
||||
grown ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 4, 8, 1)
|
||||
if grown |bytes| {
|
||||
resized = grown
|
||||
if bytes[0] != 10 or bytes[1] != 20 or bytes[2] != 30 or bytes[3] != 40 {
|
||||
mem.free(mem.c_allocator, grown, 8, 1)
|
||||
mem.raw_free(mem.c_allocator, grown, 8, 1)
|
||||
return 21
|
||||
}
|
||||
} else {
|
||||
mem.free(mem.c_allocator, resized, 4, 1)
|
||||
mem.raw_free(mem.c_allocator, resized, 4, 1)
|
||||
return 22
|
||||
}
|
||||
|
||||
shrunk ?*mut u8 = mem.realloc(mem.c_allocator, resized, 8, 2, 1)
|
||||
shrunk ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 8, 2, 1)
|
||||
if shrunk |bytes| {
|
||||
resized = shrunk
|
||||
if bytes[0] != 10 or bytes[1] != 20 {
|
||||
mem.free(mem.c_allocator, shrunk, 2, 1)
|
||||
mem.raw_free(mem.c_allocator, shrunk, 2, 1)
|
||||
return 23
|
||||
}
|
||||
} else {
|
||||
mem.free(mem.c_allocator, resized, 8, 1)
|
||||
mem.raw_free(mem.c_allocator, resized, 8, 1)
|
||||
return 24
|
||||
}
|
||||
|
||||
invalid ?*mut u8 = mem.realloc(mem.c_allocator, resized, 2, 4, 24)
|
||||
invalid ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 2, 4, 24)
|
||||
if invalid |memory| {
|
||||
mem.free(mem.c_allocator, memory, 4, 24)
|
||||
mem.free(mem.c_allocator, resized, 2, 1)
|
||||
mem.raw_free(mem.c_allocator, memory, 4, 24)
|
||||
mem.raw_free(mem.c_allocator, resized, 2, 1)
|
||||
return 25
|
||||
}
|
||||
if resized |bytes| {
|
||||
if bytes[0] != 10 or bytes[1] != 20 {
|
||||
mem.free(mem.c_allocator, resized, 2, 1)
|
||||
mem.raw_free(mem.c_allocator, resized, 2, 1)
|
||||
return 26
|
||||
}
|
||||
}
|
||||
|
||||
resized = mem.realloc(mem.c_allocator, resized, 2, 0, 1)
|
||||
resized = mem.raw_realloc(mem.c_allocator, resized, 2, 0, 1)
|
||||
if resized |memory| {
|
||||
mem.free(mem.c_allocator, memory, 0, 1)
|
||||
mem.raw_free(mem.c_allocator, memory, 0, 1)
|
||||
return 27
|
||||
}
|
||||
|
||||
over_aligned ?*mut u8 = mem.alloc(mem.c_allocator, 4, 32)
|
||||
over_aligned ?*mut u8 = mem.raw_alloc(mem.c_allocator, 4, 32)
|
||||
if over_aligned |bytes| {
|
||||
bytes[0] = 11
|
||||
bytes[1] = 22
|
||||
} else {
|
||||
return 28
|
||||
}
|
||||
over_aligned_grown ?*mut u8 = mem.realloc(mem.c_allocator, over_aligned, 4, 8, 32)
|
||||
over_aligned_grown ?*mut u8 = mem.raw_realloc(mem.c_allocator, over_aligned, 4, 8, 32)
|
||||
if over_aligned_grown |bytes| {
|
||||
if bytes[0] != 11 or bytes[1] != 22 {
|
||||
mem.free(mem.c_allocator, over_aligned_grown, 8, 32)
|
||||
mem.raw_free(mem.c_allocator, over_aligned_grown, 8, 32)
|
||||
return 29
|
||||
}
|
||||
mem.free(mem.c_allocator, over_aligned_grown, 8, 32)
|
||||
mem.raw_free(mem.c_allocator, over_aligned_grown, 8, 32)
|
||||
} else {
|
||||
mem.free(mem.c_allocator, over_aligned, 4, 32)
|
||||
mem.raw_free(mem.c_allocator, over_aligned, 4, 32)
|
||||
return 30
|
||||
}
|
||||
|
||||
zero_alignment ?*mut u8 = mem.alloc(mem.c_allocator, 8, 0)
|
||||
zero_alignment ?*mut u8 = mem.raw_alloc(mem.c_allocator, 8, 0)
|
||||
if zero_alignment |memory| {
|
||||
mem.free(mem.c_allocator, memory, 8, 0)
|
||||
mem.raw_free(mem.c_allocator, memory, 8, 0)
|
||||
return 1
|
||||
}
|
||||
|
||||
bad_alignment ?*mut u8 = mem.alloc(mem.c_allocator, 8, 24)
|
||||
bad_alignment ?*mut u8 = mem.raw_alloc(mem.c_allocator, 8, 24)
|
||||
if bad_alignment |memory| {
|
||||
mem.free(mem.c_allocator, memory, 8, 24)
|
||||
mem.raw_free(mem.c_allocator, memory, 8, 24)
|
||||
return 2
|
||||
}
|
||||
|
||||
aligned ?*mut u8 = mem.alloc(mem.c_allocator, 64, 32)
|
||||
defer mem.free(mem.c_allocator, aligned, 64, 32)
|
||||
aligned ?*mut u8 = mem.raw_alloc(mem.c_allocator, 64, 32)
|
||||
defer mem.raw_free(mem.c_allocator, aligned, 64, 32)
|
||||
if aligned |bytes| {
|
||||
bytes[0] = 1
|
||||
bytes[63] = 2
|
||||
|
||||
Reference in New Issue
Block a user