summary refs log tree commit diff stats
path: root/lib/system/gc_regions.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/system/gc_regions.nim')
-rw-r--r--lib/system/gc_regions.nim79
1 files changed, 47 insertions, 32 deletions
diff --git a/lib/system/gc_regions.nim b/lib/system/gc_regions.nim
index e9efbdfb0..06fded86b 100644
--- a/lib/system/gc_regions.nim
+++ b/lib/system/gc_regions.nim
@@ -70,8 +70,9 @@ type
     bump: pointer
     head, tail: Chunk
     nextChunkSize, totalSize: int
-    freeLists: array[MaxSmallObject div MemAlign, FreeEntry]
-    holes: SizedFreeEntry
+    when false:
+      freeLists: array[MaxSmallObject div MemAlign, FreeEntry]
+      holes: SizedFreeEntry
     when hasThreadSupport:
       lock: SysLock
 
@@ -144,22 +145,24 @@ proc allocSlowPath(r: var MemRegion; size: int) =
   r.tail = fresh
   r.remaining = s - sizeof(BaseChunk)
 
-proc alloc(r: var MemRegion; size: int): pointer =
-  if size <= MaxSmallObject:
-    var it = r.freeLists[size div MemAlign]
-    if it != nil:
-      r.freeLists[size div MemAlign] = it.next
-      return pointer(it)
-  else:
-    var it = r.holes
-    var prev: SizedFreeEntry = nil
-    while it != nil:
-      if it.size >= size:
-        if prev != nil: prev.next = it.next
-        else: r.holes = it.next
+proc allocFast(r: var MemRegion; size: int): pointer =
+  when false:
+    if size <= MaxSmallObject:
+      var it = r.freeLists[size div MemAlign]
+      if it != nil:
+        r.freeLists[size div MemAlign] = it.next
         return pointer(it)
-      prev = it
-      it = it.next
+    else:
+      var it = r.holes
+      var prev: SizedFreeEntry = nil
+      while it != nil:
+        if it.size >= size:
+          if prev != nil: prev.next = it.next
+          else: r.holes = it.next
+          return pointer(it)
+        prev = it
+        it = it.next
+  let size = roundup(size, MemAlign)
   if size > r.remaining:
     allocSlowPath(r, size)
   sysAssert(size <= r.remaining, "size <= r.remaining")
@@ -184,15 +187,16 @@ proc dealloc(r: var MemRegion; p: pointer; size: int) =
   # it is benefitial to not use the free lists here:
   if r.bump -! size == p:
     dec r.bump, size
-  elif size <= MaxSmallObject:
-    let it = cast[FreeEntry](p)
-    it.next = r.freeLists[size div MemAlign]
-    r.freeLists[size div MemAlign] = it
-  else:
-    let it = cast[SizedFreeEntry](p)
-    it.size = size
-    it.next = r.holes
-    r.holes = it
+  when false:
+    if size <= MaxSmallObject:
+      let it = cast[FreeEntry](p)
+      it.next = r.freeLists[size div MemAlign]
+      r.freeLists[size div MemAlign] = it
+    else:
+      let it = cast[SizedFreeEntry](p)
+      it.size = size
+      it.next = r.holes
+      r.holes = it
 
 proc deallocAll(r: var MemRegion; head: Chunk) =
   var it = head
@@ -220,9 +224,10 @@ proc setObstackPtr*(r: var MemRegion; sp: StackPtr) =
   if sp.current.next != nil:
     deallocAll(r, sp.current.next)
     sp.current.next = nil
-    # better leak this memory than be sorry:
-    for i in 0..high(r.freeLists): r.freeLists[i] = nil
-    r.holes = nil
+    when false:
+      # 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
@@ -270,7 +275,7 @@ proc isOnHeap*(r: MemRegion; p: pointer): bool =
     it = it.next
 
 proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer =
-  var res = cast[ptr ObjHeader](alloc(r, size + sizeof(ObjHeader)))
+  var res = cast[ptr ObjHeader](allocFast(r, size + sizeof(ObjHeader)))
   res.typ = typ
   if typ.finalizer != nil:
     res.nextFinal = r.head.head
@@ -278,17 +283,19 @@ proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer =
   result = res +! sizeof(ObjHeader)
 
 proc rawNewSeq(r: var MemRegion, typ: PNimType, size: int): pointer =
-  var res = cast[ptr SeqHeader](alloc(r, size + sizeof(SeqHeader)))
+  var res = cast[ptr SeqHeader](allocFast(r, size + sizeof(SeqHeader)))
   res.typ = typ
   res.region = addr(r)
   result = res +! sizeof(SeqHeader)
 
 proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.} =
+  sysAssert typ.kind notin {tySequence, tyString}, "newObj cannot be used to construct seqs"
   result = rawNewObj(tlRegion, typ, size)
   zeroMem(result, size)
   when defined(memProfiler): nimProfile(size)
 
 proc newObjNoInit(typ: PNimType, size: int): pointer {.compilerRtl.} =
+  sysAssert typ.kind notin {tySequence, tyString}, "newObj cannot be used to construct seqs"
   result = rawNewObj(tlRegion, typ, size)
   when defined(memProfiler): nimProfile(size)
 
@@ -351,6 +358,11 @@ proc alloc0(r: var MemRegion; size: Natural): pointer =
   # but incorrect in general. XXX
   result = alloc0(size)
 
+proc alloc(r: var MemRegion; size: Natural): pointer =
+  # ignore the region. That is correct for the channels module
+  # but incorrect in general. XXX
+  result = alloc(size)
+
 proc dealloc(r: var MemRegion; p: pointer) = dealloc(p)
 
 proc allocShared(size: Natural): pointer =
@@ -389,4 +401,7 @@ proc getFreeMem*(r: MemRegion): int = r.remaining
 proc getTotalMem*(r: MemRegion): int =
   result = r.totalSize
 
-proc setStackBottom(theStackBottom: pointer) = discard
+proc nimGC_setStackBottom(theStackBottom: pointer) = discard
+
+proc nimGCref(x: pointer) {.compilerProc.} = discard
+proc nimGCunref(x: pointer) {.compilerProc.} = discard
id='n343' href='#n343'>343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408