From 9d8b64dec5454a85b9818272f2102b08dcd898d7 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Mon, 2 Feb 2026 16:42:13 +0800 Subject: [PATCH] improvement --- lib/system/alloc.nim | 25 ++++++++++++++----------- tests/align/talign.nim | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index ee1b278698..66b63de4a2 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -134,7 +134,7 @@ type BigChunk = object of BaseChunk # not necessarily > PageSize! next, prev: PBigChunk # chunks of the same (or bigger) size - alignOffset: int16 # offset from data start to actual Cell (for aligned allocs) + alignOffset: uint16 # offset from data start to actual Cell (for aligned allocs) data {.align: MemAlign.}: UncheckedArray[byte] # start of usable memory HeapLinks = object @@ -846,6 +846,17 @@ when defined(heaptrack): proc heaptrack_malloc(a: pointer, size: int) {.cdecl, importc, dynlib: heaptrackLib.} proc heaptrack_free(a: pointer) {.cdecl, importc, dynlib: heaptrackLib.} +proc applyAlignment(basePtr: pointer, alignment: int, offset: int, c: PBigChunk): pointer {.inline.} = + # Apply alignment if needed: align (basePtr + offset) to alignment boundary + if alignment > MemAlign: + let base = basePtr +! offset + let alignOffset = alignment - (cast[int](base) and (alignment - 1)) + result = base +! alignOffset + c.alignOffset = cast[uint16](alignOffset + offset) + else: + c.alignOffset = 0 + result = basePtr + proc rawAlloc(a: var MemRegion, requestedSize: int, alignment: int = MemAlign, offset: int = 0): pointer = when defined(nimTypeNames): inc(a.allocCounter) @@ -963,16 +974,8 @@ proc rawAlloc(a: var MemRegion, requestedSize: int, alignment: int = MemAlign, o sysAssert c.prev == nil, "rawAlloc 10" sysAssert c.next == nil, "rawAlloc 11" result = addr(c.data) - # Apply alignment if needed: align (result + offset) to alignment boundary - if alignment > MemAlign: - let mask = alignment - 1 - let alignedUserData = (cast[int](result) + offset + mask) and not mask - let finalResult = cast[pointer](alignedUserData - offset) - c.alignOffset = cast[int16](cast[int](finalResult) - cast[int](result)) - result = finalResult - else: - c.alignOffset = 0 + result = applyAlignment(result, alignment, offset, c) sysAssert((cast[int](c) and (MemAlign-1)) == 0, "rawAlloc 13") sysAssert((cast[int](c) and PageMask) == 0, "rawAlloc: Not aligned on a page boundary") @@ -1085,7 +1088,7 @@ when not defined(gcDestructors): else: var c = cast[PBigChunk](c) # Use stored alignOffset to find the actual Cell location - let cellPtr = cast[pointer](cast[int](addr(c.data)) + c.alignOffset) + let cellPtr = cast[pointer](cast[int](addr(c.data)) + cast[int](c.alignOffset)) result = p == cellPtr and cast[ptr FreeCell](p).zeroField >% 1 proc prepareForInteriorPointerChecking(a: var MemRegion) {.inline.} = diff --git a/tests/align/talign.nim b/tests/align/talign.nim index 46b8f64a29..9ac7c8d544 100644 --- a/tests/align/talign.nim +++ b/tests/align/talign.nim @@ -1,6 +1,6 @@ discard """ ccodeCheck: "\\i @'NIM_ALIGN(128) NI mylocal1' .*" -matrix: "--mm:refc -d:useGcAssert; --mm:orc" +matrix: "--mm:refc -d:useGcAssert -d:useSysAssert; --mm:orc" targets: "c cpp" output: "align ok" """