Răsfoiți Sursa

`Allocator_Error.Mode_Not_Implemented`; Minor improvement to `map` runtime procedures

gingerBill 4 ani în urmă
părinte
comite
4d00c2b800

+ 24 - 6
core/mem/alloc.odin

@@ -31,10 +31,11 @@ Allocator_Query_Info :: struct {
 Allocator_Error :: runtime.Allocator_Error;
 Allocator_Error :: runtime.Allocator_Error;
 /*
 /*
 Allocator_Error :: enum byte {
 Allocator_Error :: enum byte {
-	None             = 0,
-	Out_Of_Memory    = 1,
-	Invalid_Pointer  = 2,
-	Invalid_Argument = 3,
+	None                 = 0,
+	Out_Of_Memory        = 1,
+	Invalid_Pointer      = 2,
+	Invalid_Argument     = 3,
+	Mode_Not_Implemented = 4,
 }
 }
 */
 */
 Allocator_Proc :: runtime.Allocator_Proc;
 Allocator_Proc :: runtime.Allocator_Proc;
@@ -121,7 +122,15 @@ resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_AL
 		return nil;
 		return nil;
 	}
 	}
 	data, err := allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc);
 	data, err := allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc);
-	_ = err;
+	if err == .Mode_Not_Implemented {
+		data, err = allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc);
+		if err != nil {
+			return nil;
+		}
+		runtime.copy(data, byte_slice(ptr, old_size));
+		_, err = allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc);
+		return raw_data(data);
+	}
 	return raw_data(data);
 	return raw_data(data);
 }
 }
 
 
@@ -140,7 +149,16 @@ resize_bytes :: proc(old_data: []byte, new_size: int, alignment: int = DEFAULT_A
 	} else if ptr == nil {
 	} else if ptr == nil {
 		return allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc);
 		return allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc);
 	}
 	}
-	return allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc);
+	data, err := allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc);
+	if err == .Mode_Not_Implemented {
+		data, err = allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc);
+		if err != nil {
+			return data, err;
+		}
+		runtime.copy(data, old_data);
+		_, err = allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc);
+	}
+	return data, err;
 }
 }
 
 
 query_features :: proc(allocator: Allocator, loc := #caller_location) -> (set: Allocator_Mode_Set) {
 query_features :: proc(allocator: Allocator, loc := #caller_location) -> (set: Allocator_Mode_Set) {

+ 8 - 106
core/mem/allocators.odin

@@ -67,8 +67,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		return byte_slice(ptr, size), nil;
 		return byte_slice(ptr, size), nil;
 
 
 	case .Free:
 	case .Free:
-		// NOTE(bill): Free all at once
-		// Use Arena_Temp_Memory if you want to free a block
+		return nil, .Mode_Not_Implemented;
 
 
 	case .Free_All:
 	case .Free_All:
 		arena.offset = 0;
 		arena.offset = 0;
@@ -84,7 +83,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		return nil, nil;
 		return nil, nil;
 
 
 	case .Query_Info:
 	case .Query_Info:
-		return nil, nil;
+		return nil, .Mode_Not_Implemented;
 	}
 	}
 
 
 	return nil, nil;
 	return nil, nil;
@@ -262,7 +261,7 @@ scratch_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		return nil, nil;
 		return nil, nil;
 
 
 	case .Query_Info:
 	case .Query_Info:
-		return nil, nil;
+		return nil, .Mode_Not_Implemented;
 	}
 	}
 
 
 	return nil, nil;
 	return nil, nil;
@@ -426,7 +425,7 @@ stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		}
 		}
 		return nil, nil;
 		return nil, nil;
 	case .Query_Info:
 	case .Query_Info:
-		return nil, nil;
+		return nil, .Mode_Not_Implemented;
 	}
 	}
 
 
 	return nil, nil;
 	return nil, nil;
@@ -561,7 +560,7 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		return nil, nil;
 		return nil, nil;
 
 
 	case .Query_Info:
 	case .Query_Info:
-		return nil, nil;
+		return nil, .Mode_Not_Implemented;
 	}
 	}
 
 
 	return nil, nil;
 	return nil, nil;
@@ -602,7 +601,7 @@ dynamic_pool_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode
 	case .Alloc:
 	case .Alloc:
 		return dynamic_pool_alloc_bytes(pool, size);
 		return dynamic_pool_alloc_bytes(pool, size);
 	case .Free:
 	case .Free:
-		return nil, nil;
+		return nil, .Mode_Not_Implemented;
 	case .Free_All:
 	case .Free_All:
 		dynamic_pool_free_all(pool);
 		dynamic_pool_free_all(pool);
 		return nil, nil;
 		return nil, nil;
@@ -786,7 +785,7 @@ panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		return nil, nil;
 		return nil, nil;
 
 
 	case .Query_Info:
 	case .Query_Info:
-		return nil, nil;
+		panic("mem: panic allocator, .Query_Info called");
 	}
 	}
 
 
 	return nil, nil;
 	return nil, nil;
@@ -908,106 +907,9 @@ tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		return nil, nil;
 		return nil, nil;
 
 
 	case .Query_Info:
 	case .Query_Info:
-		return nil, nil;
+		unreachable();
 	}
 	}
 
 
 	return result, err;
 	return result, err;
 }
 }
 
 
-
-
-// Small_Allocator primary allocates memory from its local buffer of size BUFFER_SIZE
-// If that buffer's memory is exhausted, it will use the backing allocator (a scratch allocator is recommended)
-// Memory allocated with Small_Allocator cannot be freed individually using 'free' and must be freed using 'free_all'
-Small_Allocator :: struct($BUFFER_SIZE: int)
-	where
-		BUFFER_SIZE >= 2*size_of(uintptr),
-		BUFFER_SIZE & (BUFFER_SIZE-1) == 0 {
-
-	buffer:     [BUFFER_SIZE]byte,
-	backing:    Allocator,
-	start:      uintptr,
-	curr:       uintptr,
-	end:        uintptr,
-	chunk_size: int,
-}
-
-small_allocator :: proc(s: ^$S/Small_Allocator, backing := context.allocator) -> (a: Allocator) {
-	if s.backing.procedure == nil {
-		s.backing = backing;
-	}
-	a.data = s;
-	a.procedure = proc(allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, flags: u64 = 0, loc := #caller_location) -> rawptr {
-		s := (^S)(allocator_data);
-		if s.chunk_size <= 0 {
-			s.chunk_size = 4*1024;
-		}
-		if s.start == 0 {
-			s.start = uintptr(&s.buffer[0]);
-			s.curr = s.start;
-			s.end = s.start + uintptr(S.BUFFER_SIZE);
-			(^rawptr)(s.start)^ = nil;
-			s.curr += size_of(rawptr);
-		}
-
-
-		switch mode {
-		case .Alloc:
-			s.curr = align_forward_uintptr(s.curr, uintptr(alignment));
-			if size > int(s.end - s.curr) {
-				to_allocate := size_of(rawptr) + size + alignment;
-				if to_allocate < s.chunk_size {
-					to_allocate = s.chunk_size;
-				}
-				s.chunk_size *= 2;
-
-				p := alloc(to_allocate, 16, s.backing, loc);
-				(^rawptr)(s.start)^ = p;
-				s.start = uintptr(p);
-				s.curr = s.start;
-				s.end = s.start + uintptr(to_allocate);
-
-				(^rawptr)(s.start)^ = nil;
-				s.curr += size_of(rawptr);
-				s.curr = align_forward_uintptr(s.curr, uintptr(alignment));
-			}
-
-			p := rawptr(s.curr);
-			s.curr += uintptr(size);
-			return mem_zero(p, size);
-
-		case .Free:
-			// NOP
-			return nil;
-
-		case .Resize:
-			// No need copying the code
-			return default_resize_align(old_memory, old_size, size, alignment, small_allocator(s, s.backing), loc);
-
-		case .Free_All:
-			p := (^rawptr)(&s.buffer[0])^;
-			for p != nil {
-				next := (^rawptr)(p)^;
-				free(next, s.backing, loc);
-				p = next;
-			}
-			// Reset to default
-			s.start = uintptr(&s.buffer[0]);
-			s.curr = s.start;
-			s.end = s.start + uintptr(S.BUFFER_SIZE);
-
-			(^rawptr)(s.start)^ = nil;
-			s.curr += size_of(rawptr);
-
-
-		case .Query_Features:
-			return nil, nil;
-
-		case .Query_Info:
-			return nil, nil;
-		}
-
-		return nil, nil;
-	};
-	return a;
-}

+ 2 - 2
core/os/os.odin

@@ -188,7 +188,7 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
 		aligned_free(old_memory);
 		aligned_free(old_memory);
 
 
 	case .Free_All:
 	case .Free_All:
-		// NOTE(tetra): Do nothing.
+		return nil, .Mode_Not_Implemented;
 
 
 	case .Resize:
 	case .Resize:
 		if old_memory == nil {
 		if old_memory == nil {
@@ -204,7 +204,7 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
 		return nil, nil;
 		return nil, nil;
 
 
 	case .Query_Info:
 	case .Query_Info:
-		return nil, nil;
+		return nil, .Mode_Not_Implemented;
 	}
 	}
 
 
 	return nil, nil;
 	return nil, nil;

+ 1 - 1
core/os/os2/heap_windows.odin

@@ -84,7 +84,7 @@ _heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
 		aligned_free(old_memory);
 		aligned_free(old_memory);
 
 
 	case .Free_All:
 	case .Free_All:
-		// NOTE(tetra): Do nothing.
+		return nil, .Mode_Not_Implemented;
 
 
 	case .Resize:
 	case .Resize:
 		if old_memory == nil {
 		if old_memory == nil {

+ 5 - 4
core/runtime/core.odin

@@ -276,10 +276,11 @@ Allocator_Query_Info :: struct {
 }
 }
 
 
 Allocator_Error :: enum byte {
 Allocator_Error :: enum byte {
-	None             = 0,
-	Out_Of_Memory    = 1,
-	Invalid_Pointer  = 2,
-	Invalid_Argument = 3,
+	None                 = 0,
+	Out_Of_Memory        = 1,
+	Invalid_Pointer      = 2,
+	Invalid_Argument     = 3,
+	Mode_Not_Implemented = 4,
 }
 }
 
 
 Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode,
 Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode,

+ 1 - 1
core/runtime/dynamic_map_internal.odin

@@ -196,6 +196,7 @@ __dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #c
 	new_header: Map_Header = header;
 	new_header: Map_Header = header;
 	nm := Raw_Map{};
 	nm := Raw_Map{};
 	nm.entries.allocator = m.entries.allocator;
 	nm.entries.allocator = m.entries.allocator;
+	nm.hashes = m.hashes;
 	new_header.m = &nm;
 	new_header.m = &nm;
 
 
 	c := context;
 	c := context;
@@ -239,7 +240,6 @@ __dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #c
 		}
 		}
 	}
 	}
 
 
-	delete(m.hashes, m.entries.allocator, loc);
 	free(m.entries.data, m.entries.allocator, loc);
 	free(m.entries.data, m.entries.allocator, loc);
 	header.m^ = nm;
 	header.m^ = nm;
 }
 }