From 18a2980d26602028977da151a0af1a43097b7830 Mon Sep 17 00:00:00 2001 From: Damian Tarnawski Date: Sat, 23 Aug 2025 14:28:25 +0200 Subject: [PATCH 1/2] Zero existing memory when using resize_soa (fixes #5614) --- base/runtime/core_builtin_soa.odin | 24 ++++++++++++++++ tests/core/runtime/test_core_runtime.odin | 34 +++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index ff27a4559..3cbf82bdc 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -178,9 +178,33 @@ resize_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int length: int, loc := #cal if array == nil { return nil } + reserve_soa(array, length, loc) or_return footer := raw_soa_footer(array) + old_len := footer.len footer.len = length + + if size_of(E) > 0 && length > old_len { + ti := type_info_of(typeid_of(T)) + ti = type_info_base(ti) + si := &ti.variant.(Type_Info_Struct) + + field_count := len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + + data := (^rawptr)(array)^ + + soa_offset := 0 + for i in 0.. Date: Tue, 26 Aug 2025 13:03:26 +0200 Subject: [PATCH 2/2] Add missing test attr and don't zero memory when reserve already did --- base/runtime/core_builtin_soa.odin | 15 +++++++-------- tests/core/runtime/test_core_runtime.odin | 1 + 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index a27381613..331254ac7 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -179,14 +179,12 @@ resize_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int length: int, loc := #cal return nil } - reserve_soa(array, length, loc) or_return footer := raw_soa_footer(array) - old_len := footer.len - footer.len = length - if size_of(E) > 0 && length > old_len { - ti := type_info_of(typeid_of(T)) - ti = type_info_base(ti) + if length > footer.cap { + reserve_soa(array, length, loc) or_return + } else if size_of(E) > 0 && length > footer.len { + ti := type_info_base(type_info_of(typeid_of(T))) si := &ti.variant.(Type_Info_Struct) field_count := len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) @@ -199,12 +197,13 @@ resize_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int length: int, loc := #cal soa_offset = align_forward_int(soa_offset, align_of(E)) - mem_zero(rawptr(uintptr(data) + uintptr(soa_offset) + uintptr(type.size * old_len)), type.size * (length - old_len)) + mem_zero(rawptr(uintptr(data) + uintptr(soa_offset) + uintptr(type.size * footer.len)), type.size * (length - footer.len)) - soa_offset += type.size * cap(array) + soa_offset += type.size * footer.cap } } + footer.len = length return nil } diff --git a/tests/core/runtime/test_core_runtime.odin b/tests/core/runtime/test_core_runtime.odin index 6c3b489d7..881b5f41a 100644 --- a/tests/core/runtime/test_core_runtime.odin +++ b/tests/core/runtime/test_core_runtime.odin @@ -213,6 +213,7 @@ test_soa_array_resize :: proc(t: ^testing.T) { testing.expect_value(t, array[2], V{0, 0}) } +@(test) test_soa_make_len :: proc(t: ^testing.T) { array, err := make(#soa[dynamic][2]int, 2)