ortuman / nuke

⚡ A memory arena implementation for Go.
Apache License 2.0
500 stars 13 forks source link

Arena may produce misaligned values #16

Closed MortenLohne closed 8 months ago

MortenLohne commented 8 months ago

Mixing and matching multiple types in an arena may produce misaligned values, like an int at an odd byte:

func TestSlabArenaMultipleTypes(t *testing.T) {
    arena := NewSlabArena(8182, 1) // 8KB

    var b *byte = New[byte](arena)
    var p *int = New[int](arena)

    require.Equal(t, *b, byte(0))
    require.Equal(t, int(uintptr(unsafe.Pointer(p))%unsafe.Alignof(int(0))), 0)
}

The Go spec requires all values to be aligned correctly. For example, this test fails if run with go test -race:

func TestSlabArenaMultipleTypes(t *testing.T) {
    arena := NewSlabArena(8182, 1) // 8KB

    var b *byte = New[byte](arena)
    var p **int = New[*int](arena)

    require.Equal(t, *b, byte(0))
    require.True(t, *p == nil)
}

In theory, even a monotype arena can produce unaligned values, because the go spec does not guarantee that the underlying []byte is 8-byte aligned in the first place.

ortuman commented 8 months ago

Thank you for reporting the issue @MortenLohne.

I was aware that allocated pointers were not aligned, and I had planned to change this. However I simply assumed it could negatively affect performance, but it never occurred to me that with -race enabled this condition could cause a panic (TIL).

Anyway, I've already worked on a fix, and after merging #17 , this condition should not occur again.