4848 AlignType = BiggestFloat
4949 FreeCell {.final , pure .} = object
5050 next: ptr FreeCell # next free cell in chunk (overlaid with refcount)
51- zeroField: int # 0 means cell is not used (overlaid with typ field)
52- # 1 means cell is manually managed pointer
53- # otherwise a PNimType is stored in there
51+ when not defined (gcDestructors):
52+ zeroField: int # 0 means cell is not used (overlaid with typ field)
53+ # 1 means cell is manually managed pointer
54+ # otherwise a PNimType is stored in there
55+ else :
56+ alignment: int
5457
5558 PChunk = ptr BaseChunk
5659 PBigChunk = ptr BigChunk
@@ -396,8 +399,9 @@ iterator allObjects(m: var MemRegion): pointer {.inline.} =
396399proc iterToProc * (iter: typed , envType: typedesc ; procName: untyped ) {.
397400 magic : " Plugin" , compileTime .}
398401
399- proc isCell (p: pointer ): bool {.inline .} =
400- result = cast [ptr FreeCell ](p).zeroField > % 1
402+ when not defined (gcDestructors):
403+ proc isCell (p: pointer ): bool {.inline .} =
404+ result = cast [ptr FreeCell ](p).zeroField > % 1
401405
402406# ------------- chunk management ----------------------------------------------
403407proc pageIndex (c: PChunk ): int {.inline .} =
@@ -630,7 +634,8 @@ proc getSmallChunk(a: var MemRegion): PSmallChunk =
630634 result = cast [PSmallChunk ](res)
631635
632636# -----------------------------------------------------------------------------
633- proc isAllocatedPtr (a: MemRegion , p: pointer ): bool {.benign .}
637+ when not defined (gcDestructors):
638+ proc isAllocatedPtr (a: MemRegion , p: pointer ): bool {.benign .}
634639
635640when true :
636641 template allocInv (a: MemRegion ): bool = true
@@ -773,7 +778,8 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
773778 inc (c.acc, size)
774779 else :
775780 result = c.freeList
776- sysAssert (c.freeList.zeroField == 0 , " rawAlloc 8" )
781+ when not defined (gcDestructors):
782+ sysAssert (c.freeList.zeroField == 0 , " rawAlloc 8" )
777783 c.freeList = c.freeList.next
778784 dec (c.free, size)
779785 sysAssert ((cast [ByteAddress ](result ) and (MemAlign - 1 )) == 0 , " rawAlloc 9" )
@@ -826,9 +832,10 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
826832 sysAssert (((cast [ByteAddress ](p) and PageMask ) - smallChunkOverhead ()) %%
827833 s == 0 , " rawDealloc 3" )
828834 var f = cast [ptr FreeCell ](p)
829- # echo("setting to nil: ", $cast[ByteAddress](addr(f.zeroField)))
830- sysAssert (f.zeroField != 0 , " rawDealloc 1" )
831- f.zeroField = 0
835+ when not defined (gcDestructors):
836+ # echo("setting to nil: ", $cast[ByteAddress](addr(f.zeroField)))
837+ sysAssert (f.zeroField != 0 , " rawDealloc 1" )
838+ f.zeroField = 0
832839 f.next = c.freeList
833840 c.freeList = f
834841 when overwriteFree:
@@ -863,88 +870,102 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
863870 sysAssert (allocInv (a), " rawDealloc: end" )
864871 when logAlloc: cprintf (" dealloc(pointer_%p)\n " , p)
865872
866- proc isAllocatedPtr (a: MemRegion , p: pointer ): bool =
867- if isAccessible (a, p):
868- var c = pageAddr (p)
869- if not chunkUnused (c):
870- if isSmallChunk (c):
871- var c = cast [PSmallChunk ](c)
872- var offset = (cast [ByteAddress ](p) and (PageSize - 1 )) -%
873- smallChunkOverhead ()
874- result = (c.acc > % offset) and (offset %% c.size == 0 ) and
875- (cast [ptr FreeCell ](p).zeroField > % 1 )
876- else :
877- var c = cast [PBigChunk ](c)
878- result = p == addr (c.data) and cast [ptr FreeCell ](p).zeroField > % 1
873+ when not defined (gcDestructors):
874+ proc isAllocatedPtr (a: MemRegion , p: pointer ): bool =
875+ if isAccessible (a, p):
876+ var c = pageAddr (p)
877+ if not chunkUnused (c):
878+ if isSmallChunk (c):
879+ var c = cast [PSmallChunk ](c)
880+ var offset = (cast [ByteAddress ](p) and (PageSize - 1 )) -%
881+ smallChunkOverhead ()
882+ result = (c.acc > % offset) and (offset %% c.size == 0 ) and
883+ (cast [ptr FreeCell ](p).zeroField > % 1 )
884+ else :
885+ var c = cast [PBigChunk ](c)
886+ result = p == addr (c.data) and cast [ptr FreeCell ](p).zeroField > % 1
879887
880- proc prepareForInteriorPointerChecking (a: var MemRegion ) {.inline .} =
881- a.minLargeObj = lowGauge (a.root)
882- a.maxLargeObj = highGauge (a.root)
888+ proc prepareForInteriorPointerChecking (a: var MemRegion ) {.inline .} =
889+ a.minLargeObj = lowGauge (a.root)
890+ a.maxLargeObj = highGauge (a.root)
883891
884- proc interiorAllocatedPtr (a: MemRegion , p: pointer ): pointer =
885- if isAccessible (a, p):
886- var c = pageAddr (p)
887- if not chunkUnused (c):
888- if isSmallChunk (c):
889- var c = cast [PSmallChunk ](c)
890- var offset = (cast [ByteAddress ](p) and (PageSize - 1 )) -%
891- smallChunkOverhead ()
892- if c.acc > % offset:
893- sysAssert (cast [ByteAddress ](addr (c.data)) +% offset ==
894- cast [ByteAddress ](p), " offset is not what you think it is" )
895- var d = cast [ptr FreeCell ](cast [ByteAddress ](addr (c.data)) +%
896- offset -% (offset %% c.size))
897- if d.zeroField > % 1 :
892+ proc interiorAllocatedPtr (a: MemRegion , p: pointer ): pointer =
893+ if isAccessible (a, p):
894+ var c = pageAddr (p)
895+ if not chunkUnused (c):
896+ if isSmallChunk (c):
897+ var c = cast [PSmallChunk ](c)
898+ var offset = (cast [ByteAddress ](p) and (PageSize - 1 )) -%
899+ smallChunkOverhead ()
900+ if c.acc > % offset:
901+ sysAssert (cast [ByteAddress ](addr (c.data)) +% offset ==
902+ cast [ByteAddress ](p), " offset is not what you think it is" )
903+ var d = cast [ptr FreeCell ](cast [ByteAddress ](addr (c.data)) +%
904+ offset -% (offset %% c.size))
905+ if d.zeroField > % 1 :
906+ result = d
907+ sysAssert isAllocatedPtr (a, result ), " result wrong pointer!"
908+ else :
909+ var c = cast [PBigChunk ](c)
910+ var d = addr (c.data)
911+ if p >= d and cast [ptr FreeCell ](d).zeroField > % 1 :
898912 result = d
899913 sysAssert isAllocatedPtr (a, result ), " result wrong pointer!"
900- else :
901- var c = cast [PBigChunk ](c)
902- var d = addr (c.data)
903- if p >= d and cast [ptr FreeCell ](d).zeroField > % 1 :
904- result = d
905- sysAssert isAllocatedPtr (a, result ), " result wrong pointer!"
906- else :
907- var q = cast [int ](p)
908- if q >= % a.minLargeObj and q <= % a.maxLargeObj:
909- # this check is highly effective! Test fails for 99,96% of all checks on
910- # an x86-64.
911- var avlNode = inRange (a.root, q)
912- if avlNode != nil :
913- var k = cast [pointer ](avlNode.key)
914- var c = cast [PBigChunk ](pageAddr (k))
915- sysAssert (addr (c.data) == k, " k is not the same as addr(c.data)!" )
916- if cast [ptr FreeCell ](k).zeroField > % 1 :
917- result = k
918- sysAssert isAllocatedPtr (a, result ), " result wrong pointer!"
914+ else :
915+ var q = cast [int ](p)
916+ if q >= % a.minLargeObj and q <= % a.maxLargeObj:
917+ # this check is highly effective! Test fails for 99,96% of all checks on
918+ # an x86-64.
919+ var avlNode = inRange (a.root, q)
920+ if avlNode != nil :
921+ var k = cast [pointer ](avlNode.key)
922+ var c = cast [PBigChunk ](pageAddr (k))
923+ sysAssert (addr (c.data) == k, " k is not the same as addr(c.data)!" )
924+ if cast [ptr FreeCell ](k).zeroField > % 1 :
925+ result = k
926+ sysAssert isAllocatedPtr (a, result ), " result wrong pointer!"
919927
920928proc ptrSize (p: pointer ): int =
921- var x = cast [pointer ](cast [ByteAddress ](p) -% sizeof (FreeCell ))
922- var c = pageAddr (p)
923- sysAssert (not chunkUnused (c), " ptrSize" )
924- result = c.size -% sizeof (FreeCell )
925- if not isSmallChunk (c):
926- dec result , bigChunkOverhead ()
929+ when not defined (gcDestructors):
930+ var x = cast [pointer ](cast [ByteAddress ](p) -% sizeof (FreeCell ))
931+ var c = pageAddr (p)
932+ sysAssert (not chunkUnused (c), " ptrSize" )
933+ result = c.size -% sizeof (FreeCell )
934+ if not isSmallChunk (c):
935+ dec result , bigChunkOverhead ()
936+ else :
937+ var c = pageAddr (p)
938+ sysAssert (not chunkUnused (c), " ptrSize" )
939+ result = c.size
940+ if not isSmallChunk (c):
941+ dec result , bigChunkOverhead ()
927942
928943proc alloc (allocator: var MemRegion , size: Natural ): pointer {.gcsafe .} =
929- result = rawAlloc (allocator, size+ sizeof (FreeCell ))
930- cast [ptr FreeCell ](result ).zeroField = 1 # mark it as used
931- sysAssert (not isAllocatedPtr (allocator, result ), " alloc" )
932- result = cast [pointer ](cast [ByteAddress ](result ) +% sizeof (FreeCell ))
933- track (" alloc" , result , size)
944+ when not defined (gcDestructors):
945+ result = rawAlloc (allocator, size+ sizeof (FreeCell ))
946+ cast [ptr FreeCell ](result ).zeroField = 1 # mark it as used
947+ sysAssert (not isAllocatedPtr (allocator, result ), " alloc" )
948+ result = cast [pointer ](cast [ByteAddress ](result ) +% sizeof (FreeCell ))
949+ track (" alloc" , result , size)
950+ else :
951+ result = rawAlloc (allocator, size)
934952
935953proc alloc0 (allocator: var MemRegion , size: Natural ): pointer =
936954 result = alloc (allocator, size)
937955 zeroMem (result , size)
938956
939957proc dealloc (allocator: var MemRegion , p: pointer ) =
940- sysAssert (p != nil , " dealloc: p is nil" )
941- var x = cast [pointer ](cast [ByteAddress ](p) -% sizeof (FreeCell ))
942- sysAssert (x != nil , " dealloc: x is nil" )
943- sysAssert (isAccessible (allocator, x), " is not accessible" )
944- sysAssert (cast [ptr FreeCell ](x).zeroField == 1 , " dealloc: object header corrupted" )
945- rawDealloc (allocator, x)
946- sysAssert (not isAllocatedPtr (allocator, x), " dealloc: object still accessible" )
947- track (" dealloc" , p, 0 )
958+ when not defined (gcDestructors):
959+ sysAssert (p != nil , " dealloc: p is nil" )
960+ var x = cast [pointer ](cast [ByteAddress ](p) -% sizeof (FreeCell ))
961+ sysAssert (x != nil , " dealloc: x is nil" )
962+ sysAssert (isAccessible (allocator, x), " is not accessible" )
963+ sysAssert (cast [ptr FreeCell ](x).zeroField == 1 , " dealloc: object header corrupted" )
964+ rawDealloc (allocator, x)
965+ sysAssert (not isAllocatedPtr (allocator, x), " dealloc: object still accessible" )
966+ track (" dealloc" , p, 0 )
967+ else :
968+ rawDealloc (allocator, p)
948969
949970proc realloc (allocator: var MemRegion , p: pointer , newsize: Natural ): pointer =
950971 if newsize > 0 :
@@ -958,7 +979,7 @@ proc realloc(allocator: var MemRegion, p: pointer, newsize: Natural): pointer =
958979proc realloc0 (allocator: var MemRegion , p: pointer , oldsize, newsize: Natural ): pointer =
959980 result = realloc (allocator, p, newsize)
960981 if newsize > oldsize:
961- zeroMem (cast [pointer ](cast [int ](result ) + oldsize), newsize - oldsize)
982+ zeroMem (cast [pointer ](cast [uint ](result ) + uint ( oldsize) ), newsize - oldsize)
962983
963984proc deallocOsPages (a: var MemRegion ) =
964985 # we free every 'ordinarily' allocated page by iterating over the page bits:
0 commit comments