Procházet zdrojové kódy

Inline heap_allocator resize logic on *nix platforms

gingerBill před 4 roky
rodič
revize
16eeae36d7
4 změnil soubory, kde provedl 88 přidání a 61 odebrání
  1. 4 5
      src/array.cpp
  2. 42 40
      src/common.cpp
  3. 41 15
      src/gb/gb.h
  4. 1 1
      src/llvm_backend.cpp

+ 4 - 5
src/array.cpp

@@ -326,18 +326,17 @@ void array_set_capacity(Array<T> *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);
 	}

+ 42 - 40
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:

+ 41 - 15
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
 

+ 1 - 1
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