summary refs log tree commit diff stats
path: root/lib/system
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-03-29 16:36:24 +0100
committerAraq <rumpf_a@web.de>2013-03-29 16:36:24 +0100
commite24305f1e15f63256528e0a9649464919eae83c6 (patch)
tree0aef4aafca8e453cc773143a62a3fd45a87994b3 /lib/system
parent905fb8578979513829b7d6d1da6722d20d306430 (diff)
downloadNim-e24305f1e15f63256528e0a9649464919eae83c6.tar.gz
bugfix: mark&sweep GC
Diffstat (limited to 'lib/system')
-rw-r--r--lib/system/alloc.nim30
1 files changed, 16 insertions, 14 deletions
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 7b52780fe..744c26d36 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -312,20 +312,22 @@ proc chunkUnused(c: PChunk): bool {.inline.} =
 
 iterator allObjects(m: TMemRegion): pointer {.inline.} =
   for s in elements(m.chunkStarts):
-    let c = cast[PChunk](s shl PageShift)
-    if not chunkUnused(c):
-      if isSmallChunk(c):
-        var c = cast[PSmallChunk](c)
-        
-        let size = c.size
-        var a = cast[TAddress](addr(c.data))
-        let limit = a + c.acc
-        while a <% limit:
-          yield cast[pointer](a)
-          a = a +% size
-      else:
-        let c = cast[PBigChunk](c)
-        yield addr(c.data)
+    # we need to check here again as it could have been modified:
+    if s in m.chunkStarts:
+      let c = cast[PChunk](s shl PageShift)
+      if not chunkUnused(c):
+        if isSmallChunk(c):
+          var c = cast[PSmallChunk](c)
+          
+          let size = c.size
+          var a = cast[TAddress](addr(c.data))
+          let limit = a + c.acc
+          while a <% limit:
+            yield cast[pointer](a)
+            a = a +% size
+        else:
+          let c = cast[PBigChunk](c)
+          yield addr(c.data)
 
 proc isCell(p: pointer): bool {.inline.} =
   result = cast[ptr TFreeCell](p).zeroField >% 1