diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index e6c015dbee..a23702dc1f 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -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.} \ No newline at end of file diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 4b02b2f257..bc199b8351 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -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 \ No newline at end of file