diff --git a/core/mem/alloc.odin b/core/mem/alloc.odin index 4f449bd37..c7a21dcd4 100644 --- a/core/mem/alloc.odin +++ b/core/mem/alloc.odin @@ -164,8 +164,6 @@ new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_locat return nil, .Out_Of_Memory } -DEFAULT_RESERVE_CAPACITY :: 16 - make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (slice: T, err: Allocator_Error) { runtime.make_slice_error_loc(loc, len) data := alloc_bytes(size_of(E)*len, alignment, allocator, loc) or_return @@ -179,7 +177,7 @@ make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allo return make_aligned(T, len, align_of(E), allocator, loc) } make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) { - return make_dynamic_array_len_cap(T, 0, DEFAULT_RESERVE_CAPACITY, allocator, loc) + return make_dynamic_array_len_cap(T, 0, 16, allocator, loc) } make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) { return make_dynamic_array_len_cap(T, len, len, allocator, loc) @@ -194,12 +192,12 @@ make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #a array = transmute(T)s return } -make_map :: proc($T: typeid/map[$K]$E, #any_int cap: int = DEFAULT_RESERVE_CAPACITY, allocator := context.allocator, loc := #caller_location) -> T { +make_map :: proc($T: typeid/map[$K]$E, #any_int cap: int = 1< T { runtime.make_map_expr_error_loc(loc, cap) context.allocator = allocator m: T - reserve_map(&m, cap) + reserve_map(&m, cap, loc) return m } make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: T, err: Allocator_Error) { diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index dab177f46..24a53dfbd 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -231,12 +231,12 @@ make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #a return } @(builtin) -make_map :: proc($T: typeid/map[$K]$E, #any_int cap: int = 1< T { - make_map_expr_error_loc(loc, cap) +make_map :: proc($T: typeid/map[$K]$E, #any_int capacity: int = 1< T { + make_map_expr_error_loc(loc, capacity) context.allocator = allocator m: T - reserve_map(&m, cap) + reserve_map(&m, capacity, loc) return m } @(builtin) diff --git a/core/runtime/dynamic_map_internal.odin b/core/runtime/dynamic_map_internal.odin index 5543a62dc..e943a3e24 100644 --- a/core/runtime/dynamic_map_internal.odin +++ b/core/runtime/dynamic_map_internal.odin @@ -437,36 +437,42 @@ map_grow_dynamic :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Inf map_reserve_dynamic :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, new_capacity: uintptr, loc := #caller_location) -> Allocator_Error { + ceil_log2 :: #force_inline proc "contextless" (x: uintptr) -> uintptr { + z := intrinsics.count_leading_zeros(x) + if z > 0 && x & (x-1) != 0 { + z -= 1 + } + return size_of(uintptr)*8 - 1 - z + } + if m.allocator.procedure == nil { m.allocator = context.allocator } new_capacity := new_capacity + old_capacity := uintptr(map_cap(m^)) - log2_capacity := map_log2_cap(m^) - capacity := uintptr(1) << log2_capacity - - if capacity >= new_capacity { + if old_capacity >= new_capacity { return nil } - new_capacity = max(new_capacity, uintptr(1)< Allocator_Error { - if m.len + 1 >= map_resize_threshold(m^) { + if m.len >= map_resize_threshold(m^) { return map_grow_dynamic(m, info, loc) } return nil