diff --git a/core/mem/alloc.odin b/core/mem/alloc.odin index 818a21026..54004d333 100644 --- a/core/mem/alloc.odin +++ b/core/mem/alloc.odin @@ -61,55 +61,24 @@ DEFAULT_PAGE_SIZE :: 4 * 1024 alloc :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> rawptr { - if size == 0 { - return nil - } - if allocator.procedure == nil { - return nil - } - data, err := allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc) - _ = err + data, _ := runtime.mem_alloc(size, alignment, allocator, loc) return raw_data(data) } alloc_bytes :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) { - if size == 0 { - return nil, nil - } - if allocator.procedure == nil { - return nil, nil - } - return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc) + return runtime.mem_alloc(size, alignment, allocator, loc) } free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) -> Allocator_Error { - if ptr == nil { - return nil - } - if allocator.procedure == nil { - return nil - } - _, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, loc) - return err + return runtime.mem_free(ptr, allocator, loc) } free_bytes :: proc(bytes: []byte, allocator := context.allocator, loc := #caller_location) -> Allocator_Error { - if bytes == nil { - return nil - } - if allocator.procedure == nil { - return nil - } - _, err := allocator.procedure(allocator.data, .Free, 0, 0, raw_data(bytes), len(bytes), loc) - return err + return runtime.mem_free_bytes(bytes, allocator, loc) } free_all :: proc(allocator := context.allocator, loc := #caller_location) -> Allocator_Error { - if allocator.procedure != nil { - _, err := allocator.procedure(allocator.data, .Free_All, 0, 0, nil, 0, loc) - return err - } - return nil + return runtime.mem_free_all(allocator, loc) } resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> rawptr { diff --git a/core/runtime/dynamic_map_internal.odin b/core/runtime/dynamic_map_internal.odin index 02ecf9354..35b42d488 100644 --- a/core/runtime/dynamic_map_internal.odin +++ b/core/runtime/dynamic_map_internal.odin @@ -197,7 +197,7 @@ __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: Allocator, l if err != nil { return false } - if new_data != nil || elem_size == 0 { + if new_data != nil || size_of(E) == 0 { array.data = raw_data(new_data) array.len = new_count return true diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index c82d7b2cc..55f600d68 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -103,7 +103,7 @@ mem_zero :: proc "contextless" (data: rawptr, len: int) -> rawptr { if data == nil { return nil } - if len < 0 { + if len <= 0 { return data } intrinsics.mem_zero(data, len) @@ -111,22 +111,18 @@ mem_zero :: proc "contextless" (data: rawptr, len: int) -> rawptr { } mem_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { - if src == nil { - return dst + if src != nil && dst != src && len > 0 { + // NOTE(bill): This _must_ be implemented like C's memmove + intrinsics.mem_copy(dst, src, len) } - - // NOTE(bill): This _must_ be implemented like C's memmove - intrinsics.mem_copy(dst, src, len) return dst } mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { - if src == nil { - return dst + if src != nil && dst != src && len > 0 { + // NOTE(bill): This _must_ be implemented like C's memcpy + intrinsics.mem_copy_non_overlapping(dst, src, len) } - - // NOTE(bill): This _must_ be implemented like C's memcpy - intrinsics.mem_copy_non_overlapping(dst, src, len) return dst } @@ -142,28 +138,30 @@ mem_alloc_bytes :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNM return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc) } -mem_alloc :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (rawptr, Allocator_Error) { - if size == 0 { +mem_alloc :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) { + if size == 0 || allocator.procedure == nil { return nil, nil } - if allocator.procedure == nil { - return nil, nil - } - data, err := allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc) - return raw_data(data), err + return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc) } mem_free :: #force_inline proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) -> Allocator_Error { - if ptr == nil { - return .None - } - if allocator.procedure == nil { - return .None + if ptr == nil || allocator.procedure == nil { + return nil } _, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, loc) return err } +mem_free_bytes :: #force_inline proc(bytes: []byte, allocator := context.allocator, loc := #caller_location) -> Allocator_Error { + if bytes == nil || allocator.procedure == nil { + return nil + } + _, err := allocator.procedure(allocator.data, .Free, 0, 0, raw_data(bytes), len(bytes), loc) + return err +} + + mem_free_all :: #force_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) diff --git a/core/strings/intern.odin b/core/strings/intern.odin index 1e9577e61..5e9193a0d 100644 --- a/core/strings/intern.odin +++ b/core/strings/intern.odin @@ -31,31 +31,31 @@ intern_destroy :: proc(m: ^Intern) { // returns the `text` string from the intern map - gets set if it didnt exist yet // the returned string lives as long as the map entry lives -intern_get :: proc(m: ^Intern, text: string) -> string { - entry := _intern_get_entry(m, text) - #no_bounds_check return string(entry.str[:entry.len]) +intern_get :: proc(m: ^Intern, text: string) -> (str: string, err: runtime.Allocator_Error) { + entry := _intern_get_entry(m, text) or_return + #no_bounds_check return string(entry.str[:entry.len]), nil } // returns the `text` cstring from the intern map - gets set if it didnt exist yet // the returned cstring lives as long as the map entry lives -intern_get_cstring :: proc(m: ^Intern, text: string) -> cstring { - entry := _intern_get_entry(m, text) - return cstring(&entry.str[0]) +intern_get_cstring :: proc(m: ^Intern, text: string) -> (str: cstring, err: runtime.Allocator_Error) { + entry := _intern_get_entry(m, text) or_return + return cstring(&entry.str[0]), nil } // looks up wether the `text` string exists in the map, returns the entry // sets & allocates the entry if it wasnt set yet -_intern_get_entry :: proc(m: ^Intern, text: string) -> ^Intern_Entry #no_bounds_check { +_intern_get_entry :: proc(m: ^Intern, text: string) -> (new_entry: ^Intern_Entry, err: runtime.Allocator_Error) #no_bounds_check { if prev, ok := m.entries[text]; ok { - return prev + return prev, nil } if m.allocator.procedure == nil { m.allocator = context.allocator } entry_size := int(offset_of(Intern_Entry, str)) + len(text) + 1 - ptr, _ := runtime.mem_alloc(entry_size, align_of(Intern_Entry), m.allocator) - new_entry := (^Intern_Entry)(ptr) + bytes := runtime.mem_alloc(entry_size, align_of(Intern_Entry), m.allocator) or_return + new_entry = (^Intern_Entry)(raw_data(bytes)) new_entry.len = len(text) copy(new_entry.str[:new_entry.len], text) @@ -63,5 +63,5 @@ _intern_get_entry :: proc(m: ^Intern, text: string) -> ^Intern_Entry #no_bounds_ key := string(new_entry.str[:new_entry.len]) m.entries[key] = new_entry - return new_entry + return new_entry, nil }