fixes #25566; {.align.} pragma where each 16-byte-aligned (#25570)

fixes #25566
This commit is contained in:
ringabout
2026-03-04 16:14:13 +08:00
committed by GitHub
parent 46cddbccd6
commit 8e2547a5e2
7 changed files with 32 additions and 20 deletions

View File

@@ -7906,7 +7906,7 @@ alignment requirement of the type are ignored.
main()
```
This pragma has no effect on the JS backend.
This pragma has no effect on the JavaScript backend and may significantly increase memory usage with the `--mm:refc` option.
Noalias pragma

View File

@@ -104,6 +104,8 @@ type
zeroField: int # 0 means cell is not used (overlaid with typ field)
# 1 means cell is manually managed pointer
# otherwise a PNimType is stored in there
when sizeof(int) == 4: # 32-bit only
headerAlignPad: array[8, byte] # so addr(data) ≡ 8 (mod 16)
else:
alignment: int
@@ -854,7 +856,7 @@ proc bigChunkAlignOffset(alignment: int): int {.inline.} =
if alignment == 0:
result = 0
else:
result = align(sizeof(BigChunk) + sizeof(Cell), alignment) - sizeof(BigChunk) - sizeof(Cell)
result = align(sizeof(BigChunk) + sizeof(FreeCell), alignment) - sizeof(BigChunk) - sizeof(FreeCell)
proc rawAlloc(a: var MemRegion, requestedSize: int, alignment: int = 0): pointer =
when defined(nimTypeNames):

View File

@@ -48,7 +48,23 @@ when defined(gcOrc) or defined(gcArc) or defined(gcAtomicArc) or defined(gcYrc):
when not declaredInScope(PageShift):
include bitmasks
else:
type
RefCount = int
Cell {.pure.} = object
refcount: RefCount # the refcount and some flags
typ: PNimType
when trackAllocationSource:
filename: cstring
line: int
when useCellIds:
id: int
when (not trackAllocationSource) and (not useCellIds) and sizeof(int) == 4: # 32-bit only
headerAlignPad: array[8, byte] # so addr(data) ≡ 8 (mod 16)
PCell = ptr Cell
type
PPageDesc = ptr PageDesc

View File

@@ -460,7 +460,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
collectCT(gch)
# Use alignment from typ.base if available, otherwise use MemAlign
let alignment = if typ.kind == tyRef and typ.base != nil and
typ.base.align >= MemAlign: typ.base.align else: 0
typ.base.align > 16: typ.base.align else: 0
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell), alignment))
#gcAssert typ.kind in {tyString, tySequence} or size >= typ.base.size, "size too small"
# Check that the user data (after the Cell header) is properly aligned
@@ -517,7 +517,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl, noinline, raise
# Use alignment from typ.base if available, otherwise use MemAlign
let alignment = if typ.kind == tyRef and typ.base != nil and
typ.base.align >= MemAlign: typ.base.align else: 0
typ.base.align > 16: typ.base.align else: 0
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell), alignment))
sysAssert(allocInv(gch.region), "newObjRC1 after rawAlloc")
# Check that the user data (after the Cell header) is properly aligned

View File

@@ -38,21 +38,6 @@ type
PByte = ptr ByteArray
PString = ptr string
when not defined(nimV2):
type
RefCount = int
Cell {.pure.} = object
refcount: RefCount # the refcount and some flags
typ: PNimType
when trackAllocationSource:
filename: cstring
line: int
when useCellIds:
id: int
PCell = ptr Cell
when declared(IntsPerTrunk):
discard
else:

View File

@@ -168,4 +168,3 @@ for q in 0..100:
new topArr[i]
topArr[i].m.di.b = q
doAssert(cast[uint](addr topArr[i].m.di) mod uint(alignof(DeepInner)) == 0)

10
tests/align/talign2.nim Normal file
View File

@@ -0,0 +1,10 @@
discard """
matrix: "--mm:refc -d:useGcAssert -d:useSysAssert; --mm:orc"
"""
block:
type U = object
d {.align: 16.}: int8
var e: seq[ref U]
for i in 0 ..< 10000: e.add(new U)
doAssert getTotalMem() <= 1052672 * 2