mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-06 06:38:20 +00:00
Merge pull request #6476 from MortimerSnerd/scratch_allocator_fix
Fix for corner case in the scratch allocator.
This commit is contained in:
@@ -536,15 +536,8 @@ scratch_alloc_bytes_non_zeroed :: proc(
|
||||
// we don't need to be so strict about every byte.
|
||||
aligned_size += alignment - 1
|
||||
}
|
||||
if aligned_size <= len(s.data) {
|
||||
offset := uintptr(0)
|
||||
if s.curr_offset+aligned_size <= len(s.data) {
|
||||
offset = uintptr(s.curr_offset)
|
||||
} else {
|
||||
// The allocation will cause an overflow past the boundary of the
|
||||
// space available, so reset to the starting offset.
|
||||
offset = 0
|
||||
}
|
||||
if s.curr_offset+aligned_size <= len(s.data) {
|
||||
offset := uintptr(s.curr_offset)
|
||||
start := uintptr(raw_data(s.data))
|
||||
ptr := rawptr(offset+start)
|
||||
// We keep track of the original base pointer without extra alignment
|
||||
|
||||
@@ -34,6 +34,7 @@ set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused
|
||||
..\..\..\odin build ..\test_issue_6401.odin %COMMON% 2>&1 | find /c "Error:" | findstr /x "3" || exit /b
|
||||
..\..\..\odin test ..\test_pr_6470.odin %COMMON% || exit /b
|
||||
..\..\..\odin test ..\test_pr_6470.odin -define:TEST_EXPECT_FAILURE=true %COMMON% 2>&1 | find /c "Error:" | findstr /x "1" || exit /b
|
||||
..\..\..\odin test ..\test_pr_6476.odin %COMMON% || exit /b
|
||||
|
||||
@echo off
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ $ODIN test ../test_issue_6068.odin $COMMON
|
||||
$ODIN test ../test_issue_6101.odin $COMMON
|
||||
$ODIN test ../test_issue_6165.odin $COMMON
|
||||
$ODIN test ../test_issue_6396.odin $COMMON
|
||||
$ODIN test ../test_pr_6476.odin $COMMON
|
||||
|
||||
if [[ $($ODIN build ../test_issue_6240.odin $COMMON 2>&1 >/dev/null | grep -c "Error:") -eq 3 ]] ; then
|
||||
echo "SUCCESSFUL 1/1"
|
||||
else
|
||||
|
||||
35
tests/issues/test_pr_6476.odin
Normal file
35
tests/issues/test_pr_6476.odin
Normal file
@@ -0,0 +1,35 @@
|
||||
package test_issues
|
||||
|
||||
import "core:testing"
|
||||
import "core:mem"
|
||||
|
||||
// Test for a problem encountered with the scratch allocator.
|
||||
// Say you have a scratch allocator with an arena size of N.
|
||||
// If you make an allocation whose size is <= N but greater than
|
||||
// the amount of free space left in the arena, the allocator
|
||||
// will return a slice of memory from the start of the arena,
|
||||
// overlapping previous allocations. (the expected
|
||||
// behavior is it satisfies the request with the backup allocator)
|
||||
|
||||
@test
|
||||
test_scratch_smash :: proc(t: ^testing.T) {
|
||||
// setup
|
||||
frAlloc: mem.Scratch
|
||||
err := mem.scratch_init(&frAlloc, 1 * mem.Kilobyte)
|
||||
testing.expect(t, err == nil)
|
||||
|
||||
talloc := mem.scratch_allocator(&frAlloc)
|
||||
defer mem.scratch_destroy(&frAlloc)
|
||||
|
||||
// First allocation fits in arena.
|
||||
a1 := make([]byte, 512, talloc)
|
||||
|
||||
// Second allocation does not fit in the free space, but is
|
||||
// <= the arena size.
|
||||
a2 := make([]byte, 1024, talloc)
|
||||
|
||||
// Should be true, but bug in scratch allocator returns space
|
||||
// overlapping a1 when allocating a2.
|
||||
testing.expect(t, &a1[0] != &a2[0])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user