summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2017-08-13 02:50:23 +0200
committerAraq <rumpf_a@web.de>2017-08-13 02:51:00 +0200
commitb6360c5d5f19fd1e8c74fda703a465b8e46dbb63 (patch)
tree26802922aff7684f7455c2beccf68436af1dcb2a
parent36a26875ef6344fb1bb59ad64d8eed6037bf4a91 (diff)
downloadNim-b6360c5d5f19fd1e8c74fda703a465b8e46dbb63.tar.gz
memory regions seem to work now
-rw-r--r--lib/system/gc_regions.nim50
1 files changed, 32 insertions, 18 deletions
diff --git a/lib/system/gc_regions.nim b/lib/system/gc_regions.nim
index 7469373dc..e9efbdfb0 100644
--- a/lib/system/gc_regions.nim
+++ b/lib/system/gc_regions.nim
@@ -217,12 +217,15 @@ template computeRemaining(r): untyped =
 
 proc setObstackPtr*(r: var MemRegion; sp: StackPtr) =
   # free everything after 'sp':
-  if sp.current != nil:
+  if sp.current.next != nil:
     deallocAll(r, sp.current.next)
     sp.current.next = nil
-  else:
-    deallocAll(r, r.head)
-    r.head = nil
+    # better leak this memory than be sorry:
+    for i in 0..high(r.freeLists): r.freeLists[i] = nil
+    r.holes = nil
+  #else:
+  #  deallocAll(r, r.head)
+  #  r.head = nil
   r.bump = sp.bump
   r.tail = sp.current
   r.remaining = sp.remaining
@@ -233,17 +236,28 @@ proc deallocAll*() = tlRegion.deallocAll()
 
 proc deallocOsPages(r: var MemRegion) = r.deallocAll()
 
-proc joinRegion*(dest: var MemRegion; src: MemRegion) =
-  # merging is not hard.
-  if dest.head.isNil:
-    dest.head = src.head
-  else:
-    dest.tail.next = src.head
-  dest.tail = src.tail
-  dest.bump = src.bump
-  dest.remaining = src.remaining
-  dest.nextChunkSize = max(dest.nextChunkSize, src.nextChunkSize)
-  inc dest.totalSize, src.totalSize
+template withScratchRegion*(body: untyped) =
+  var scratch: MemRegion
+  let oldRegion = tlRegion
+  tlRegion = scratch
+  try:
+    body
+  finally:
+    tlRegion = oldRegion
+    deallocAll(scratch)
+
+when false:
+  proc joinRegion*(dest: var MemRegion; src: MemRegion) =
+    # merging is not hard.
+    if dest.head.isNil:
+      dest.head = src.head
+    else:
+      dest.tail.next = src.head
+    dest.tail = src.tail
+    dest.bump = src.bump
+    dest.remaining = src.remaining
+    dest.nextChunkSize = max(dest.nextChunkSize, src.nextChunkSize)
+    inc dest.totalSize, src.totalSize
 
 proc isOnHeap*(r: MemRegion; p: pointer): bool =
   # the tail chunk is the largest, so check it first. It's also special
@@ -290,7 +304,7 @@ proc newStr(typ: PNimType, len: int; init: bool): pointer {.compilerRtl.} =
   let size = roundup(addInt(len, GenericSeqSize), MemAlign)
   result = rawNewSeq(tlRegion, typ, size)
   if init: zeroMem(result, size)
-  cast[PGenericSeq](result).len = len
+  cast[PGenericSeq](result).len = 0
   cast[PGenericSeq](result).reserved = len
 
 proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
@@ -307,9 +321,9 @@ proc growObj(regionUnused: var MemRegion; old: pointer, newsize: int): pointer =
                      roundup(newsize, MemAlign))
   let elemSize = if typ.kind == tyString: 1 else: typ.base.size
   let oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize
-  copyMem(result, old, oldsize)
   zeroMem(result +! oldsize, newsize-oldsize)
-  #dealloc(sh.region[], old, roundup(oldsize, MemAlign))
+  copyMem(result, old, oldsize)
+  dealloc(sh.region[], old, roundup(oldsize, MemAlign))
 
 proc growObj(old: pointer, newsize: int): pointer {.rtl.} =
   result = growObj(tlRegion, old, newsize)