further memtracking improvements
This commit is contained in:
parent
074f276c8a
commit
249fd5e56b
5 changed files with 29 additions and 8 deletions
|
|
@ -32,7 +32,7 @@ template sbind(x: int; value) =
|
||||||
quit "could not bind value"
|
quit "could not bind value"
|
||||||
|
|
||||||
when defined(memTracker):
|
when defined(memTracker):
|
||||||
proc logEntries(log: TrackLog) {.nimcall.} =
|
proc logEntries(log: TrackLog) {.nimcall, locks: 0, tags: [].} =
|
||||||
for i in 0..log.count-1:
|
for i in 0..log.count-1:
|
||||||
var success = false
|
var success = false
|
||||||
let e = log.data[i]
|
let e = log.data[i]
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@
|
||||||
|
|
||||||
include osalloc
|
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.
|
# 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
|
# 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
|
# 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
|
cast[ptr FreeCell](result).zeroField = 1 # mark it as used
|
||||||
sysAssert(not isAllocatedPtr(allocator, result), "alloc")
|
sysAssert(not isAllocatedPtr(allocator, result), "alloc")
|
||||||
result = cast[pointer](cast[ByteAddress](result) +% sizeof(FreeCell))
|
result = cast[pointer](cast[ByteAddress](result) +% sizeof(FreeCell))
|
||||||
|
track("alloc", result, size)
|
||||||
|
|
||||||
proc alloc0(allocator: var MemRegion, size: Natural): pointer =
|
proc alloc0(allocator: var MemRegion, size: Natural): pointer =
|
||||||
result = alloc(allocator, size)
|
result = alloc(allocator, size)
|
||||||
|
|
@ -658,6 +663,7 @@ proc dealloc(allocator: var MemRegion, p: pointer) =
|
||||||
sysAssert(cast[ptr FreeCell](x).zeroField == 1, "dealloc 2")
|
sysAssert(cast[ptr FreeCell](x).zeroField == 1, "dealloc 2")
|
||||||
rawDealloc(allocator, x)
|
rawDealloc(allocator, x)
|
||||||
sysAssert(not isAllocatedPtr(allocator, x), "dealloc 3")
|
sysAssert(not isAllocatedPtr(allocator, x), "dealloc 3")
|
||||||
|
track("dealloc", p, 0)
|
||||||
|
|
||||||
proc realloc(allocator: var MemRegion, p: pointer, newsize: Natural): pointer =
|
proc realloc(allocator: var MemRegion, p: pointer, newsize: Natural): pointer =
|
||||||
if newsize > 0:
|
if newsize > 0:
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
||||||
# its refcount is zero, so add it to the ZCT:
|
# its refcount is zero, so add it to the ZCT:
|
||||||
addNewObjToZCT(res, gch)
|
addNewObjToZCT(res, gch)
|
||||||
when logGC: writeCell("new cell", res)
|
when logGC: writeCell("new cell", res)
|
||||||
|
track("rawNewObj", res, size)
|
||||||
gcTrace(res, csAllocated)
|
gcTrace(res, csAllocated)
|
||||||
release(gch)
|
release(gch)
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
|
|
@ -519,6 +520,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
||||||
res.refcount = rcIncrement # refcount is 1
|
res.refcount = rcIncrement # refcount is 1
|
||||||
sysAssert(isAllocatedPtr(gch.region, res), "newObj: 3")
|
sysAssert(isAllocatedPtr(gch.region, res), "newObj: 3")
|
||||||
when logGC: writeCell("new cell", res)
|
when logGC: writeCell("new cell", res)
|
||||||
|
track("newObjRC1", res, size)
|
||||||
gcTrace(res, csAllocated)
|
gcTrace(res, csAllocated)
|
||||||
release(gch)
|
release(gch)
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
|
|
@ -561,6 +563,8 @@ proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
||||||
writeCell("growObj new cell", res)
|
writeCell("growObj new cell", res)
|
||||||
gcTrace(ol, csZctFreed)
|
gcTrace(ol, csZctFreed)
|
||||||
gcTrace(res, csAllocated)
|
gcTrace(res, csAllocated)
|
||||||
|
track("growObj old", ol, 0)
|
||||||
|
track("growObj new", res, newsize)
|
||||||
when reallyDealloc:
|
when reallyDealloc:
|
||||||
sysAssert(allocInv(gch.region), "growObj before dealloc")
|
sysAssert(allocInv(gch.region), "growObj before dealloc")
|
||||||
if ol.refcount shr rcShift <=% 1:
|
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) =
|
proc freeCyclicCell(gch: var GcHeap, c: PCell) =
|
||||||
prepareDealloc(c)
|
prepareDealloc(c)
|
||||||
gcTrace(c, csCycFreed)
|
gcTrace(c, csCycFreed)
|
||||||
|
track("cycle collector dealloc cell", c, 0)
|
||||||
when logGC: writeCell("cycle collector dealloc cell", c)
|
when logGC: writeCell("cycle collector dealloc cell", c)
|
||||||
when reallyDealloc:
|
when reallyDealloc:
|
||||||
sysAssert(allocInv(gch.region), "free cyclic cell")
|
sysAssert(allocInv(gch.region), "free cyclic cell")
|
||||||
|
|
@ -673,6 +678,7 @@ proc doOperation(p: pointer, op: WalkOp) =
|
||||||
gcAssert(c.refcount >=% rcIncrement, "doOperation 2")
|
gcAssert(c.refcount >=% rcIncrement, "doOperation 2")
|
||||||
#c.refcount = c.refcount -% rcIncrement
|
#c.refcount = c.refcount -% rcIncrement
|
||||||
when logGC: writeCell("decref (from doOperation)", c)
|
when logGC: writeCell("decref (from doOperation)", c)
|
||||||
|
track("waZctDecref", p, 0)
|
||||||
decRef(c)
|
decRef(c)
|
||||||
#if c.refcount <% rcIncrement: addZCT(gch.zct, c)
|
#if c.refcount <% rcIncrement: addZCT(gch.zct, c)
|
||||||
of waPush:
|
of waPush:
|
||||||
|
|
@ -765,6 +771,7 @@ proc collectZCT(gch: var GcHeap): bool =
|
||||||
# In any case, it should be removed from the ZCT. But not
|
# In any case, it should be removed from the ZCT. But not
|
||||||
# freed. **KEEP THIS IN MIND WHEN MAKING THIS INCREMENTAL!**
|
# freed. **KEEP THIS IN MIND WHEN MAKING THIS INCREMENTAL!**
|
||||||
when logGC: writeCell("zct dealloc cell", c)
|
when logGC: writeCell("zct dealloc cell", c)
|
||||||
|
track("zct dealloc cell", c, 0)
|
||||||
gcTrace(c, csZctFreed)
|
gcTrace(c, csZctFreed)
|
||||||
# We are about to free the object, call the finalizer BEFORE its
|
# We are about to free the object, call the finalizer BEFORE its
|
||||||
# children are deleted as well, because otherwise the finalizer may
|
# children are deleted as well, because otherwise the finalizer may
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,9 @@ type
|
||||||
line*: int
|
line*: int
|
||||||
TrackLog* = object
|
TrackLog* = object
|
||||||
count*: int
|
count*: int
|
||||||
|
disabled: bool
|
||||||
data*: array[4000, LogEntry]
|
data*: array[4000, LogEntry]
|
||||||
TrackLogger* = proc (log: TrackLog) {.nimcall.}
|
TrackLogger* = proc (log: TrackLog) {.nimcall, tags: [], locks: 0.}
|
||||||
|
|
||||||
var
|
var
|
||||||
gLog*: TrackLog
|
gLog*: TrackLog
|
||||||
|
|
@ -38,6 +39,7 @@ proc setTrackLogger*(logger: TrackLogger) =
|
||||||
gLogger = logger
|
gLogger = logger
|
||||||
|
|
||||||
proc addEntry(entry: LogEntry) =
|
proc addEntry(entry: LogEntry) =
|
||||||
|
if not gLog.disabled:
|
||||||
if gLog.count > high(gLog.data):
|
if gLog.count > high(gLog.data):
|
||||||
gLogger(gLog)
|
gLogger(gLog)
|
||||||
gLog.count = 0
|
gLog.count = 0
|
||||||
|
|
@ -52,6 +54,12 @@ proc memTrackerOp*(op: cstring; address: pointer; size: int) =
|
||||||
addEntry LogEntry(op: op, address: address, size: size,
|
addEntry LogEntry(op: op, address: address, size: size,
|
||||||
file: "", line: 0)
|
file: "", line: 0)
|
||||||
|
|
||||||
|
proc memTrackerDisable*() =
|
||||||
|
gLog.disabled = true
|
||||||
|
|
||||||
|
proc memTrackerEnable*() =
|
||||||
|
gLog.disabled = false
|
||||||
|
|
||||||
proc logPendingOps() {.noconv.} =
|
proc logPendingOps() {.noconv.} =
|
||||||
# forward declared and called from Nim's signal handler.
|
# forward declared and called from Nim's signal handler.
|
||||||
gLogger(gLog)
|
gLogger(gLog)
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ type
|
||||||
|
|
||||||
Callback* = proc (para1: pointer, para2: int32, para3,
|
Callback* = proc (para1: pointer, para2: int32, para3,
|
||||||
para4: cstringArray): int32{.cdecl.}
|
para4: cstringArray): int32{.cdecl.}
|
||||||
Tbind_destructor_func* = proc (para1: pointer){.cdecl.}
|
Tbind_destructor_func* = proc (para1: pointer){.cdecl, locks: 0, tags: [].}
|
||||||
Create_function_step_func* = proc (para1: Pcontext, para2: int32,
|
Create_function_step_func* = proc (para1: Pcontext, para2: int32,
|
||||||
para3: PValueArg){.cdecl.}
|
para3: PValueArg){.cdecl.}
|
||||||
Create_function_func_func* = proc (para1: Pcontext, para2: int32,
|
Create_function_func_func* = proc (para1: Pcontext, para2: int32,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue