summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-01-12 19:44:57 +0100
committerAraq <rumpf_a@web.de>2012-01-12 19:44:57 +0100
commite6b3f50c7f984fb9bd30db42582e04e6c3a2dd97 (patch)
tree254324ddcbc85fab57270d9b4fbf8b6b49a80d41
parent92e1a21b260996538465a1c32a09943f001adc34 (diff)
downloadNim-e6b3f50c7f984fb9bd30db42582e04e6c3a2dd97.tar.gz
more sysasserts for allocator/gc
-rwxr-xr-xlib/pure/algorithm.nim17
-rwxr-xr-xlib/system.nim2
-rwxr-xr-xlib/system/alloc.nim4
-rwxr-xr-xlib/system/gc.nim9
-rwxr-xr-xtests/compile/tsortdev.nim19
-rwxr-xr-xtodo.txt8
-rwxr-xr-xweb/news.txt1
-rwxr-xr-xweb/nimrod.ini2
8 files changed, 38 insertions, 24 deletions
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index fa2482a3d..f283b434c 100755
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -16,7 +16,8 @@ type
 proc `*`*(x: int, order: TSortOrder): int {.inline.} = 
   ## flips `x` if ``order == Descending``;
   ## if ``order == Ascending`` then `x` is returned.
-  ## `x` is supposed to be the result of a comparator.
+  ## `x` is supposed to be the result of a comparator, ie ``< 0`` for 
+  ## *less than*, ``== 0`` for *equal*, ``> 0`` for *greater than*.
   var y = order.ord - 1
   result = (x xor y) - y
 
@@ -80,14 +81,22 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int,
   else:
     if k < j: copyMem(addr(a[k]), addr(b[i]), sizeof(T)*(j-k))
 
-proc sort*[T](a: var openArray[T], 
-              cmp: proc (x, y: T): int = cmp,
+proc sort*[T](a: var openArray[T],
+              cmp: proc (x, y: T): int,
               order = TSortOrder.Ascending) =
   ## Default Nimrod sort. The sorting is guaranteed to be stable and 
   ## the worst case is guaranteed to be O(n log n).
   ## The current implementation uses an iterative
   ## mergesort to achieve this. It uses a temporary sequence of 
-  ## length ``a.len div 2``.
+  ## length ``a.len div 2``. Currently Nimrod does not support a
+  ## sensible default argument for ``cmp``, so you have to provide one
+  ## of your own. However, the ``system.cmp`` procs can be used:
+  ##
+  ## .. code-block:: nimrod
+  ##
+  ##    sort(myIntArray, system.cmp[int])
+  ##    sort(myStrArray, system.cmp)
+  ##
   var n = a.len
   var b: seq[T]
   newSeq(b, n div 2)
diff --git a/lib/system.nim b/lib/system.nim
index 59e95cf13..c073bff92 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -833,7 +833,7 @@ proc quit*(errorcode: int = QuitSuccess) {.
 
 template sysAssert(cond, msg: expr) =
   # change this to activate system asserts
-  #if not cond: 
+  #if not cond:
   #  echo "[SYSASSERT] ", msg
   #  quit 1
   nil
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index a7c504afc..6fd9efebd 100755
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -478,6 +478,7 @@ proc getSmallChunk(a: var TMemRegion): PSmallChunk =
   result = cast[PSmallChunk](res)
 
 # -----------------------------------------------------------------------------
+proc isAllocatedPtr(a: TMemRegion, p: pointer): bool
 
 proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer =
   sysAssert(roundup(65, 8) == 72, "rawAlloc 1")
@@ -537,7 +538,8 @@ proc rawAlloc0(a: var TMemRegion, requestedSize: int): pointer =
   result = rawAlloc(a, requestedSize)
   zeroMem(result, requestedSize)
 
-proc rawDealloc(a: var TMemRegion, p: pointer) = 
+proc rawDealloc(a: var TMemRegion, p: pointer) =
+  sysAssert(isAllocatedPtr(a, p), "rawDealloc: no allocated pointer!")
   var c = pageAddr(p)
   if isSmallChunk(c):
     # `p` is within a small chunk:
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 2f6b5d395..2ac61fca0 100755
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -222,11 +222,8 @@ proc rtlAddZCT(c: PCell) {.rtl, inl.} =
     ReleaseSys(HeapLock)
 
 proc decRef(c: PCell) {.inline.} =
-  when stressGC:
-    if c.refcount <% rcIncrement:
-      writeCell("broken cell", c)
+  sysAssert(isAllocatedPtr(gch.region, c), "decRef: interiorPtr")
   sysAssert(c.refcount >=% rcIncrement, "decRef")
-  #if c.refcount <% rcIncrement: quit("leck mich")
   if --c.refcount:
     rtlAddZCT(c)
   elif canBeCycleRoot(c):
@@ -235,6 +232,7 @@ proc decRef(c: PCell) {.inline.} =
     rtlAddCycleRoot(c) 
 
 proc incRef(c: PCell) {.inline.} = 
+  sysAssert(isAllocatedPtr(gch.region, c), "incRef: interiorPtr")
   ++c.refcount
   if canBeCycleRoot(c):
     rtlAddCycleRoot(c)
@@ -500,6 +498,7 @@ proc doOperation(p: pointer, op: TWalkOp) =
   sysAssert(c != nil, "doOperation: 1")
   case op # faster than function pointers because of easy prediction
   of waZctDecRef:
+    sysAssert(isAllocatedPtr(gch.region, c), "decRef: waZctDecRef")
     sysAssert(c.refcount >=% rcIncrement, "doOperation 2")
     c.refcount = c.refcount -% rcIncrement
     when logGC: writeCell("decref (from doOperation)", c)
@@ -727,8 +726,10 @@ proc CollectZCT(gch: var TGcHeap) =
   var L = addr(gch.zct.len)
   while L[] > 0:
     var c = gch.zct.d[0]
+    sysAssert(isAllocatedPtr(gch.region, c), "CollectZCT: isAllocatedPtr")
     # remove from ZCT:
     sysAssert((c.refcount and rcZct) == rcZct, "collectZCT")
+    
     c.refcount = c.refcount and not colorMask
     gch.zct.d[0] = gch.zct.d[L[] - 1]
     dec(L[])
diff --git a/tests/compile/tsortdev.nim b/tests/compile/tsortdev.nim
index c4e63fab4..479b8ffc0 100755
--- a/tests/compile/tsortdev.nim
+++ b/tests/compile/tsortdev.nim
@@ -1,5 +1,5 @@
 discard """
-  disabled: true
+  disabled: false
 """
 
 import math, algorithm
@@ -12,7 +12,7 @@ proc sorted[T](a: openArray[T], order: TSortOrder): bool =
       result = false
 
 proc bubbleSort[T](a: var openArray[T], 
-                   cmp: proc (x, y: T): int = cmp,
+                   cmp: proc (x, y: T): int,
                    order = TSortOrder.Ascending) =
   while true:
     var sorted = true
@@ -28,12 +28,16 @@ when isMainModule:
     var data: seq[string] = @[]
 
     for i in 0..10_000: 
-      var L = random(59)
+      var L = 59 #random(59)
       setLen(data, L)
       for j in 0 .. L-1: 
-        data[j] = $(math.random(90) - 10)
-      var copy = data
-      sort(data, cmp, order)
+        data[j] = "" #$(math.random(90) - 10)
+    when false:
+      #var copy = data
+      var copy: seq[string]
+      newSeq(copy, data.len)
+      for i in 0..data.high: copy[i] = data[i]
+      bubblesort(data, cmp, order)
       if not sorted(data, order):
         #for x in items(data): echo x
         break
@@ -46,6 +50,7 @@ when isMainModule:
         if copy[i] != data[i]:
           quit "algorithms differ!"
 
+  when false:
     for i in 0..10_000: 
       var data: seq[int] = @[]
       var L = random(59)
@@ -59,7 +64,7 @@ when isMainModule:
         break
       else:
         echo "SUCCESS!"
-      bubblesort(copy)
+      bubblesort(copy, cmp[int])
       if copy.len != data.len: 
         quit "lengths differ!"
       for i in 0 .. copy.high:
diff --git a/todo.txt b/todo.txt
index a932bfd0c..2132cc825 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,21 +1,17 @@
 version 0.8.14
 ==============
 
-- fix memory corruption bug triggered by visual c++ in release mode:
-  * sysasserts in incref
-  * force full collection in ccgstmts.nim
+- fix tsortdev bugs
 - fix line info in assertions
-- fix remaining generics bugs
-
 
 version 0.9.0
 =============
 
+- fix remaining generics bugs
 - GC: marker procs for native Nimrod GC and Boehm GC; precise stack marking;
   escape analysis for string/seq seems to be easy to do too;
   even further write barrier specialization
 - dead code elim for JS backend; 'of' operator for JS backend
-- test the sort implementation again
 - const ptr/ref
 - unsigned ints and bignums; requires abstract integer literal type: 
   use tyInt+node for that
diff --git a/web/news.txt b/web/news.txt
index 9faaeaa92..925271921 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -146,6 +146,7 @@ Library Additions
 - Added ``memfiles`` module.
 - Added ``subexes`` module.
 - Added ``critbits`` module.
+- Added ``algorithm`` module for generic ``sort``, ``reverse`` etc. operations.
 - Added ``osproc.startCmd``, ``osproc.execCmdEx``.
 - The ``osproc`` module now uses ``posix_spawn`` instead of ``fork`` 
   and ``exec`` on Posix systems. Define the symbol ``useFork`` to revert to
diff --git a/web/nimrod.ini b/web/nimrod.ini
index be8bcb509..7a5e6f01c 100755
--- a/web/nimrod.ini
+++ b/web/nimrod.ini
@@ -27,7 +27,7 @@ pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst"
 srcdoc: "core/macros;pure/marshal;core/typeinfo"
 srcdoc: "impure/graphics;impure/re;pure/sockets"
 srcdoc: "system.nim;system/threads.nim;system/channels.nim"
-srcdoc: "pure/os;pure/strutils;pure/math;pure/matchers"
+srcdoc: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm"
 srcdoc: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib"
 srcdoc: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase"
 srcdoc: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"