From 2c364980afff8d78afd38415432647c7cd9e471a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 8 Jul 2026 12:47:50 +0100 Subject: [PATCH] Breaking Change: `Allocator_Packed_Info` as part of the `Allocator_Proc` interface to minimize register use with calls --- base/runtime/core.odin | 14 ++- base/runtime/core_builtin.odin | 3 +- base/runtime/default_allocators_nil.odin | 14 ++- .../runtime/default_temp_allocator_arena.odin | 9 +- base/runtime/default_temporary_allocator.odin | 7 +- base/runtime/heap_allocator.odin | 7 +- base/runtime/internal.odin | 48 +++++----- core/log/log_allocator.odin | 13 +-- core/math/big/common.odin | 2 + core/mem/alloc.odin | 7 +- core/mem/allocators.odin | 88 ++++++++++--------- core/mem/mutex_allocator.odin | 5 +- core/mem/rollback_stack_allocator.odin | 7 +- core/mem/tlsf/tlsf.odin | 16 ++-- core/mem/tracking_allocator.odin | 8 +- core/mem/virtual/arena.odin | 8 +- core/os/errors.odin | 1 + core/os/heap.odin | 7 +- core/os/heap_windows.odin | 8 +- core/os/old/errors.odin | 1 + vendor/commonmark/cmark.odin | 10 +-- vendor/raylib/raylib.odin | 7 +- 22 files changed, 165 insertions(+), 125 deletions(-) diff --git a/base/runtime/core.odin b/base/runtime/core.odin index b1c20e70d..f385d6650 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -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, diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index 16b8d70a3..856da06a9 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -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 diff --git a/base/runtime/default_allocators_nil.odin b/base/runtime/default_allocators_nil.odin index 2f2edb40a..5d077304e 100644 --- a/base/runtime/default_allocators_nil.odin +++ b/base/runtime/default_allocators_nil.odin @@ -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) diff --git a/base/runtime/default_temp_allocator_arena.odin b/base/runtime/default_temp_allocator_arena.odin index f1d09792a..196ba3489 100644 --- a/base/runtime/default_temp_allocator_arena.odin +++ b/base/runtime/default_temp_allocator_arena.odin @@ -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)< (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) diff --git a/base/runtime/heap_allocator.odin b/base/runtime/heap_allocator.odin index e2667a78c..0df16199e 100644 --- a/base/runtime/heap_allocator.odin +++ b/base/runtime/heap_allocator.odin @@ -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)< ([]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 diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index e08d0e01d..e6fbae0cb 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -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)< (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 { diff --git a/core/log/log_allocator.odin b/core/log/log_allocator.odin index a6784133b..e86f48a73 100644 --- a/core/log/log_allocator.odin +++ b/core/log/log_allocator.odin @@ -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, mode: runtime.Allocator_Mode, - size, alignment: int, - old_memory: rawptr, old_size: int, location := #caller_location) -> ([]byte, runtime.Allocator_Error) { +log_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) { la := (^Log_Allocator)(allocator_data) if context.logger.procedure == nil || la.level < context.logger.lowest_level { - return la.allocator.procedure(la.allocator.data, mode, size, alignment, old_memory, old_size, location) + 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< (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 } diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index dcd126230..7d3717b37 100644 --- a/core/mem/allocators.odin +++ b/core/mem/allocators.odin @@ -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< ([]byte, Allocator_Error) { s := (^Scratch)(allocator_data) + mode := packed_info.mode + alignment := 1< ([]byte, Allocator_Error) { s := cast(^Small_Stack)allocator_data if s.data == nil { return nil, .Invalid_Argument } - switch mode { + alignment := 1< 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< ([]byte, Allocator_Error) { b := (^Buddy_Allocator)(allocator_data) - switch mode { + alignment := 1< 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<= 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} diff --git a/core/mem/mutex_allocator.odin b/core/mem/mutex_allocator.odin index 7361016c3..2755c4ab0 100644 --- a/core/mem/mutex_allocator.odin +++ b/core/mem/mutex_allocator.odin @@ -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) } diff --git a/core/mem/rollback_stack_allocator.odin b/core/mem/rollback_stack_allocator.odin index 3c98135de..5ae39b17a 100644 --- a/core/mem/rollback_stack_allocator.odin +++ b/core/mem/rollback_stack_allocator.odin @@ -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< ([]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)< 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< 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)< 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)) diff --git a/core/os/heap.odin b/core/os/heap.odin index 356e60b4d..178a07747 100644 --- a/core/os/heap.odin +++ b/core/os/heap.odin @@ -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) } diff --git a/core/os/heap_windows.odin b/core/os/heap_windows.odin index e0e62a91f..05365e243 100644 --- a/core/os/heap_windows.odin +++ b/core/os/heap_windows.odin @@ -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< 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) diff --git a/vendor/commonmark/cmark.odin b/vendor/commonmark/cmark.odin index 574b977e0..aa7dc59c7 100644 --- a/vendor/commonmark/cmark.odin +++ b/vendor/commonmark/cmark.odin @@ -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) } diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin index b2e25755e..f1871cac2 100644 --- a/vendor/raylib/raylib.odin +++ b/vendor/raylib/raylib.odin @@ -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 {