Merge pull request #2181 from odin-lang/map-dev

New `map` internals
This commit is contained in:
gingerBill
2022-11-17 15:29:28 +00:00
committed by GitHub
35 changed files with 2147 additions and 896 deletions
+21 -17
View File
@@ -77,6 +77,14 @@ free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_locatio
return runtime.mem_free(ptr, allocator, loc)
}
free_with_size :: proc(ptr: rawptr, byte_count: int, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
if ptr == nil || allocator.procedure == nil {
return nil
}
_, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, byte_count, loc)
return err
}
free_bytes :: proc(bytes: []byte, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
return runtime.mem_free_bytes(bytes, allocator, loc)
}
@@ -112,22 +120,20 @@ query_info :: proc(pointer: rawptr, allocator: Allocator, loc := #caller_locatio
delete_string :: proc(str: string, allocator := context.allocator, loc := #caller_location) {
free(raw_data(str), allocator, loc)
delete_string :: proc(str: string, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
return free_with_size(raw_data(str), len(str), allocator, loc)
}
delete_cstring :: proc(str: cstring, allocator := context.allocator, loc := #caller_location) {
free((^byte)(str), allocator, loc)
delete_cstring :: proc(str: cstring, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
return free((^byte)(str), allocator, loc)
}
delete_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) {
free(raw_data(array), array.allocator, loc)
delete_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) -> Allocator_Error {
return free_with_size(raw_data(array), cap(array)*size_of(E), array.allocator, loc)
}
delete_slice :: proc(array: $T/[]$E, allocator := context.allocator, loc := #caller_location) {
free(raw_data(array), allocator, loc)
delete_slice :: proc(array: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
return free_with_size(raw_data(array), len(array)*size_of(E), allocator, loc)
}
delete_map :: proc(m: $T/map[$K]$V, loc := #caller_location) {
raw := transmute(Raw_Map)m
delete_slice(raw.hashes, raw.entries.allocator, loc)
free(raw.entries.data, raw.entries.allocator, loc)
delete_map :: proc(m: $T/map[$K]$V, loc := #caller_location) -> Allocator_Error {
return runtime.map_free_dynamic(transmute(Raw_Map)m, runtime.map_info(T), loc)
}
@@ -158,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
@@ -173,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)
@@ -188,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<<runtime.MAP_MIN_LOG2_CAPACITY, allocator := context.allocator, loc := #caller_location) -> 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) {
+15 -9
View File
@@ -867,6 +867,10 @@ tracking_allocator_init :: proc(t: ^Tracking_Allocator, backing_allocator: Alloc
t.backing = backing_allocator
t.allocation_map.allocator = internals_allocator
t.bad_free_array.allocator = internals_allocator
if .Free_All in query_features(t.backing) {
t.clear_on_free_all = true
}
}
tracking_allocator_destroy :: proc(t: ^Tracking_Allocator) {
@@ -874,6 +878,13 @@ tracking_allocator_destroy :: proc(t: ^Tracking_Allocator) {
delete(t.bad_free_array)
}
tracking_allocator_clear :: proc(t: ^Tracking_Allocator) {
clear(&t.allocation_map)
clear(&t.bad_free_array)
}
tracking_allocator :: proc(data: ^Tracking_Allocator) -> Allocator {
return Allocator{
data = data,
@@ -883,7 +894,7 @@ tracking_allocator :: proc(data: ^Tracking_Allocator) -> Allocator {
tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
size, alignment: int,
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
old_memory: rawptr, old_size: int, loc := #caller_location) -> (result: []byte, err: Allocator_Error) {
data := (^Tracking_Allocator)(allocator_data)
if mode == .Query_Info {
info := (^Allocator_Query_Info)(old_memory)
@@ -895,21 +906,16 @@ tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
info.pointer = nil
}
return nil, nil
return
}
result: []byte
err: Allocator_Error
if mode == .Free && old_memory != nil && old_memory not_in data.allocation_map {
append(&data.bad_free_array, Tracking_Allocator_Bad_Free_Entry{
memory = old_memory,
location = loc,
})
} else {
result, err = data.backing.procedure(data.backing.data, mode, size, alignment, old_memory, old_size, loc)
if err != nil {
return result, err
}
result = data.backing.procedure(data.backing.data, mode, size, alignment, old_memory, old_size, loc) or_return
}
result_ptr := raw_data(result)
@@ -957,6 +963,6 @@ tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
unreachable()
}
return result, err
return
}