diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-11-24 08:27:09 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-11-24 08:27:19 +0100 |
commit | 249fd5e56b60899b7ee2a7551f643307796247bc (patch) | |
tree | 36df2341786bd0a73afe2586fbac70432540d3f6 /lib/system | |
parent | 074f276c8a753bbb85788777b7c58a074f41329f (diff) | |
download | Nim-249fd5e56b60899b7ee2a7551f643307796247bc.tar.gz |
further memtracking improvements
Diffstat (limited to 'lib/system')
-rw-r--r-- | lib/system/alloc.nim | 6 | ||||
-rw-r--r-- | lib/system/gc.nim | 7 | ||||
-rw-r--r-- | lib/system/memtracker.nim | 20 |
3 files changed, 27 insertions, 6 deletions
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 745bbbf62..3a8e8a1b6 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -15,6 +15,10 @@ include osalloc +template track(op, address, size) = + when defined(memTracker): + memTrackerOp(op, address, size) + # We manage *chunks* of memory. Each chunk is a multiple of the page size. # Each chunk starts at an address that is divisible by the page size. Chunks # that are bigger than ``ChunkOsReturn`` are returned back to the operating @@ -645,6 +649,7 @@ proc alloc(allocator: var MemRegion, size: Natural): pointer = cast[ptr FreeCell](result).zeroField = 1 # mark it as used sysAssert(not isAllocatedPtr(allocator, result), "alloc") result = cast[pointer](cast[ByteAddress](result) +% sizeof(FreeCell)) + track("alloc", result, size) proc alloc0(allocator: var MemRegion, size: Natural): pointer = result = alloc(allocator, size) @@ -658,6 +663,7 @@ proc dealloc(allocator: var MemRegion, p: pointer) = sysAssert(cast[ptr FreeCell](x).zeroField == 1, "dealloc 2") rawDealloc(allocator, x) sysAssert(not isAllocatedPtr(allocator, x), "dealloc 3") + track("dealloc", p, 0) proc realloc(allocator: var MemRegion, p: pointer, newsize: Natural): pointer = if newsize > 0: diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 11897ce80..3bb0f62ff 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -468,6 +468,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer = # its refcount is zero, so add it to the ZCT: addNewObjToZCT(res, gch) when logGC: writeCell("new cell", res) + track("rawNewObj", res, size) gcTrace(res, csAllocated) release(gch) when useCellIds: @@ -519,6 +520,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} = res.refcount = rcIncrement # refcount is 1 sysAssert(isAllocatedPtr(gch.region, res), "newObj: 3") when logGC: writeCell("new cell", res) + track("newObjRC1", res, size) gcTrace(res, csAllocated) release(gch) when useCellIds: @@ -561,6 +563,8 @@ proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer = writeCell("growObj new cell", res) gcTrace(ol, csZctFreed) gcTrace(res, csAllocated) + track("growObj old", ol, 0) + track("growObj new", res, newsize) when reallyDealloc: sysAssert(allocInv(gch.region), "growObj before dealloc") if ol.refcount shr rcShift <=% 1: @@ -604,6 +608,7 @@ proc growObj(old: pointer, newsize: int): pointer {.rtl.} = proc freeCyclicCell(gch: var GcHeap, c: PCell) = prepareDealloc(c) gcTrace(c, csCycFreed) + track("cycle collector dealloc cell", c, 0) when logGC: writeCell("cycle collector dealloc cell", c) when reallyDealloc: sysAssert(allocInv(gch.region), "free cyclic cell") @@ -673,6 +678,7 @@ proc doOperation(p: pointer, op: WalkOp) = gcAssert(c.refcount >=% rcIncrement, "doOperation 2") #c.refcount = c.refcount -% rcIncrement when logGC: writeCell("decref (from doOperation)", c) + track("waZctDecref", p, 0) decRef(c) #if c.refcount <% rcIncrement: addZCT(gch.zct, c) of waPush: @@ -765,6 +771,7 @@ proc collectZCT(gch: var GcHeap): bool = # In any case, it should be removed from the ZCT. But not # freed. **KEEP THIS IN MIND WHEN MAKING THIS INCREMENTAL!** when logGC: writeCell("zct dealloc cell", c) + track("zct dealloc cell", c, 0) gcTrace(c, csZctFreed) # We are about to free the object, call the finalizer BEFORE its # children are deleted as well, because otherwise the finalizer may diff --git a/lib/system/memtracker.nim b/lib/system/memtracker.nim index b4a5460fa..a9767bbca 100644 --- a/lib/system/memtracker.nim +++ b/lib/system/memtracker.nim @@ -27,8 +27,9 @@ type line*: int TrackLog* = object count*: int + disabled: bool data*: array[4000, LogEntry] - TrackLogger* = proc (log: TrackLog) {.nimcall.} + TrackLogger* = proc (log: TrackLog) {.nimcall, tags: [], locks: 0.} var gLog*: TrackLog @@ -38,11 +39,12 @@ proc setTrackLogger*(logger: TrackLogger) = gLogger = logger proc addEntry(entry: LogEntry) = - if gLog.count > high(gLog.data): - gLogger(gLog) - gLog.count = 0 - gLog.data[gLog.count] = entry - inc gLog.count + if not gLog.disabled: + if gLog.count > high(gLog.data): + gLogger(gLog) + gLog.count = 0 + gLog.data[gLog.count] = entry + inc gLog.count proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.compilerProc.} = addEntry LogEntry(op: "write", address: address, @@ -52,6 +54,12 @@ proc memTrackerOp*(op: cstring; address: pointer; size: int) = addEntry LogEntry(op: op, address: address, size: size, file: "", line: 0) +proc memTrackerDisable*() = + gLog.disabled = true + +proc memTrackerEnable*() = + gLog.disabled = false + proc logPendingOps() {.noconv.} = # forward declared and called from Nim's signal handler. gLogger(gLog) |