summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndrii Riabushenko <cdome@bk.ru>2018-11-29 23:41:38 +0000
committerAndrii Riabushenko <cdome@bk.ru>2018-11-29 23:41:38 +0000
commit4c327d9ae235e11ca94153a734f481b1f55e1789 (patch)
tree6cb869823f9dc4fa0f8df2e9b63f08ad6e8cc950 /lib
parent9bba790534be76c6b50033d54d061eb076f35d9d (diff)
parent350396e1cab824ec69a9a06380ff15a7fa799819 (diff)
downloadNim-4c327d9ae235e11ca94153a734f481b1f55e1789.tar.gz
merge devel
Diffstat (limited to 'lib')
-rw-r--r--lib/core/allocators.nim34
-rw-r--r--lib/core/seqs.nim17
-rw-r--r--lib/system.nim4
3 files changed, 34 insertions, 21 deletions
diff --git a/lib/core/allocators.nim b/lib/core/allocators.nim
index f652f0d85..5189bb762 100644
--- a/lib/core/allocators.nim
+++ b/lib/core/allocators.nim
@@ -11,19 +11,36 @@ type
   AllocatorFlag* {.pure.} = enum  ## flags describing the properties of the allocator
     ThreadLocal ## the allocator is thread local only.
     ZerosMem    ## the allocator always zeros the memory on an allocation
-  Allocator* = ptr object {.inheritable.}
+  Allocator* = ptr AllocatorObj
+  AllocatorObj* {.inheritable.} = object
     alloc*: proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall.}
     dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall.}
     realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall.}
     deallocAll*: proc (a: Allocator) {.nimcall.}
     flags*: set[AllocatorFlag]
+    allocCount: int
+    deallocCount: int
 
 var
   localAllocator {.threadvar.}: Allocator
   sharedAllocator: Allocator
+  allocatorStorage {.threadvar.}: AllocatorObj
 
 proc getLocalAllocator*(): Allocator =
   result = localAllocator
+  if result == nil:
+    result = addr allocatorStorage
+    result.alloc = proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall.} =
+      result = system.alloc(size)
+      inc a.allocCount
+    result.dealloc = proc (a: Allocator; p: pointer; size: int) {.nimcall.} =
+      system.dealloc(p)
+      inc a.deallocCount
+    result.realloc = proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall.} =
+      result = system.realloc(p, newSize)
+    result.deallocAll = nil
+    result.flags = {ThreadLocal}
+    localAllocator = result
 
 proc setLocalAllocator*(a: Allocator) =
   localAllocator = a
@@ -34,15 +51,6 @@ proc getSharedAllocator*(): Allocator =
 proc setSharedAllocator*(a: Allocator) =
   sharedAllocator = a
 
-when false:
-  proc alloc*(size: int; alignment: int = 8): pointer =
-    let a = getCurrentAllocator()
-    result = a.alloc(a, size, alignment)
-
-  proc dealloc*(p: pointer; size: int) =
-    let a = getCurrentAllocator()
-    a.dealloc(a, p, size)
-
-  proc realloc*(p: pointer; oldSize, newSize: int): pointer =
-    let a = getCurrentAllocator()
-    result = a.realloc(a, p, oldSize, newSize)
+proc allocCounters*(): (int, int) =
+  let a = getLocalAllocator()
+  result = (a.allocCount, a.deallocCount)
diff --git a/lib/core/seqs.nim b/lib/core/seqs.nim
index c62a05904..a41ef10ab 100644
--- a/lib/core/seqs.nim
+++ b/lib/core/seqs.nim
@@ -85,7 +85,7 @@ type
 proc newSeqPayload(cap, elemSize: int): pointer {.compilerRtl.} =
   # we have to use type erasure here as Nim does not support generic
   # compilerProcs. Oh well, this will all be inlined anyway.
-  if cap <= 0:
+  if cap > 0:
     let region = getLocalAllocator()
     var p = cast[ptr PayloadBase](region.alloc(region, cap * elemSize + sizeof(int) + sizeof(Allocator)))
     p.region = region
@@ -126,18 +126,19 @@ proc grow*[T](x: var seq[T]; newLen: Natural; value: T) =
   let oldLen = x.len
   if newLen <= oldLen: return
   var xu = cast[ptr NimSeqV2[T]](addr x)
-
-  xu.p = cast[typeof(xu.p)](prepareSeqAdd(oldLen, xu.p, newLen - oldLen, sizeof(T)))
+  if xu.p == nil or xu.p.cap < newLen:
+    xu.p = cast[typeof(xu.p)](prepareSeqAdd(oldLen, xu.p, newLen - oldLen, sizeof(T)))
   xu.len = newLen
   for i in oldLen .. newLen-1:
     xu.p.data[i] = value
 
 proc setLen[T](s: var seq[T], newlen: Natural) =
-  if newlen < s.len:
-    shrink(s, newLen)
-  else:
-    var v: T # get the default value of 'v'
-    grow(s, newLen, v)
+  {.noSideEffect.}:
+    if newlen < s.len:
+      shrink(s, newLen)
+    else:
+      var v: T # get the default value of 'v'
+      grow(s, newLen, v)
 
 when false:
   proc resize[T](s: var NimSeqV2[T]) =
diff --git a/lib/system.nim b/lib/system.nim
index 4414c2107..9111ddd86 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -4209,6 +4209,10 @@ when hasAlloc and not defined(nimscript) and not defined(JS) and
     ## for the implementation of ``spawn``.
     discard
 
+  proc deepCopy*[T](y: T): T =
+    ## Convenience wrapper around `deepCopy` overload.
+    deepCopy(result, y)
+
   include "system/deepcopy"
 
 proc procCall*(x: untyped) {.magic: "ProcCall", compileTime.} =