mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-04 13:18:31 +00:00
Breaking Change: Allocator_Packed_Info as part of the Allocator_Proc interface to minimize register use with calls
This commit is contained in:
@@ -420,9 +420,17 @@ Allocator_Error :: enum byte {
|
||||
Multiplication_Overflow_On_Requested_Size = 5,
|
||||
}
|
||||
|
||||
Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
Allocator_Packed_Info :: struct {
|
||||
mode: Allocator_Mode,
|
||||
log2_alignment: u8,
|
||||
}
|
||||
|
||||
// NOTE(bill): Allocator_Packed_Info could be packed even further to 8 bits (3:mode + 5:log2_alignment)
|
||||
// but this is not benefiting any ABI whatsoever to minimize it furthers
|
||||
#assert(size_of(Allocator_Packed_Info) == 2)
|
||||
|
||||
Allocator_Proc :: #type proc(allocator_data: rawptr, packed_info: Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int,
|
||||
location: Source_Code_Location = #caller_location) -> ([]byte, Allocator_Error)
|
||||
Allocator :: struct {
|
||||
procedure: Allocator_Proc,
|
||||
|
||||
@@ -651,7 +651,8 @@ make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := con
|
||||
|
||||
byte_count, overflows := intrinsics.overflow_mul(size_of(E), len)
|
||||
if overflows {
|
||||
return .Multiplication_Overflow_On_Requested_Size
|
||||
err = .Multiplication_Overflow_On_Requested_Size
|
||||
return
|
||||
}
|
||||
|
||||
data := mem_alloc_bytes(byte_count, align_of(E), allocator, loc) or_return
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package runtime
|
||||
|
||||
nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||
switch mode {
|
||||
nil_allocator_proc :: proc(allocator_data: rawptr, packed_info: Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||
switch packed_info.mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
return nil, .Out_Of_Memory
|
||||
case .Free:
|
||||
@@ -40,10 +39,9 @@ nil_allocator :: proc "contextless" () -> Allocator {
|
||||
}
|
||||
|
||||
|
||||
panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||
switch mode {
|
||||
panic_allocator_proc :: proc(allocator_data: rawptr, packed_info: Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||
switch packed_info.mode {
|
||||
case .Alloc:
|
||||
if size > 0 {
|
||||
panic("panic allocator, .Alloc called", loc=loc)
|
||||
|
||||
@@ -183,16 +183,15 @@ arena_allocator :: proc(arena: ^Arena) -> Allocator {
|
||||
return Allocator{arena_allocator_proc, arena}
|
||||
}
|
||||
|
||||
arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
arena_allocator_proc :: proc(allocator_data: rawptr, packed_info: Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
arena := (^Arena)(allocator_data)
|
||||
|
||||
size, alignment := uint(size), uint(alignment)
|
||||
size, alignment := uint(size), uint(1)<<packed_info.log2_alignment
|
||||
old_size := uint(old_size)
|
||||
|
||||
switch mode {
|
||||
switch packed_info.mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
return arena_alloc(arena, size, alignment, location)
|
||||
case .Free:
|
||||
|
||||
@@ -41,12 +41,11 @@ when NO_DEFAULT_TEMP_ALLOCATOR {
|
||||
}
|
||||
}
|
||||
|
||||
default_temp_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
default_temp_allocator_proc :: proc(allocator_data: rawptr, packed_info: Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
|
||||
s := (^Default_Temp_Allocator)(allocator_data)
|
||||
return arena_allocator_proc(&s.arena, mode, size, alignment, old_memory, old_size, loc)
|
||||
return arena_allocator_proc(&s.arena, packed_info, size, old_memory, old_size, loc)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
|
||||
@@ -10,8 +10,8 @@ heap_allocator :: proc() -> Allocator {
|
||||
}
|
||||
}
|
||||
|
||||
heap_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
heap_allocator_proc :: proc(allocator_data: rawptr, packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||
//
|
||||
// NOTE(tetra, 2020-01-14): The heap doesn't respect alignment.
|
||||
@@ -20,6 +20,9 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
// the pointer we return to the user.
|
||||
//
|
||||
|
||||
mode := packed_info.mode
|
||||
alignment := int(1)<<packed_info.log2_alignment
|
||||
|
||||
aligned_alloc :: proc(size, alignment: int, old_ptr: rawptr, old_size: int, zero_memory := true) -> ([]byte, Allocator_Error) {
|
||||
// Not(flysand): We need to reserve enough space for alignment, which
|
||||
// includes the user data itself, the space to store the pointer to
|
||||
|
||||
@@ -30,6 +30,15 @@ NATIVE_SIMD_BIT_WIDTH ::
|
||||
// Fallback for no hardware SIMD, but also SSE, NEON, SVE, RVV and WASM SIMD128.
|
||||
128
|
||||
|
||||
@(require_results)
|
||||
_u8_log2 :: proc "contextless" (x: $T) -> (res: u8) where intrinsics.type_is_integer(T) {
|
||||
if x <= 0 {
|
||||
return 0
|
||||
}
|
||||
return u8((8*size_of(T)-1) - intrinsics.count_leading_zeros(x))
|
||||
}
|
||||
|
||||
|
||||
@(private)
|
||||
byte_slice :: #force_inline proc "contextless" (data: rawptr, len: int) -> []byte #no_bounds_check {
|
||||
return ([^]byte)(data)[:max(len, 0)]
|
||||
@@ -119,7 +128,7 @@ mem_alloc_bytes :: #force_no_inline proc(size: int, alignment: int = DEFAULT_ALI
|
||||
if size == 0 || allocator.procedure == nil{
|
||||
return nil, nil
|
||||
}
|
||||
return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc)
|
||||
return allocator.procedure(allocator.data, {.Alloc, _u8_log2(alignment)}, size, nil, 0, loc)
|
||||
}
|
||||
|
||||
mem_alloc :: #force_no_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||
@@ -127,7 +136,7 @@ mem_alloc :: #force_no_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT
|
||||
if size == 0 || allocator.procedure == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc)
|
||||
return allocator.procedure(allocator.data, {.Alloc, _u8_log2(alignment)}, size, nil, 0, loc)
|
||||
}
|
||||
|
||||
mem_alloc_non_zeroed :: #force_no_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||
@@ -135,7 +144,7 @@ mem_alloc_non_zeroed :: #force_no_inline proc(size: int, alignment: int = DEFAUL
|
||||
if size == 0 || allocator.procedure == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return allocator.procedure(allocator.data, .Alloc_Non_Zeroed, size, alignment, nil, 0, loc)
|
||||
return allocator.procedure(allocator.data, {.Alloc_Non_Zeroed, _u8_log2(alignment)}, size, nil, 0, loc)
|
||||
}
|
||||
|
||||
@builtin
|
||||
@@ -143,7 +152,7 @@ mem_free :: #force_no_inline proc(ptr: rawptr, allocator := context.allocator, l
|
||||
if ptr == nil || allocator.procedure == nil {
|
||||
return nil
|
||||
}
|
||||
_, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, loc)
|
||||
_, err := allocator.procedure(allocator.data, {.Free, 0}, 0, ptr, 0, loc)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -151,7 +160,7 @@ mem_free_with_size :: #force_no_inline proc(ptr: rawptr, byte_count: int, alloca
|
||||
if ptr == nil || allocator.procedure == nil {
|
||||
return nil
|
||||
}
|
||||
_, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, byte_count, loc)
|
||||
_, err := allocator.procedure(allocator.data, {.Free, 0}, 0, ptr, byte_count, loc)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -159,67 +168,66 @@ mem_free_bytes :: #force_no_inline proc(bytes: []byte, allocator := context.allo
|
||||
if bytes == nil || allocator.procedure == nil {
|
||||
return nil
|
||||
}
|
||||
_, err := allocator.procedure(allocator.data, .Free, 0, 0, raw_data(bytes), len(bytes), loc)
|
||||
_, err := allocator.procedure(allocator.data, {.Free, 0}, 0, raw_data(bytes), len(bytes), loc)
|
||||
return err
|
||||
}
|
||||
|
||||
@builtin
|
||||
mem_free_all :: #force_no_inline proc(allocator := context.allocator, loc := #caller_location) -> (err: Allocator_Error) {
|
||||
if allocator.procedure != nil {
|
||||
_, err = allocator.procedure(allocator.data, .Free_All, 0, 0, nil, 0, loc)
|
||||
_, err = allocator.procedure(allocator.data, {.Free_All, 0}, 0, nil, 0, loc)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_mem_resize :: #force_no_inline proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, should_zero: bool, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
|
||||
_mem_resize :: #force_no_inline proc(ptr: rawptr, old_size, new_size: int, log2_alignment: u8, allocator := context.allocator, should_zero: bool, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
if allocator.procedure == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if new_size == 0 {
|
||||
if ptr != nil {
|
||||
_, err = allocator.procedure(allocator.data, .Free, 0, 0, ptr, old_size, loc)
|
||||
_, err = allocator.procedure(allocator.data, {.Free, log2_alignment}, 0, ptr, old_size, loc)
|
||||
return
|
||||
}
|
||||
return
|
||||
} else if ptr == nil {
|
||||
if should_zero {
|
||||
return allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc)
|
||||
return allocator.procedure(allocator.data, {.Alloc, log2_alignment}, new_size, nil, 0, loc)
|
||||
} else {
|
||||
return allocator.procedure(allocator.data, .Alloc_Non_Zeroed, new_size, alignment, nil, 0, loc)
|
||||
return allocator.procedure(allocator.data, {.Alloc_Non_Zeroed, log2_alignment}, new_size, nil, 0, loc)
|
||||
}
|
||||
} else if old_size == new_size && uintptr(ptr) % uintptr(alignment) == 0 {
|
||||
} else if old_size == new_size && uintptr(ptr) % (uintptr(1)<<log2_alignment) == 0 {
|
||||
data = ([^]byte)(ptr)[:old_size]
|
||||
return
|
||||
}
|
||||
|
||||
if should_zero {
|
||||
data, err = allocator.procedure(allocator.data, .Resize, new_size, alignment, ptr, old_size, loc)
|
||||
data, err = allocator.procedure(allocator.data, {.Resize, log2_alignment}, new_size, ptr, old_size, loc)
|
||||
} else {
|
||||
data, err = allocator.procedure(allocator.data, .Resize_Non_Zeroed, new_size, alignment, ptr, old_size, loc)
|
||||
data, err = allocator.procedure(allocator.data, {.Resize_Non_Zeroed, log2_alignment}, new_size, ptr, old_size, loc)
|
||||
}
|
||||
if err == .Mode_Not_Implemented {
|
||||
if should_zero {
|
||||
data, err = allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc)
|
||||
data, err = allocator.procedure(allocator.data, {.Alloc, log2_alignment}, new_size, nil, 0, loc)
|
||||
} else {
|
||||
data, err = allocator.procedure(allocator.data, .Alloc_Non_Zeroed, new_size, alignment, nil, 0, loc)
|
||||
data, err = allocator.procedure(allocator.data, {.Alloc_Non_Zeroed, log2_alignment}, new_size, nil, 0, loc)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
copy(data, ([^]byte)(ptr)[:old_size])
|
||||
_, err = allocator.procedure(allocator.data, .Free, 0, 0, ptr, old_size, loc)
|
||||
_, err = allocator.procedure(allocator.data, {.Free, log2_alignment}, 0, ptr, old_size, loc)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
|
||||
return _mem_resize(ptr, old_size, new_size, alignment, allocator, true, loc)
|
||||
return _mem_resize(ptr, old_size, new_size, _u8_log2(alignment), allocator, true, loc)
|
||||
}
|
||||
non_zero_mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
|
||||
return _mem_resize(ptr, old_size, new_size, alignment, allocator, false, loc)
|
||||
return _mem_resize(ptr, old_size, new_size, _u8_log2(alignment), allocator, false, loc)
|
||||
}
|
||||
|
||||
conditional_mem_zero :: proc "contextless" (data: rawptr, n_: int) #no_bounds_check {
|
||||
|
||||
@@ -59,19 +59,22 @@ log_allocator :: proc(la: ^Log_Allocator) -> runtime.Allocator {
|
||||
|
||||
// Backing procedure for allocator that logs all allocations.
|
||||
log_allocator_proc :: proc(allocator_data: rawptr,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, location := #caller_location) -> ([]byte, runtime.Allocator_Error) {
|
||||
la := (^Log_Allocator)(allocator_data)
|
||||
packed_info: runtime.Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int, location := #caller_location) -> ([]byte, runtime.Allocator_Error) {
|
||||
la := (^Log_Allocator)(allocator_data)
|
||||
|
||||
if context.logger.procedure == nil || la.level < context.logger.lowest_level {
|
||||
return la.allocator.procedure(la.allocator.data, packed_info, size, old_memory, old_size, location)
|
||||
}
|
||||
}
|
||||
|
||||
padding := " " if la.prefix != "" else ""
|
||||
|
||||
buf: [256]byte = ---
|
||||
|
||||
mode := packed_info.mode
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
|
||||
sync.lock(&la.lock)
|
||||
switch mode {
|
||||
case .Alloc:
|
||||
format: string
|
||||
@@ -138,7 +141,7 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
|
||||
sync.unlock(&la.lock)
|
||||
|
||||
data, err := la.allocator.procedure(la.allocator.data, packed_info, size, old_memory, old_size, location)
|
||||
if err != nil {
|
||||
if err != nil {
|
||||
sync.lock(&la.lock)
|
||||
str := fmt.bprintf(buf[:], "%s%sALLOCATOR ERROR=%v", la.prefix, padding, err)
|
||||
context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location)
|
||||
|
||||
@@ -119,6 +119,7 @@ Error :: enum byte {
|
||||
Invalid_Pointer = 2,
|
||||
Invalid_Argument = 3,
|
||||
Mode_Not_Implemented = 4, // Allocation
|
||||
Multiplication_Overflow_On_Requested_Size = 5,
|
||||
|
||||
Assignment_To_Immutable = 10,
|
||||
Max_Iterations_Reached = 11,
|
||||
@@ -147,6 +148,7 @@ Error_String :: #sparse[Error]string{
|
||||
.Invalid_Pointer = "Invalid pointer",
|
||||
.Invalid_Argument = "Invalid argument",
|
||||
.Mode_Not_Implemented = "Allocation mode not implemented",
|
||||
.Multiplication_Overflow_On_Requested_Size = "Multiplication overflow on requested allocation size",
|
||||
|
||||
.Assignment_To_Immutable = "Assignment to immutable",
|
||||
.Max_Iterations_Reached = "Max iterations reached",
|
||||
|
||||
@@ -246,6 +246,9 @@ is defined as follows:
|
||||
*/
|
||||
Allocator :: runtime.Allocator
|
||||
|
||||
Allocator_Packed_Info :: runtime.Allocator_Packed_Info
|
||||
|
||||
|
||||
/*
|
||||
Default alignment.
|
||||
|
||||
@@ -709,7 +712,7 @@ Query allocator features.
|
||||
@(require_results)
|
||||
query_features :: proc(allocator: Allocator, loc := #caller_location) -> (set: Allocator_Mode_Set) {
|
||||
if allocator.procedure != nil {
|
||||
allocator.procedure(allocator.data, .Query_Features, 0, 0, &set, 0, loc)
|
||||
allocator.procedure(allocator.data, {.Query_Features, 0}, 0, &set, 0, loc)
|
||||
return set
|
||||
}
|
||||
return nil
|
||||
@@ -726,7 +729,7 @@ query_info :: proc(
|
||||
) -> (props: Allocator_Query_Info) {
|
||||
props.pointer = pointer
|
||||
if allocator.procedure != nil {
|
||||
allocator.procedure(allocator.data, .Query_Info, 0, 0, &props, 0, loc)
|
||||
allocator.procedure(allocator.data, {.Query_Info, 0}, 0, &props, 0, loc)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ nil_allocator :: proc() -> Allocator {
|
||||
|
||||
nil_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
@@ -98,13 +98,13 @@ panic_allocator :: proc() -> Allocator {
|
||||
|
||||
panic_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
) -> ([]byte, Allocator_Error) {
|
||||
switch mode {
|
||||
switch packed_info.mode {
|
||||
case .Alloc:
|
||||
if size > 0 {
|
||||
panic("mem: panic allocator, .Alloc called", loc=loc)
|
||||
@@ -291,14 +291,15 @@ arena_free_all :: proc(a: ^Arena) {
|
||||
|
||||
arena_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
alignment: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
) -> ([]byte, Allocator_Error) {
|
||||
arena := cast(^Arena)allocator_data
|
||||
mode := packed_info.mode
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
switch mode {
|
||||
case .Alloc:
|
||||
return arena_alloc_bytes(arena, size, alignment, loc)
|
||||
@@ -772,14 +773,16 @@ scratch_resize_bytes_non_zeroed :: proc(
|
||||
}
|
||||
|
||||
scratch_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
allocator_data: rawptr,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
) -> ([]byte, Allocator_Error) {
|
||||
s := (^Scratch)(allocator_data)
|
||||
mode := packed_info.mode
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
size := size
|
||||
switch mode {
|
||||
case .Alloc:
|
||||
@@ -1190,9 +1193,8 @@ stack_resize_bytes_non_zeroed :: proc(
|
||||
|
||||
stack_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
alignment: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
@@ -1201,7 +1203,8 @@ stack_allocator_proc :: proc(
|
||||
if s.data == nil {
|
||||
return nil, .Invalid_Argument
|
||||
}
|
||||
switch mode {
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
switch packed_info.mode {
|
||||
case .Alloc:
|
||||
return stack_alloc_bytes(s, size, alignment, loc)
|
||||
case .Alloc_Non_Zeroed:
|
||||
@@ -1585,18 +1588,19 @@ small_stack_resize_bytes_non_zeroed :: proc(
|
||||
}
|
||||
|
||||
small_stack_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
allocator_data: rawptr,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
) -> ([]byte, Allocator_Error) {
|
||||
s := cast(^Small_Stack)allocator_data
|
||||
if s.data == nil {
|
||||
return nil, .Invalid_Argument
|
||||
}
|
||||
switch mode {
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
switch packed_info.mode {
|
||||
case .Alloc:
|
||||
return small_stack_alloc_bytes(s, size, alignment, loc)
|
||||
case .Alloc_Non_Zeroed:
|
||||
@@ -1725,12 +1729,13 @@ _dynamic_arena_cycle_new_block :: proc(a: ^Dynamic_Arena, alignment: int, loc :=
|
||||
if len(a.unused_blocks) > 0 {
|
||||
new_block = pop(&a.unused_blocks)
|
||||
} else {
|
||||
log2_alignment := runtime._u8_log2(max(a.minimum_alignment, alignment))
|
||||
|
||||
data: []byte
|
||||
data, err = a.block_allocator.procedure(
|
||||
a.block_allocator.data,
|
||||
Allocator_Mode.Alloc,
|
||||
{.Alloc, log2_alignment},
|
||||
a.block_size,
|
||||
max(a.minimum_alignment, alignment),
|
||||
nil,
|
||||
0,
|
||||
)
|
||||
@@ -2001,15 +2006,15 @@ dynamic_arena_resize_bytes_non_zeroed :: proc(
|
||||
|
||||
dynamic_arena_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
alignment: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
) -> ([]byte, Allocator_Error) {
|
||||
arena := (^Dynamic_Arena)(allocator_data)
|
||||
switch mode {
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
switch packed_info.mode {
|
||||
case .Alloc:
|
||||
return dynamic_arena_alloc_bytes(arena, size, alignment, loc)
|
||||
case .Alloc_Non_Zeroed:
|
||||
@@ -2362,15 +2367,16 @@ buddy_allocator_free_all :: proc(b: ^Buddy_Allocator) {
|
||||
|
||||
@(no_sanitize_address)
|
||||
buddy_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
allocator_data: rawptr,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
) -> ([]byte, Allocator_Error) {
|
||||
b := (^Buddy_Allocator)(allocator_data)
|
||||
switch mode {
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
switch packed_info.mode {
|
||||
case .Alloc:
|
||||
return buddy_allocator_alloc_bytes(b, uint(size))
|
||||
case .Alloc_Non_Zeroed:
|
||||
@@ -2431,9 +2437,8 @@ compat_allocator :: proc(rra: ^Compat_Allocator) -> Allocator {
|
||||
}
|
||||
}
|
||||
|
||||
compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
compat_allocator_proc :: proc(allocator_data: rawptr, packed_info: Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
Header :: struct {
|
||||
size: int,
|
||||
@@ -2448,6 +2453,9 @@ compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
return header
|
||||
}
|
||||
|
||||
mode := packed_info.mode
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
|
||||
rra := (^Compat_Allocator)(allocator_data)
|
||||
switch mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
@@ -2455,7 +2463,7 @@ compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
req_size := size + a
|
||||
assert(req_size >= 0, "overflow")
|
||||
|
||||
allocation := rra.parent.procedure(rra.parent.data, mode, req_size, alignment, old_memory, old_size, location) or_return
|
||||
allocation := rra.parent.procedure(rra.parent.data, {mode, runtime._u8_log2(a)}, req_size, old_memory, old_size, location) or_return
|
||||
#no_bounds_check data = allocation[a:]
|
||||
|
||||
([^]Header)(raw_data(data))[-1] = {
|
||||
@@ -2472,7 +2480,7 @@ compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
orig_ptr := rawptr(uintptr(old_memory)-uintptr(a))
|
||||
orig_size := header.size + a
|
||||
|
||||
return rra.parent.procedure(rra.parent.data, mode, orig_size, header.alignment, orig_ptr, orig_size, location)
|
||||
return rra.parent.procedure(rra.parent.data, {mode, runtime._u8_log2(header.alignment)}, orig_size, orig_ptr, orig_size, location)
|
||||
|
||||
case .Resize, .Resize_Non_Zeroed:
|
||||
header := get_unpoisoned_header(old_memory)
|
||||
@@ -2486,7 +2494,7 @@ compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
req_size := size + a
|
||||
assert(size >= 0, "overflow")
|
||||
|
||||
allocation := rra.parent.procedure(rra.parent.data, mode, req_size, new_alignment, orig_ptr, orig_size, location) or_return
|
||||
allocation := rra.parent.procedure(rra.parent.data, {mode, runtime._u8_log2(new_alignment)}, req_size, orig_ptr, orig_size, location) or_return
|
||||
#no_bounds_check data = allocation[a:]
|
||||
|
||||
([^]Header)(raw_data(data))[-1] = {
|
||||
@@ -2498,7 +2506,7 @@ compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
return
|
||||
|
||||
case .Free_All:
|
||||
return rra.parent.procedure(rra.parent.data, mode, size, alignment, old_memory, old_size, location)
|
||||
return rra.parent.procedure(rra.parent.data, {mode, runtime._u8_log2(alignment)}, size, old_memory, old_size, location)
|
||||
|
||||
case .Query_Info:
|
||||
info := (^Allocator_Query_Info)(old_memory)
|
||||
@@ -2510,7 +2518,7 @@ compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
return
|
||||
|
||||
case .Query_Features:
|
||||
data, err = rra.parent.procedure(rra.parent.data, mode, size, alignment, old_memory, old_size, location)
|
||||
data, err = rra.parent.procedure(rra.parent.data, {mode, runtime._u8_log2(alignment)}, size, old_memory, old_size, location)
|
||||
if err != nil {
|
||||
set := (^Allocator_Mode_Set)(old_memory)
|
||||
set^ += {.Query_Info}
|
||||
|
||||
@@ -38,15 +38,14 @@ mutex_allocator :: proc(m: ^Mutex_Allocator) -> Allocator {
|
||||
|
||||
mutex_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
alignment: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
) -> (result: []byte, err: Allocator_Error) {
|
||||
m := (^Mutex_Allocator)(allocator_data)
|
||||
sync.mutex_guard(&m.mutex)
|
||||
return m.backing.procedure(m.backing.data, mode, size, alignment, old_memory, old_size, loc)
|
||||
return m.backing.procedure(m.backing.data, packed_info, size, old_memory, old_size, loc)
|
||||
}
|
||||
|
||||
|
||||
@@ -458,14 +458,15 @@ rollback_stack_allocator :: proc(stack: ^Rollback_Stack) -> Allocator {
|
||||
@(require_results, no_sanitize_address)
|
||||
rollback_stack_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
) -> (result: []byte, err: Allocator_Error) {
|
||||
stack := cast(^Rollback_Stack)allocator_data
|
||||
switch mode {
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
switch packed_info.mode {
|
||||
case .Alloc:
|
||||
return rb_alloc_bytes(stack, size, alignment, loc)
|
||||
case .Alloc_Non_Zeroed:
|
||||
|
||||
@@ -137,8 +137,8 @@ destroy :: proc(control: ^Allocator) {
|
||||
}
|
||||
}
|
||||
|
||||
allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
allocator_proc :: proc(allocator_data: rawptr, packed_info: runtime.Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr, old_size: int, location := #caller_location) -> ([]byte, runtime.Allocator_Error) {
|
||||
|
||||
control := (^Allocator)(allocator_data)
|
||||
@@ -146,11 +146,13 @@ allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
|
||||
return nil, .Invalid_Argument
|
||||
}
|
||||
|
||||
switch mode {
|
||||
alignment := uint(1)<<packed_info.log2_alignment
|
||||
|
||||
switch packed_info.mode {
|
||||
case .Alloc:
|
||||
return alloc_bytes(control, uint(size), uint(alignment))
|
||||
return alloc_bytes(control, uint(size), alignment)
|
||||
case .Alloc_Non_Zeroed:
|
||||
return alloc_bytes_non_zeroed(control, uint(size), uint(alignment))
|
||||
return alloc_bytes_non_zeroed(control, uint(size), alignment)
|
||||
|
||||
case .Free:
|
||||
free_with_size(control, old_memory, uint(old_size))
|
||||
@@ -161,10 +163,10 @@ allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
|
||||
return nil, nil
|
||||
|
||||
case .Resize:
|
||||
return resize(control, old_memory, uint(old_size), uint(size), uint(alignment))
|
||||
return resize(control, old_memory, uint(old_size), uint(size), alignment)
|
||||
|
||||
case .Resize_Non_Zeroed:
|
||||
return resize_non_zeroed(control, old_memory, uint(old_size), uint(size), uint(alignment))
|
||||
return resize_non_zeroed(control, old_memory, uint(old_size), uint(size), alignment)
|
||||
|
||||
case .Query_Features:
|
||||
set := (^runtime.Allocator_Mode_Set)(old_memory)
|
||||
|
||||
@@ -192,8 +192,8 @@ tracking_allocator :: proc(data: ^Tracking_Allocator) -> Allocator {
|
||||
@(no_sanitize_address)
|
||||
tracking_allocator_proc :: proc(
|
||||
allocator_data: rawptr,
|
||||
mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
packed_info: Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr,
|
||||
old_size: int,
|
||||
loc := #caller_location,
|
||||
@@ -216,6 +216,8 @@ tracking_allocator_proc :: proc(
|
||||
}
|
||||
|
||||
data := (^Tracking_Allocator)(allocator_data)
|
||||
mode := packed_info.mode
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
|
||||
sync.mutex_guard(&data.mutex)
|
||||
|
||||
@@ -237,7 +239,7 @@ tracking_allocator_proc :: proc(
|
||||
data.bad_free_callback(data, old_memory, loc)
|
||||
}
|
||||
} else {
|
||||
result = data.backing.procedure(data.backing.data, mode, size, alignment, old_memory, old_size, loc) or_return
|
||||
result = data.backing.procedure(data.backing.data, packed_info, size, old_memory, old_size, loc) or_return
|
||||
}
|
||||
result_ptr := raw_data(result)
|
||||
|
||||
|
||||
@@ -326,13 +326,15 @@ arena_allocator :: proc(arena: ^Arena) -> mem.Allocator {
|
||||
|
||||
// The allocator procedure used by an `Allocator` produced by `arena_allocator`
|
||||
@(no_sanitize_address)
|
||||
arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
arena_allocator_proc :: proc(allocator_data: rawptr, packed_info: mem.Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
arena := (^Arena)(allocator_data)
|
||||
|
||||
size, alignment := uint(size), uint(alignment)
|
||||
mode := packed_info.mode
|
||||
|
||||
size, alignment := uint(size), uint(1)<<packed_info.log2_alignment
|
||||
old_size := uint(old_size)
|
||||
|
||||
switch mode {
|
||||
|
||||
@@ -108,6 +108,7 @@ error_string :: proc(ferr: Error) -> string {
|
||||
case .Invalid_Pointer: return "invalid allocator pointer"
|
||||
case .Invalid_Argument: return "invalid allocator argument"
|
||||
case .Mode_Not_Implemented: return "allocator mode not implemented"
|
||||
case .Multiplication_Overflow_On_Requested_Size: return "multiplication overflow on requested allocation size"
|
||||
}
|
||||
case Platform_Error:
|
||||
return _error_string(i32(e))
|
||||
|
||||
@@ -15,8 +15,7 @@ heap_allocator :: proc() -> runtime.Allocator {
|
||||
|
||||
|
||||
@(require_results)
|
||||
heap_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, runtime.Allocator_Error) {
|
||||
return _heap_allocator_proc(allocator_data, mode, size, alignment, old_memory, old_size, loc)
|
||||
heap_allocator_proc :: proc(allocator_data: rawptr, packed_info: runtime.Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, runtime.Allocator_Error) {
|
||||
return _heap_allocator_proc(allocator_data, packed_info, size, old_memory, old_size, loc)
|
||||
}
|
||||
|
||||
@@ -26,9 +26,8 @@ heap_free :: proc(ptr: rawptr) {
|
||||
win32.HeapFree(win32.GetProcessHeap(), 0, ptr)
|
||||
}
|
||||
|
||||
_heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, mem.Allocator_Error) {
|
||||
_heap_allocator_proc :: proc(allocator_data: rawptr, packed_info: mem.Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, mem.Allocator_Error) {
|
||||
//
|
||||
// NOTE(tetra, 2020-01-14): The heap doesn't respect alignment.
|
||||
// Instead, we overallocate by `alignment + size_of(rawptr) - 1`, and insert
|
||||
@@ -75,6 +74,9 @@ _heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
return aligned_alloc(new_size, new_alignment, true, p)
|
||||
}
|
||||
|
||||
mode := packed_info.mode
|
||||
alignment := 1<<packed_info.log2_alignment
|
||||
|
||||
switch mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
return aligned_alloc(size, alignment, mode == .Alloc)
|
||||
|
||||
@@ -104,6 +104,7 @@ error_string :: proc "contextless" (ferr: Error) -> string {
|
||||
case .Invalid_Pointer: return "invalid allocator pointer"
|
||||
case .Invalid_Argument: return "invalid allocator argument"
|
||||
case .Mode_Not_Implemented: return "allocator mode not implemented"
|
||||
case .Multiplication_Overflow_On_Requested_Size: return "multiplication overflow on requested allocation size"
|
||||
}
|
||||
case Platform_Error:
|
||||
return _error_string(e)
|
||||
|
||||
10
vendor/commonmark/cmark.odin
vendored
10
vendor/commonmark/cmark.odin
vendored
@@ -493,12 +493,12 @@ free :: proc{free_rawptr, free_cstring}
|
||||
|
||||
// Wrap CMark allocator as Odin allocator
|
||||
@(private)
|
||||
cmark_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
cmark_allocator_proc :: proc(allocator_data: rawptr, packed_info: runtime.Allocator_Packed_Info,
|
||||
size: int,
|
||||
old_memory: rawptr, old_size: int, loc := #caller_location) -> (res: []byte, err: runtime.Allocator_Error) {
|
||||
|
||||
cmark_alloc := cast(^Allocator)allocator_data
|
||||
switch mode {
|
||||
switch packed_info.mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
ptr := cmark_alloc.calloc(1, c.size_t(size))
|
||||
res = ([^]byte)(ptr)[:size]
|
||||
@@ -515,8 +515,8 @@ cmark_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mod
|
||||
return nil, .Mode_Not_Implemented
|
||||
|
||||
case .Resize, .Resize_Non_Zeroed:
|
||||
new_ptr := cmark_alloc.realloc(old_memory, c.size_t(size))
|
||||
res = transmute([]byte)runtime.Raw_Slice{new_ptr, size}
|
||||
new_ptr := ([^]byte)(cmark_alloc.realloc(old_memory, c.size_t(size)))
|
||||
res = new_ptr[:size]
|
||||
if size > old_size {
|
||||
runtime.mem_zero(raw_data(res[old_size:]), size - old_size)
|
||||
}
|
||||
|
||||
7
vendor/raylib/raylib.odin
vendored
7
vendor/raylib/raylib.odin
vendored
@@ -1826,10 +1826,9 @@ MemAllocator :: proc "contextless" () -> mem.Allocator {
|
||||
return mem.Allocator{MemAllocatorProc, nil}
|
||||
}
|
||||
|
||||
MemAllocatorProc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, location := #caller_location) -> (data: []byte, err: mem.Allocator_Error) {
|
||||
switch mode {
|
||||
MemAllocatorProc :: proc(allocator_data: rawptr, packed_info: mem.Allocator_Packed_Info,
|
||||
size: int, old_memory: rawptr, old_size: int, location := #caller_location) -> (data: []byte, err: mem.Allocator_Error) {
|
||||
switch packed_info.mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
ptr := MemAlloc(c.uint(size))
|
||||
if ptr == nil {
|
||||
|
||||
Reference in New Issue
Block a user