mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 22:33:49 +00:00
more sysasserts for allocator/gc
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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[])
|
||||
|
||||
@@ -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:
|
||||
|
||||
8
todo.txt
8
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user