improvements to memtracking

This commit is contained in:
Andreas Rumpf
2017-01-26 11:25:55 +01:00
parent 303c49b9f3
commit 05a3c1b10a
5 changed files with 38 additions and 16 deletions

View File

@@ -1630,20 +1630,22 @@ when not defined(nimscript) and not defined(JS):
## Exactly ``size`` bytes will be overwritten. Like any procedure
## dealing with raw memory this is *unsafe*.
proc copyMem*(dest, source: pointer, size: Natural) {.inline, benign.}
proc copyMem*(dest, source: pointer, size: Natural) {.inline, benign,
tags: [], locks: 0.}
## copies the contents from the memory at ``source`` to the memory
## at ``dest``. Exactly ``size`` bytes will be copied. The memory
## regions may not overlap. Like any procedure dealing with raw
## memory this is *unsafe*.
proc moveMem*(dest, source: pointer, size: Natural) {.inline, benign.}
proc moveMem*(dest, source: pointer, size: Natural) {.inline, benign,
tags: [], locks: 0.}
## copies the contents from the memory at ``source`` to the memory
## at ``dest``. Exactly ``size`` bytes will be copied. The memory
## regions may overlap, ``moveMem`` handles this case appropriately
## and is thus somewhat more safe than ``copyMem``. Like any procedure
## dealing with raw memory this is still *unsafe*, though.
proc equalMem*(a, b: pointer, size: Natural): bool {.inline, noSideEffect.}
proc equalMem*(a, b: pointer, size: Natural): bool {.inline, noSideEffect, tags: [], locks: 0.}
## compares the memory blocks ``a`` and ``b``. ``size`` bytes will
## be compared. If the blocks are equal, true is returned, false
## otherwise. Like any procedure dealing with raw memory this is
@@ -2688,16 +2690,6 @@ when not defined(JS): #and not defined(nimscript):
else:
result = int(c_strcmp(x, y))
when not defined(nimscript):
proc zeroMem(p: pointer, size: Natural) =
c_memset(p, 0, size)
proc copyMem(dest, source: pointer, size: Natural) =
c_memcpy(dest, source, size)
proc moveMem(dest, source: pointer, size: Natural) =
c_memmove(dest, source, size)
proc equalMem(a, b: pointer, size: Natural): bool =
c_memcmp(a, b, size) == 0
when defined(nimscript):
proc readFile*(filename: string): string {.tags: [ReadIOEffect], benign.}
## Opens a file named `filename` for reading, calls `readAll
@@ -2986,6 +2978,23 @@ when not defined(JS): #and not defined(nimscript):
{.push stack_trace: off, profiler:off.}
when defined(memtracker):
include "system/memtracker"
when not defined(nimscript):
proc zeroMem(p: pointer, size: Natural) =
c_memset(p, 0, size)
when declared(memTrackerOp):
memTrackerOp("zeroMem", p, size)
proc copyMem(dest, source: pointer, size: Natural) =
c_memcpy(dest, source, size)
when declared(memTrackerOp):
memTrackerOp("copyMem", dest, size)
proc moveMem(dest, source: pointer, size: Natural) =
c_memmove(dest, source, size)
when declared(memTrackerOp):
memTrackerOp("moveMem", dest, size)
proc equalMem(a, b: pointer, size: Natural): bool =
c_memcmp(a, b, size) == 0
when hostOS == "standalone":
include "system/embedded"
else:

View File

@@ -140,6 +140,8 @@ proc llAlloc(a: var MemRegion, size: int): pointer =
sysAssert roundup(size+sizeof(LLChunk), PageSize) == PageSize, "roundup 6"
var old = a.llmem # can be nil and is correct with nil
a.llmem = cast[PLLChunk](osAllocPages(PageSize))
when defined(avlcorruption):
trackLocation(a.llmem, PageSize)
incCurrMem(a, PageSize)
a.llmem.size = PageSize - sizeof(LLChunk)
a.llmem.acc = sizeof(LLChunk)
@@ -155,11 +157,15 @@ proc allocAvlNode(a: var MemRegion, key, upperBound: int): PAvlNode =
a.freeAvlNodes = a.freeAvlNodes.link[0]
else:
result = cast[PAvlNode](llAlloc(a, sizeof(AvlNode)))
when defined(avlcorruption):
cprintf("tracking location: %p\n", result)
result.key = key
result.upperBound = upperBound
result.link[0] = bottom
result.link[1] = bottom
result.level = 1
when defined(avlcorruption):
track("allocAvlNode", result, sizeof(AvlNode))
sysAssert(bottom == addr(bottomData), "bottom data")
sysAssert(bottom.link[0] == bottom, "bottom link[0]")
sysAssert(bottom.link[1] == bottom, "bottom link[1]")
@@ -666,7 +672,7 @@ proc ptrSize(p: pointer): int =
if not isSmallChunk(c):
dec result, bigChunkOverhead()
proc alloc(allocator: var MemRegion, size: Natural): pointer =
proc alloc(allocator: var MemRegion, size: Natural): pointer {.gcsafe.} =
result = rawAlloc(allocator, size+sizeof(FreeCell))
cast[ptr FreeCell](result).zeroField = 1 # mark it as used
sysAssert(not isAllocatedPtr(allocator, result), "alloc")

View File

@@ -56,8 +56,14 @@ proc add(a: var MemRegion, t: var PAvlNode, key, upperBound: int) {.benign.} =
t = allocAvlNode(a, key, upperBound)
else:
if key <% t.key:
when defined(avlcorruption):
if t.link[0] == nil:
cprintf("bug here %p\n", t)
add(a, t.link[0], key, upperBound)
elif key >% t.key:
when defined(avlcorruption):
if t.link[1] == nil:
cprintf("bug here B %p\n", t)
add(a, t.link[1], key, upperBound)
else:
sysAssert false, "key already exists"

View File

@@ -73,7 +73,8 @@ proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.co
addEntry LogEntry(op: "write", address: address,
size: size, file: file, line: line)
proc memTrackerOp*(op: cstring; address: pointer; size: int) =
proc memTrackerOp*(op: cstring; address: pointer; size: int) {.tags: [],
locks: 0, gcsafe.} =
addEntry LogEntry(op: op, address: address, size: size,
file: "", line: 0)

View File

@@ -110,7 +110,7 @@ type
Callback* = proc (para1: pointer, para2: int32, para3,
para4: cstringArray): int32{.cdecl.}
Tbind_destructor_func* = proc (para1: pointer){.cdecl, locks: 0, tags: [].}
Tbind_destructor_func* = proc (para1: pointer){.cdecl, locks: 0, tags: [], gcsafe.}
Create_function_step_func* = proc (para1: Pcontext, para2: int32,
para3: PValueArg){.cdecl.}
Create_function_func_func* = proc (para1: Pcontext, para2: int32,