From 16eeae36d719a8499107924c2e24b3c84feee579 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 7 Aug 2021 15:05:46 +0100 Subject: [PATCH] Inline heap_allocator resize logic on *nix platforms --- src/array.cpp | 9 +++-- src/common.cpp | 82 +++++++++++++++++++++++--------------------- src/gb/gb.h | 56 ++++++++++++++++++++++-------- src/llvm_backend.cpp | 2 +- 4 files changed, 88 insertions(+), 61 deletions(-) diff --git a/src/array.cpp b/src/array.cpp index 3e37aa7af..ad0efcd74 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -326,18 +326,17 @@ void array_set_capacity(Array *array, isize capacity) { array_resize(array, capacity); } - T *new_data = nullptr; -#if 0 - // NOTE(bill): try gb_resize_align first, and then fallback to alloc+memmove+free isize old_size = array->capacity * gb_size_of(T); isize new_size = capacity * gb_size_of(T); + T *new_data = nullptr; + + // NOTE(bill): try gb_resize_align first, and then fallback to alloc+memmove+free new_data = cast(T *)gb_resize_align(array->allocator, array->data, old_size, new_size, gb_align_of(T)); -#endif if (new_data == nullptr) { if (capacity > 0) { new_data = gb_alloc_array(array->allocator, T, capacity); GB_ASSERT(new_data != nullptr); - gb_memmove(new_data, array->data, gb_size_of(T) * array->capacity); + gb_memmove(new_data, array->data, old_size); } gb_free(array->allocator, array->data); } diff --git a/src/common.cpp b/src/common.cpp index 5e5ec3490..c9d88d55b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -149,20 +149,6 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) { // TODO(bill): Throughly test! switch (type) { #if defined(GB_COMPILER_MSVC) - #if 0 - case gbAllocation_Alloc: - ptr = _aligned_malloc(size, alignment); - if (flags & gbAllocatorFlag_ClearToZero) { - zero_size(ptr, size); - } - break; - case gbAllocation_Free: - _aligned_free(old_memory); - break; - case gbAllocation_Resize: - ptr = _aligned_realloc(old_memory, size, alignment); - break; - #else case gbAllocation_Alloc: { isize aligned_size = align_formula_isize(size, alignment); // TODO(bill): Make sure this is aligned correctly @@ -175,50 +161,66 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) { isize aligned_size = align_formula_isize(size, alignment); ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size); } break; - #endif - #elif defined(GB_SYSTEM_LINUX) // TODO(bill): *nix version that's decent case gbAllocation_Alloc: { ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1)); - // ptr = malloc(size+alignment); - - if (flags & gbAllocatorFlag_ClearToZero) { - zero_size(ptr, size); - } - break; - } + gb_zero_size(ptr, size); + } break; case gbAllocation_Free: { free(old_memory); - break; - } + } break; - case gbAllocation_Resize: { - // ptr = realloc(old_memory, size); - ptr = gb_default_resize_align(heap_allocator(), old_memory, old_size, size, alignment); + case gbAllocation_Resize: + if (new_size == 0) { + free(old_memory); + break; + } + if (!old_memory) { + ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1)); + gb_zero_size(ptr, size); + break; + } + if (new_size <= old_size) { + ptr = old_memory; + break; + } + + ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1)); + gb_memmove(ptr, old_memory, old_size); + gb_zero_size(cast(u8 *)ptr + old_size, gb_max(new_size-old_size, 0)); break; - } #else // TODO(bill): *nix version that's decent - case gbAllocation_Alloc: { + case gbAllocation_Alloc: posix_memalign(&ptr, alignment, size); - - if (flags & gbAllocatorFlag_ClearToZero) { - zero_size(ptr, size); - } + gb_zero_size(ptr, size); break; - } - case gbAllocation_Free: { + case gbAllocation_Free: free(old_memory); break; - } - case gbAllocation_Resize: { - ptr = gb_default_resize_align(heap_allocator(), old_memory, old_size, size, alignment); + case gbAllocation_Resize: + if (new_size == 0) { + free(old_memory); + break; + } + if (!old_memory) { + posix_memalign(&ptr, alignment, size); + gb_zero_size(ptr, size); + break; + } + if (new_size <= old_size) { + ptr = old_memory; + break; + } + + posix_memalign(&ptr, alignment, size); + gb_memmove(ptr, old_memory, old_size); + gb_zero_size(cast(u8 *)ptr + old_size, gb_max(new_size-old_size, 0)); break; - } #endif case gbAllocation_FreeAll: diff --git a/src/gb/gb.h b/src/gb/gb.h index d93f4217e..ce8546a79 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -5014,8 +5014,9 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) { #if defined(GB_COMPILER_MSVC) case gbAllocation_Alloc: ptr = _aligned_malloc(size, alignment); - if (flags & gbAllocatorFlag_ClearToZero) + if (flags & gbAllocatorFlag_ClearToZero) { gb_zero_size(ptr, size); + } break; case gbAllocation_Free: _aligned_free(old_memory); @@ -5028,29 +5029,37 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) { // TODO(bill): *nix version that's decent case gbAllocation_Alloc: { ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1)); - // ptr = malloc(size+alignment); - - if (flags & gbAllocatorFlag_ClearToZero) { - gb_zero_size(ptr, size); - } + gb_zero_size(ptr, size); } break; case gbAllocation_Free: { free(old_memory); } break; - case gbAllocation_Resize: { - // ptr = realloc(old_memory, size); - ptr = gb_default_resize_align(gb_heap_allocator(), old_memory, old_size, size, alignment); - } break; + case gbAllocation_Resize: + if (new_size == 0) { + free(old_memory); + break; + } + if (!old_memory) { + ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1)); + gb_zero_size(ptr, size); + break; + } + if (new_size <= old_size) { + ptr = old_memory; + break; + } + + ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1)); + gb_memmove(ptr, old_memory, old_size); + gb_zero_size(cast(u8 *)ptr + old_size, gb_max(new_size-old_size, 0)); + break; #else // TODO(bill): *nix version that's decent case gbAllocation_Alloc: { posix_memalign(&ptr, alignment, size); - - if (flags & gbAllocatorFlag_ClearToZero) { - gb_zero_size(ptr, size); - } + gb_zero_size(ptr, size); } break; case gbAllocation_Free: { @@ -5058,7 +5067,24 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) { } break; case gbAllocation_Resize: { - ptr = gb_default_resize_align(gb_heap_allocator(), old_memory, old_size, size, alignment); + if (new_size == 0) { + free(old_memory); + break; + } + if (!old_memory) { + posix_memalign(&ptr, alignment, size); + gb_zero_size(ptr, size); + break; + } + if (new_size <= old_size) { + ptr = old_memory; + break; + } + + posix_memalign(&ptr, alignment, size); + gb_memmove(ptr, old_memory, old_size); + gb_zero_size(cast(u8 *)ptr + old_size, gb_max(new_size-old_size, 0)); + } break; #endif diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 2267907a1..9f79c5908 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -538,7 +538,7 @@ lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) { i64 length = LLVMConstIntGetSExtValue(len); char const *text = nullptr; if (false && length != 0) { - if (LLVMGetConstOpcode(data) != LLVMGetElementPtr) { + if (LLVMGetConstOpcode(data) != LLVMGetElementPtr) { return {}; } // TODO(bill): THIS IS BROKEN! THIS NEEDS FIXING :P