summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2017-01-26 11:25:55 +0100
committerAndreas Rumpf <rumpf_a@web.de>2017-01-26 11:26:02 +0100
commit05a3c1b10a87c26b396aafbd72852db37dd0b378 (patch)
treed0546ce8ef4057e948fd15a2282fd6ba1644c706
parent303c49b9f3bfe90b248fb414dc514b8e61d4ad0f (diff)
downloadNim-05a3c1b10a87c26b396aafbd72852db37dd0b378.tar.gz
improvements to memtracking
-rw-r--r--lib/system.nim35
-rw-r--r--lib/system/alloc.nim8
-rw-r--r--lib/system/avltree.nim6
-rw-r--r--lib/system/memtracker.nim3
-rw-r--r--lib/wrappers/sqlite3.nim2
5 files changed, 38 insertions, 16 deletions
diff --git a/lib/system.nim b/lib/system.nim
index 782d6d946..1e6d2dff4 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -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:
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 780baad7a..9387c3128 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -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")
diff --git a/lib/system/avltree.nim b/lib/system/avltree.nim
index 50faada26..96c187841 100644
--- a/lib/system/avltree.nim
+++ b/lib/system/avltree.nim
@@ -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"
diff --git a/lib/system/memtracker.nim b/lib/system/memtracker.nim
index f37b0c45a..0e33e0ec0 100644
--- a/lib/system/memtracker.nim
+++ b/lib/system/memtracker.nim
@@ -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)
 
diff --git a/lib/wrappers/sqlite3.nim b/lib/wrappers/sqlite3.nim
index d2b70df8d..a12945832 100644
--- a/lib/wrappers/sqlite3.nim
+++ b/lib/wrappers/sqlite3.nim
@@ -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,