diff --git a/core/mem/alloc.odin b/core/mem/alloc.odin index 7416ebdb7..818a21026 100644 --- a/core/mem/alloc.odin +++ b/core/mem/alloc.odin @@ -67,7 +67,7 @@ alloc :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := contex if allocator.procedure == nil { return nil } - data, err := allocator.procedure(allocator.data, Allocator_Mode.Alloc, size, alignment, nil, 0, loc) + data, err := allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc) _ = err return raw_data(data) } @@ -79,7 +79,7 @@ alloc_bytes :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := if allocator.procedure == nil { return nil, nil } - return allocator.procedure(allocator.data, Allocator_Mode.Alloc, size, alignment, nil, 0, loc) + return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc) } free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) -> Allocator_Error { @@ -89,7 +89,7 @@ free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_locatio if allocator.procedure == nil { return nil } - _, err := allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, 0, loc) + _, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, loc) return err } @@ -100,75 +100,30 @@ free_bytes :: proc(bytes: []byte, allocator := context.allocator, loc := #caller if allocator.procedure == nil { return nil } - _, err := allocator.procedure(allocator.data, Allocator_Mode.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 } free_all :: proc(allocator := context.allocator, loc := #caller_location) -> Allocator_Error { if allocator.procedure != nil { - _, err := allocator.procedure(allocator.data, Allocator_Mode.Free_All, 0, 0, nil, 0, loc) + _, err := allocator.procedure(allocator.data, .Free_All, 0, 0, nil, 0, loc) return err } return nil } resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> rawptr { - if allocator.procedure == nil { - return nil - } - if new_size == 0 { - if ptr != nil { - allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc) - } - return nil - } else if ptr == nil { - _, err := allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc) - _ = err - return nil - } - data, err := allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc) - if err == .Mode_Not_Implemented { - data, err = allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc) - if err != nil { - return nil - } - runtime.copy(data, byte_slice(ptr, old_size)) - _, err = allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc) - return raw_data(data) - } + data, _ := runtime.mem_resize(ptr, old_size, new_size, alignment, allocator, loc) return raw_data(data) } resize_bytes :: proc(old_data: []byte, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) { - if allocator.procedure == nil { - return nil, nil - } - ptr := raw_data(old_data) - old_size := len(old_data) - if new_size == 0 { - if ptr != nil { - _, err := allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc) - return nil, err - } - return nil, nil - } else if ptr == nil { - return allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc) - } - data, err := allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc) - if err == .Mode_Not_Implemented { - data, err = allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc) - if err != nil { - return data, err - } - runtime.copy(data, old_data) - _, err = allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc) - } - return data, err + return runtime.mem_resize(raw_data(old_data), len(old_data), new_size, alignment, allocator, loc) } query_features :: proc(allocator: Allocator, loc := #caller_location) -> (set: Allocator_Mode_Set) { if allocator.procedure != nil { - allocator.procedure(allocator.data, Allocator_Mode.Query_Features, 0, 0, &set, 0, loc) + allocator.procedure(allocator.data, .Query_Features, 0, 0, &set, 0, loc) return set } return nil @@ -177,7 +132,7 @@ query_features :: proc(allocator: Allocator, loc := #caller_location) -> (set: A query_info :: proc(pointer: rawptr, allocator: Allocator, loc := #caller_location) -> (props: Allocator_Query_Info) { props.pointer = pointer if allocator.procedure != nil { - allocator.procedure(allocator.data, Allocator_Mode.Query_Info, 0, 0, &props, 0, loc) + allocator.procedure(allocator.data, .Query_Info, 0, 0, &props, 0, loc) } return } diff --git a/core/runtime/dynamic_array_internal.odin b/core/runtime/dynamic_array_internal.odin index d39c2dd0b..b6a685fcf 100644 --- a/core/runtime/dynamic_array_internal.odin +++ b/core/runtime/dynamic_array_internal.odin @@ -29,11 +29,15 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: new_size := cap * elem_size allocator := array.allocator - new_data, err := allocator.procedure(allocator.data, .Resize, new_size, elem_align, array.data, old_size, loc) + new_data, err := mem_resize(array.data, old_size, new_size, elem_align, allocator, loc) if err != nil { return false } - if new_data != nil || elem_size == 0 { + if elem_size == 0 { + array.data = raw_data(new_data) + array.cap = cap + return true + } else if new_data != nil { array.data = raw_data(new_data) array.cap = min(cap, len(new_data)/elem_size) return true @@ -59,7 +63,7 @@ __dynamic_array_shrink :: proc(array_: rawptr, elem_size, elem_align: int, new_c new_size := new_cap * elem_size allocator := array.allocator - new_data, err := allocator.procedure(allocator.data, .Resize, new_size, elem_align, array.data, old_size, loc) + new_data, err := mem_resize(array.data, old_size, new_size, elem_align, allocator, loc) if err != nil { return } diff --git a/core/runtime/dynamic_map_internal.odin b/core/runtime/dynamic_map_internal.odin index fee0f570f..02ecf9354 100644 --- a/core/runtime/dynamic_map_internal.odin +++ b/core/runtime/dynamic_map_internal.odin @@ -194,12 +194,15 @@ __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: Allocator, l new_size := new_count*size_of(T) new_data, err := mem_resize(array.data, old_size, new_size, align_of(T), allocator, loc) - if new_data == nil || err != nil { + if err != nil { return false } - array.data = new_data - array.len = new_count - return true + if new_data != nil || elem_size == 0 { + array.data = raw_data(new_data) + array.len = new_count + return true + } + return false } __dynamic_map_reset_entries :: proc(using header: Map_Header, loc := #caller_location) { @@ -207,7 +210,7 @@ __dynamic_map_reset_entries :: proc(using header: Map_Header, loc := #caller_loc m.hashes[i] = -1 } - for i in 0 ..< m.entries.len { + for i in 0.. (new_ptr: rawptr, err: Allocator_Error) { - new_data: []byte - switch { - case allocator.procedure == nil: - return - case new_size == 0: - new_data, err = allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, loc) - case ptr == nil: - new_data, err = allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc) - case: - new_data, err = allocator.procedure(allocator.data, .Resize, new_size, alignment, ptr, old_size, loc) +mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) { + if allocator.procedure == nil { + return nil, nil } - new_ptr = raw_data(new_data) - return + if new_size == 0 { + if ptr != nil { + _, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, old_size, loc) + return nil, err + } + return nil, nil + } else if ptr == nil { + return allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc) + } else if old_size == new_size && uintptr(ptr) % uintptr(alignment) == 0 { + return ([^]byte)(ptr)[:old_size], nil + } + + data, err := allocator.procedure(allocator.data, .Resize, new_size, alignment, ptr, old_size, loc) + if err == .Mode_Not_Implemented { + data, err = allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc) + if err != nil { + return data, err + } + copy(data, ([^]byte)(ptr)[:old_size]) + _, err = allocator.procedure(allocator.data, .Free, 0, 0, ptr, old_size, loc) + } + return data, err } + memory_equal :: proc "contextless" (x, y: rawptr, n: int) -> bool { switch { case n == 0: return true