default GC can do a sort of heap dump via -d:nimTypeNames and dumpNumberOfInstances()
This commit is contained in:
parent
9753782f96
commit
823fbd4e40
3 changed files with 37 additions and 3 deletions
|
|
@ -880,10 +880,13 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: Rope) =
|
||||||
#else MessageOut("can contain a cycle: " & typeToString(typ))
|
#else MessageOut("can contain a cycle: " & typeToString(typ))
|
||||||
if flags != 0:
|
if flags != 0:
|
||||||
addf(m.s[cfsTypeInit3], "$1.flags = $2;$n", [name, rope(flags)])
|
addf(m.s[cfsTypeInit3], "$1.flags = $2;$n", [name, rope(flags)])
|
||||||
|
discard cgsym(m, "TNimType")
|
||||||
if isDefined("nimTypeNames"):
|
if isDefined("nimTypeNames"):
|
||||||
addf(m.s[cfsTypeInit3], "$1.name = $2;$n",
|
addf(m.s[cfsTypeInit3], "$1.name = $2;$n",
|
||||||
[name, makeCstring typeToString(origType, preferName)])
|
[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])
|
addf(m.s[cfsVars], "TNimType $1;$n", [name])
|
||||||
|
|
||||||
proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope) =
|
proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope) =
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,15 @@ proc writeCell(msg: cstring, c: PCell) =
|
||||||
c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld; color=%ld\n",
|
c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld; color=%ld\n",
|
||||||
msg, c, kind, typName, c.refcount shr rcShift, c.color)
|
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.} =
|
template gcTrace(cell, state: expr): stmt {.immediate.} =
|
||||||
when traceGC: traceCell(cell, state)
|
when traceGC: traceCell(cell, state)
|
||||||
|
|
||||||
|
|
@ -190,15 +199,25 @@ else:
|
||||||
proc prepareDealloc(cell: PCell) =
|
proc prepareDealloc(cell: PCell) =
|
||||||
when useMarkForDebug:
|
when useMarkForDebug:
|
||||||
gcAssert(cell notin gch.marked, "Cell still alive!")
|
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
|
# the finalizer could invoke something that
|
||||||
# allocates memory; this could trigger a garbage
|
# allocates memory; this could trigger a garbage
|
||||||
# collection. Since we are already collecting we
|
# collection. Since we are already collecting we
|
||||||
# prevend recursive entering here by a lock.
|
# prevend recursive entering here by a lock.
|
||||||
# XXX: we should set the cell's children to nil!
|
# XXX: we should set the cell's children to nil!
|
||||||
inc(gch.recGcLock)
|
inc(gch.recGcLock)
|
||||||
(cast[Finalizer](cell.typ.finalizer))(cellToUsr(cell))
|
(cast[Finalizer](t.finalizer))(cellToUsr(cell))
|
||||||
dec(gch.recGcLock)
|
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) =
|
template beforeDealloc(gch: var GcHeap; c: PCell; msg: typed) =
|
||||||
when false:
|
when false:
|
||||||
|
|
@ -462,6 +481,9 @@ template setFrameInfo(c: PCell) =
|
||||||
|
|
||||||
proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
||||||
# generates a new object and sets its reference counter to 0
|
# 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")
|
sysAssert(allocInv(gch.region), "rawNewObj begin")
|
||||||
acquire(gch)
|
acquire(gch)
|
||||||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
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.} =
|
proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
||||||
# generates a new object and sets its reference counter to 1
|
# 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")
|
sysAssert(allocInv(gch.region), "newObjRC1 begin")
|
||||||
acquire(gch)
|
acquire(gch)
|
||||||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,12 @@ type
|
||||||
deepcopy: proc (p: pointer): pointer {.nimcall, benign.}
|
deepcopy: proc (p: pointer): pointer {.nimcall, benign.}
|
||||||
when defined(nimTypeNames):
|
when defined(nimTypeNames):
|
||||||
name: cstring
|
name: cstring
|
||||||
|
nextType: ptr TNimType
|
||||||
|
instances: int # count the number of instances
|
||||||
|
sizes: int # sizes of all instances in bytes
|
||||||
PNimType = ptr TNimType
|
PNimType = ptr TNimType
|
||||||
|
|
||||||
|
when defined(nimTypeNames):
|
||||||
|
var nimTypeRoot {.codegenType.}: PNimType
|
||||||
|
|
||||||
# node.len may be the ``first`` element of a set
|
# node.len may be the ``first`` element of a set
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue