mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-06 07:38:24 +00:00
improve alignment for refc (#25525)
(cherry picked from commit 1e3caf457b)
This commit is contained in:
@@ -851,12 +851,12 @@ when defined(heaptrack):
|
||||
|
||||
proc bigChunkAlignOffset(alignment: int): int {.inline.} =
|
||||
## Compute the alignment offset for big chunk data.
|
||||
if alignment <= MemAlign:
|
||||
if alignment == 0:
|
||||
result = 0
|
||||
else:
|
||||
result = align(sizeof(BigChunk) + sizeof(Cell), alignment) - sizeof(BigChunk) - sizeof(Cell)
|
||||
|
||||
proc rawAlloc(a: var MemRegion, requestedSize: int, alignment: int = MemAlign): pointer =
|
||||
proc rawAlloc(a: var MemRegion, requestedSize: int, alignment: int = 0): pointer =
|
||||
when defined(nimTypeNames):
|
||||
inc(a.allocCounter)
|
||||
sysAssert(allocInv(a), "rawAlloc: begin")
|
||||
@@ -868,7 +868,7 @@ proc rawAlloc(a: var MemRegion, requestedSize: int, alignment: int = MemAlign):
|
||||
|
||||
# For custom alignments > MemAlign, force big chunk allocation
|
||||
# Small chunks cannot handle arbitrary alignments due to fixed cell boundaries
|
||||
if size <= SmallChunkSize-smallChunkOverhead() and alignment <= MemAlign:
|
||||
if size <= SmallChunkSize-smallChunkOverhead() and alignment == 0:
|
||||
template fetchSharedCells(tc: PSmallChunk) =
|
||||
# Consumes cells from (potentially) foreign threads from `a.sharedFreeLists[s]`
|
||||
when defined(gcDestructors):
|
||||
@@ -1364,4 +1364,4 @@ template instantiateForRegion(allocator: untyped) {.dirty.} =
|
||||
#sharedMemStatsShared(sharedHeap.currMem - sharedHeap.freeMem)
|
||||
{.pop.}
|
||||
|
||||
{.pop.}
|
||||
{.pop.}
|
||||
@@ -459,11 +459,15 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
||||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
||||
collectCT(gch)
|
||||
# Use alignment from typ.base if available, otherwise use MemAlign
|
||||
let alignment = if typ.kind == tyRef and typ.base != nil: max(typ.base.align, MemAlign) else: MemAlign
|
||||
let alignment = if typ.kind == tyRef and typ.base != nil and
|
||||
typ.base.align >= MemAlign: 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
|
||||
gcAssert((cast[int](cellToUsr(res)) and (alignment-1)) == 0, "newObj: 2")
|
||||
if alignment == 0:
|
||||
gcAssert((cast[int](res) and (MemAlign-1)) == 0, "newObj: 2.1")
|
||||
else:
|
||||
gcAssert((cast[int](cellToUsr(res)) and (alignment-1)) == 0, "newObj: 2.2")
|
||||
# now it is buffered in the ZCT
|
||||
res.typ = typ
|
||||
setFrameInfo(res)
|
||||
@@ -512,11 +516,15 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl, noinline, raise
|
||||
sysAssert(allocInv(gch.region), "newObjRC1 after collectCT")
|
||||
|
||||
# Use alignment from typ.base if available, otherwise use MemAlign
|
||||
let alignment = if typ.base != nil: max(typ.base.align, MemAlign) else: MemAlign
|
||||
let alignment = if typ.kind == tyRef and typ.base != nil and
|
||||
typ.base.align >= MemAlign: 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
|
||||
sysAssert((cast[int](cellToUsr(res)) and (alignment-1)) == 0, "newObj: 2")
|
||||
if alignment == 0:
|
||||
sysAssert((cast[int](res) and (MemAlign-1)) == 0, "newObj: 2.1")
|
||||
else:
|
||||
sysAssert((cast[int](cellToUsr(res)) and (alignment-1)) == 0, "newObj: 2.2")
|
||||
# now it is buffered in the ZCT
|
||||
res.typ = typ
|
||||
setFrameInfo(res)
|
||||
@@ -922,4 +930,4 @@ when not defined(useNimRtl):
|
||||
result.add "[GC] max stack size: " & $gch.stat.maxStackSize & "\n"
|
||||
|
||||
{.pop.} # raises: []
|
||||
{.pop.} # profiler: off, stackTrace: off
|
||||
{.pop.} # profiler: off, stackTrace: off
|
||||
Reference in New Issue
Block a user