diff options
author | Andrii Riabushenko <cdome@bk.ru> | 2018-11-29 23:41:38 +0000 |
---|---|---|
committer | Andrii Riabushenko <cdome@bk.ru> | 2018-11-29 23:41:38 +0000 |
commit | 4c327d9ae235e11ca94153a734f481b1f55e1789 (patch) | |
tree | 6cb869823f9dc4fa0f8df2e9b63f08ad6e8cc950 /lib | |
parent | 9bba790534be76c6b50033d54d061eb076f35d9d (diff) | |
parent | 350396e1cab824ec69a9a06380ff15a7fa799819 (diff) | |
download | Nim-4c327d9ae235e11ca94153a734f481b1f55e1789.tar.gz |
merge devel
Diffstat (limited to 'lib')
-rw-r--r-- | lib/core/allocators.nim | 34 | ||||
-rw-r--r-- | lib/core/seqs.nim | 17 | ||||
-rw-r--r-- | lib/system.nim | 4 |
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.} = |