diff options
-rw-r--r-- | compiler/ccgtypes.nim | 5 | ||||
-rw-r--r-- | lib/system/gc.nim | 29 | ||||
-rw-r--r-- | lib/system/hti.nim | 6 |
3 files changed, 37 insertions, 3 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 20e6342c3..8a11f954f 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -880,10 +880,13 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: Rope) = #else MessageOut("can contain a cycle: " & typeToString(typ)) if flags != 0: addf(m.s[cfsTypeInit3], "$1.flags = $2;$n", [name, rope(flags)]) + discard cgsym(m, "TNimType") if isDefined("nimTypeNames"): addf(m.s[cfsTypeInit3], "$1.name = $2;$n", [name, makeCstring typeToString(origType, preferName)]) - discard cgsym(m, "TNimType") + discard cgsym(m, "nimTypeRoot") + addf(m.s[cfsTypeInit3], "$1.nextType = nimTypeRoot; nimTypeRoot=&$1;$n", + [name]) addf(m.s[cfsVars], "TNimType $1;$n", [name]) proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope) = diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 8d9dc9025..2c971b35d 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -167,6 +167,15 @@ proc writeCell(msg: cstring, c: PCell) = c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld; color=%ld\n", msg, c, kind, typName, c.refcount shr rcShift, c.color) + +when defined(nimTypeNames): + proc dumpNumberOfInstances* = + var it = nimTypeRoot + while it != nil: + if it.instances > 0: + c_fprintf(stdout, "[Heap] %s: #%ld; bytes: %ld\n", it.name, it.instances, it.sizes) + it = it.nextType + template gcTrace(cell, state: expr): stmt {.immediate.} = when traceGC: traceCell(cell, state) @@ -190,15 +199,25 @@ else: proc prepareDealloc(cell: PCell) = when useMarkForDebug: gcAssert(cell notin gch.marked, "Cell still alive!") - if cell.typ.finalizer != nil: + let t = cell.typ + if t.finalizer != nil: # the finalizer could invoke something that # allocates memory; this could trigger a garbage # collection. Since we are already collecting we # prevend recursive entering here by a lock. # XXX: we should set the cell's children to nil! inc(gch.recGcLock) - (cast[Finalizer](cell.typ.finalizer))(cellToUsr(cell)) + (cast[Finalizer](t.finalizer))(cellToUsr(cell)) dec(gch.recGcLock) + when defined(nimTypeNames): + if t.kind in {tyString, tySequence}: + let len = cast[PGenericSeq](cellToUsr(cell)).len + let base = if t.kind == tyString: 1 else: t.base.size + let size = addInt(mulInt(len, base), GenericSeqSize) + dec t.sizes, size+sizeof(Cell) + else: + dec t.sizes, t.size+sizeof(Cell) + dec t.instances template beforeDealloc(gch: var GcHeap; c: PCell; msg: typed) = when false: @@ -462,6 +481,9 @@ template setFrameInfo(c: PCell) = proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer = # generates a new object and sets its reference counter to 0 + when defined(nimTypeNames): + inc typ.instances + inc typ.sizes, size+sizeof(Cell) sysAssert(allocInv(gch.region), "rawNewObj begin") acquire(gch) gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1") @@ -509,6 +531,9 @@ proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} = proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} = # generates a new object and sets its reference counter to 1 + when defined(nimTypeNames): + inc typ.instances + inc typ.sizes, size+sizeof(Cell) sysAssert(allocInv(gch.region), "newObjRC1 begin") acquire(gch) gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1") diff --git a/lib/system/hti.nim b/lib/system/hti.nim index d5cca7c1c..6ac976cb4 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -88,6 +88,12 @@ type deepcopy: proc (p: pointer): pointer {.nimcall, benign.} when defined(nimTypeNames): name: cstring + nextType: ptr TNimType + instances: int # count the number of instances + sizes: int # sizes of all instances in bytes PNimType = ptr TNimType +when defined(nimTypeNames): + var nimTypeRoot {.codegenType.}: PNimType + # node.len may be the ``first`` element of a set |