fixes the recently discovered GC memory leaks

This revision is intended as comparison point between the old and the new GC
The used GC can be switched in mmdisp and various statistics will be gathered during
execution (these will be removed/disabled in later revisions)
This commit is contained in:
Zahary Karadjov 2012-12-05 20:42:19 +02:00
commit 083d4f4708
12 changed files with 1939 additions and 364 deletions

View file

@ -10,8 +10,10 @@
# Efficient set of pointers for the GC (and repr)
type
TRefCount = int
TCell {.pure.} = object
refcount: int # the refcount and some flags
refcount: TRefCount # the refcount and some flags
typ: PNimType
when trackAllocationSource:
filename: cstring

File diff suppressed because it is too large Load diff

View file

@ -13,11 +13,19 @@ when defined(NimString):
else:
{.pragma: codegenType.}
type # This should be he same as ast.TTypeKind
# many enum fields are not used at runtime
type
# This should be he same as ast.TTypeKind
# many enum fields are not used at runtime
TNimKind = enum
tyNone, tyBool, tyChar,
tyEmpty, tyArrayConstr, tyNil, tyExpr, tyStmt, tyTypeDesc,
tyNone,
tyBool,
tyChar,
tyEmpty,
tyArrayConstr,
tyNil,
tyExpr,
tyStmt,
tyTypeDesc,
tyGenericInvokation, # ``T[a, b]`` for types to invoke
tyGenericBody, # ``T[a, b, body]`` last parameter is the body
tyGenericInst, # ``T[a, b, realInstance]`` instantiated generic type
@ -30,15 +38,30 @@ type # This should be he same as ast.TTypeKind
tyTuple, # WARNING: The compiler uses tyTuple for pure objects!
tySet,
tyRange,
tyPtr, tyRef,
tyPtr,
tyRef,
tyVar,
tySequence,
tyProc,
tyPointer, tyOpenArray,
tyString, tyCString, tyForward,
tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
tyFloat, tyFloat32, tyFloat64, tyFloat128,
tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64,
tyPointer,
tyOpenArray,
tyString,
tyCString,
tyForward,
tyInt,
tyInt8,
tyInt16,
tyInt32,
tyInt64,
tyFloat,
tyFloat32,
tyFloat64,
tyFloat128,
tyUInt,
tyUInt8,
tyUInt16,
tyUInt32,
tyUInt64,
tyBigNum,
TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase

View file

@ -14,9 +14,9 @@
{.push checks:off.}
const
debugGC = false # we wish to debug the GC...
debugGC = true # we wish to debug the GC...
logGC = false
traceGC = false # extensive debugging
traceGC = true # extensive debugging
alwaysCycleGC = false
alwaysGC = false # collect after every memory allocation (for debugging)
leakDetector = false
@ -307,7 +307,10 @@ else:
include "system/cellsets"
when not leakDetector:
sysAssert(sizeof(TCell) == sizeof(TFreeCell), "sizeof TFreeCell")
include "system/gc"
when true:
include "system/gc"
else:
include "system/oldgc"
{.pop.}

1044
lib/system/oldgc.nim Normal file

File diff suppressed because it is too large Load diff

View file

@ -204,9 +204,16 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
# we need to decref here, otherwise the GC leaks!
when not defined(boehmGC) and not defined(nogc):
for i in newLen..result.len-1:
let len0 = gch.tempStack.len
forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
GenericSeqSize +% (i*%elemSize)),
extGetCellType(result).base, waZctDecRef)
extGetCellType(result).base, waPush)
let len1 = gch.tempStack.len
for i in len0 .. <len1:
doDecRef(gch.tempStack.d[i], LocalHeap, MaybeCyclic)
gch.tempStack.len = len0
# XXX add a proper addCycleRoot barrier here!
# and set the memory to nil:
zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +%
(newLen*%elemSize)), (result.len-%newLen) *% elemSize)

View file

@ -44,10 +44,11 @@ elif defined(macosx):
proc getTicks(): TTicks {.inline.} =
result = TTicks(mach_absolute_time())
var timeBaseInfo: TMachTimebaseInfoData
mach_timebase_info(timeBaseInfo)
proc `-`(a, b: TTicks): TNanos =
var timeBaseInfo: TMachTimebaseInfoData
mach_timebase_info(timeBaseInfo)
result = (a.int64 - b.int64) * timeBaseInfo.numer div timeBaseInfo.denom
elif defined(posixRealtime):