Bläddra i källkod

Improve `resize` call

gingerBill 3 år sedan
förälder
incheckning
4aca9372a6

+ 9 - 54
core/mem/alloc.odin

@@ -67,7 +67,7 @@ alloc :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := contex
 	if allocator.procedure == nil {
 		return nil
 	}
-	data, err := allocator.procedure(allocator.data, Allocator_Mode.Alloc, size, alignment, nil, 0, loc)
+	data, err := allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc)
 	_ = err
 	return raw_data(data)
 }
@@ -79,7 +79,7 @@ alloc_bytes :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator :=
 	if allocator.procedure == nil {
 		return nil, nil
 	}
-	return allocator.procedure(allocator.data, Allocator_Mode.Alloc, size, alignment, nil, 0, loc)
+	return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc)
 }
 
 free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
@@ -89,7 +89,7 @@ free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_locatio
 	if allocator.procedure == nil {
 		return nil
 	}
-	_, err := allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, 0, loc)
+	_, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, loc)
 	return err
 }
 
@@ -100,75 +100,30 @@ free_bytes :: proc(bytes: []byte, allocator := context.allocator, loc := #caller
 	if allocator.procedure == nil {
 		return nil
 	}
-	_, err := allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, raw_data(bytes), len(bytes), loc)
+	_, err := allocator.procedure(allocator.data, .Free, 0, 0, raw_data(bytes), len(bytes), loc)
 	return err
 }
 
 free_all :: proc(allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
 	if allocator.procedure != nil {
-		_, err := allocator.procedure(allocator.data, Allocator_Mode.Free_All, 0, 0, nil, 0, loc)
+		_, err := allocator.procedure(allocator.data, .Free_All, 0, 0, nil, 0, loc)
 		return err
 	}
 	return nil
 }
 
 resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> rawptr {
-	if allocator.procedure == nil {
-		return nil
-	}
-	if new_size == 0 {
-		if ptr != nil {
-			allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc)
-		}
-		return nil
-	} else if ptr == nil {
-		_, err := allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc)
-		_ = err
-		return nil
-	}
-	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 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)
-	}
+	data, _ := runtime.mem_resize(ptr, old_size, new_size, alignment, allocator, loc)
 	return raw_data(data)
 }
 
 resize_bytes :: proc(old_data: []byte, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
-	if allocator.procedure == nil {
-		return nil, nil
-	}
-	ptr := raw_data(old_data)
-	old_size := len(old_data)
-	if new_size == 0 {
-		if ptr != nil {
-			_, err := allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc)
-			return nil, err
-		}
-		return nil, nil
-	} else if ptr == nil {
-		return allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, 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
+	return runtime.mem_resize(raw_data(old_data), len(old_data), new_size, alignment, allocator, loc)
 }
 
 query_features :: proc(allocator: Allocator, loc := #caller_location) -> (set: Allocator_Mode_Set) {
 	if allocator.procedure != nil {
-		allocator.procedure(allocator.data, Allocator_Mode.Query_Features, 0, 0, &set, 0, loc)
+		allocator.procedure(allocator.data, .Query_Features, 0, 0, &set, 0, loc)
 		return set
 	}
 	return nil
@@ -177,7 +132,7 @@ query_features :: proc(allocator: Allocator, loc := #caller_location) -> (set: A
 query_info :: proc(pointer: rawptr, allocator: Allocator, loc := #caller_location) -> (props: Allocator_Query_Info) {
 	props.pointer = pointer
 	if allocator.procedure != nil {
-		allocator.procedure(allocator.data, Allocator_Mode.Query_Info, 0, 0, &props, 0, loc)
+		allocator.procedure(allocator.data, .Query_Info, 0, 0, &props, 0, loc)
 	}
 	return
 }

+ 7 - 3
core/runtime/dynamic_array_internal.odin

@@ -29,11 +29,15 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap:
 	new_size  := cap * elem_size
 	allocator := array.allocator
 
-	new_data, err := allocator.procedure(allocator.data, .Resize, new_size, elem_align, array.data, old_size, loc)
+	new_data, err := mem_resize(array.data, old_size, new_size, elem_align, allocator, loc)
 	if err != nil {
 		return false
 	}
-	if new_data != nil || elem_size == 0 {
+	if elem_size == 0 {
+		array.data = raw_data(new_data)
+		array.cap = cap
+		return true
+	} else if new_data != nil {
 		array.data = raw_data(new_data)
 		array.cap = min(cap, len(new_data)/elem_size)
 		return true
@@ -59,7 +63,7 @@ __dynamic_array_shrink :: proc(array_: rawptr, elem_size, elem_align: int, new_c
 	new_size  := new_cap * elem_size
 	allocator := array.allocator
 
-	new_data, err := allocator.procedure(allocator.data, .Resize, new_size, elem_align, array.data, old_size, loc)
+	new_data, err := mem_resize(array.data, old_size, new_size, elem_align, allocator, loc)
 	if err != nil {
 		return
 	}

+ 8 - 5
core/runtime/dynamic_map_internal.odin

@@ -194,12 +194,15 @@ __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: Allocator, l
 	new_size := new_count*size_of(T)
 
 	new_data, err := mem_resize(array.data, old_size, new_size, align_of(T), allocator, loc)
-	if new_data == nil || err != nil {
+	if err != nil {
 		return false
 	}
-	array.data = new_data
-	array.len = new_count
-	return true
+	if new_data != nil || elem_size == 0 {
+		array.data = raw_data(new_data)
+		array.len = new_count
+		return true
+	}
+	return false
 }
 
 __dynamic_map_reset_entries :: proc(using header: Map_Header, loc := #caller_location) {
@@ -207,7 +210,7 @@ __dynamic_map_reset_entries :: proc(using header: Map_Header, loc := #caller_loc
 		m.hashes[i] = -1
 	}
 
-	for i in 0 ..< m.entries.len {
+	for i in 0..<m.entries.len {
 		entry_header := __dynamic_map_get_entry(header, i)
 		entry_hash := __get_map_hash_from_entry(header, entry_header)
 		entry_header.next = -1

+ 27 - 14
core/runtime/internal.odin

@@ -171,21 +171,34 @@ mem_free_all :: #force_inline proc(allocator := context.allocator, loc := #calle
 	return
 }
 
-mem_resize :: #force_inline proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (new_ptr: rawptr, err: Allocator_Error) {
-	new_data: []byte
-	switch {
-	case allocator.procedure == nil:
-		return
-	case new_size == 0:
-		new_data, err = allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, loc)
-	case ptr == nil:
-		new_data, err = allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc)
-	case:
-		new_data, err = allocator.procedure(allocator.data, .Resize, new_size, alignment, ptr, old_size, loc)
-	}
-	new_ptr = raw_data(new_data)
-	return
+mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
+	if allocator.procedure == nil {
+		return nil, nil
+	}
+	if new_size == 0 {
+		if ptr != nil {
+			_, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, old_size, loc)
+			return nil, err
+		}
+		return nil, nil
+	} else if ptr == nil {
+		return allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc)
+	} else if old_size == new_size && uintptr(ptr) % uintptr(alignment) == 0 {
+		return ([^]byte)(ptr)[:old_size], nil
+	}
+
+	data, err := allocator.procedure(allocator.data, .Resize, new_size, alignment, ptr, old_size, loc)
+	if err == .Mode_Not_Implemented {
+		data, err = allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc)
+		if err != nil {
+			return data, err
+		}
+		copy(data, ([^]byte)(ptr)[:old_size])
+		_, err = allocator.procedure(allocator.data, .Free, 0, 0, ptr, old_size, loc)
+	}
+	return data, err
 }
+
 memory_equal :: proc "contextless" (x, y: rawptr, n: int) -> bool {
 	switch {
 	case n == 0: return true