diff options
author | Araq <rumpf_a@web.de> | 2012-01-12 19:44:57 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-01-12 19:44:57 +0100 |
commit | e6b3f50c7f984fb9bd30db42582e04e6c3a2dd97 (patch) | |
tree | 254324ddcbc85fab57270d9b4fbf8b6b49a80d41 | |
parent | 92e1a21b260996538465a1c32a09943f001adc34 (diff) | |
download | Nim-e6b3f50c7f984fb9bd30db42582e04e6c3a2dd97.tar.gz |
more sysasserts for allocator/gc
-rwxr-xr-x | lib/pure/algorithm.nim | 17 | ||||
-rwxr-xr-x | lib/system.nim | 2 | ||||
-rwxr-xr-x | lib/system/alloc.nim | 4 | ||||
-rwxr-xr-x | lib/system/gc.nim | 9 | ||||
-rwxr-xr-x | tests/compile/tsortdev.nim | 19 | ||||
-rwxr-xr-x | todo.txt | 8 | ||||
-rwxr-xr-x | web/news.txt | 1 | ||||
-rwxr-xr-x | web/nimrod.ini | 2 |
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" |