Removed lib/system/allocators.nim. seqs_v2 and strs_v2 now uses allocShared0. (#13190)
* Cleanup, remove lib/system/allocators.nim. seqs_v2 and strs_v2 now use allocShared0 by default. * Fixed -d:useMalloc allocShared / reallocShared / deallocShared. These now use the alloc/dealloc/realloc implementation that also takes care of zeroing memory at realloc. * Removed debug printfs * Removed unpairedEnvAllocs() from tests/destructor/tnewruntime_misc * More mmdisp cleanups. The shared allocators do not need to zero memory or throw since the regular ones already do that * Introduced realloc0 and reallocShared0, these procs are now used by strs_v2 and seqs_v2. This also allowed the -d:useMalloc allocator to drop the extra header with allocation length. * Moved strs_v2/seqs_v2 'allocated' flag into 'cap' field * Added 'getAllocStats()' to get low level alloc/dealloc counters. Enable with -d:allocStats * *allocShared implementations for boehm and go allocators now depend on the proper *allocImpl procs
This commit is contained in:
parent
f500895efe
commit
b68eb1cad0
21 changed files with 275 additions and 312 deletions
|
|
@ -9,12 +9,12 @@
|
|||
|
||||
## Default new string implementation used by Nim's core.
|
||||
|
||||
import allocators
|
||||
|
||||
type
|
||||
NimStrPayloadBase = object
|
||||
cap: int
|
||||
|
||||
NimStrPayload {.core.} = object
|
||||
cap: int
|
||||
allocator: Allocator
|
||||
data: UncheckedArray[char]
|
||||
|
||||
NimStringV2 {.core.} = object
|
||||
|
|
@ -23,13 +23,13 @@ type
|
|||
|
||||
const nimStrVersion {.core.} = 2
|
||||
|
||||
template isLiteral(s): bool = s.p == nil or s.p.allocator == nil
|
||||
template isLiteral(s): bool = (s.p == nil) or (s.p.cap and strlitFlag) == strlitFlag
|
||||
|
||||
template contentSize(cap): int = cap + 1 + sizeof(int) + sizeof(Allocator)
|
||||
template contentSize(cap): int = cap + 1 + sizeof(NimStrPayloadBase)
|
||||
|
||||
template frees(s) =
|
||||
if not isLiteral(s):
|
||||
s.p.allocator.dealloc(s.p.allocator, s.p, contentSize(s.p.cap))
|
||||
deallocShared(s.p)
|
||||
|
||||
proc resize(old: int): int {.inline.} =
|
||||
if old <= 0: result = 4
|
||||
|
|
@ -41,19 +41,17 @@ proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} =
|
|||
if addlen > 0:
|
||||
let oldP = s.p
|
||||
# can't mutate a literal, so we need a fresh copy here:
|
||||
let allocator = getLocalAllocator()
|
||||
s.p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(s.len + addlen)))
|
||||
s.p.allocator = allocator
|
||||
s.p = cast[ptr NimStrPayload](allocShared0(contentSize(s.len + addlen)))
|
||||
s.p.cap = s.len + addlen
|
||||
if s.len > 0:
|
||||
# we are about to append, so there is no need to copy the \0 terminator:
|
||||
copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len)
|
||||
elif s.len + addlen > s.p.cap:
|
||||
let cap = max(s.len + addlen, resize(s.p.cap))
|
||||
s.p = cast[ptr NimStrPayload](s.p.allocator.realloc(s.p.allocator, s.p,
|
||||
oldSize = contentSize(s.p.cap),
|
||||
newSize = contentSize(cap)))
|
||||
s.p.cap = cap
|
||||
else:
|
||||
let oldCap = s.p.cap and not strlitFlag
|
||||
if s.len + addlen > oldCap:
|
||||
let newCap = max(s.len + addlen, resize(oldCap))
|
||||
s.p = cast[ptr NimStrPayload](reallocShared0(s.p, contentSize(oldCap), contentSize(newCap)))
|
||||
s.p.cap = newCap
|
||||
|
||||
proc nimAddCharV1(s: var NimStringV2; c: char) {.compilerRtl.} =
|
||||
prepareAdd(s, 1)
|
||||
|
|
@ -65,9 +63,7 @@ proc toNimStr(str: cstring, len: int): NimStringV2 {.compilerproc.} =
|
|||
if len <= 0:
|
||||
result = NimStringV2(len: 0, p: nil)
|
||||
else:
|
||||
let allocator = getLocalAllocator()
|
||||
var p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(len)))
|
||||
p.allocator = allocator
|
||||
var p = cast[ptr NimStrPayload](allocShared0(contentSize(len)))
|
||||
p.cap = len
|
||||
if len > 0:
|
||||
# we are about to append, so there is no need to copy the \0 terminator:
|
||||
|
|
@ -98,9 +94,7 @@ proc rawNewString(space: int): NimStringV2 {.compilerproc.} =
|
|||
if space <= 0:
|
||||
result = NimStringV2(len: 0, p: nil)
|
||||
else:
|
||||
let allocator = getLocalAllocator()
|
||||
var p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(space)))
|
||||
p.allocator = allocator
|
||||
var p = cast[ptr NimStrPayload](allocShared0(contentSize(space)))
|
||||
p.cap = space
|
||||
result = NimStringV2(len: 0, p: p)
|
||||
|
||||
|
|
@ -108,9 +102,7 @@ proc mnewString(len: int): NimStringV2 {.compilerproc.} =
|
|||
if len <= 0:
|
||||
result = NimStringV2(len: 0, p: nil)
|
||||
else:
|
||||
let allocator = getLocalAllocator()
|
||||
var p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(len)))
|
||||
p.allocator = allocator
|
||||
var p = cast[ptr NimStrPayload](allocShared0(contentSize(len)))
|
||||
p.cap = len
|
||||
result = NimStringV2(len: len, p: p)
|
||||
|
||||
|
|
@ -130,24 +122,20 @@ proc nimAsgnStrV2(a: var NimStringV2, b: NimStringV2) {.compilerRtl.} =
|
|||
a.len = b.len
|
||||
a.p = b.p
|
||||
else:
|
||||
if isLiteral(a) or a.p.cap < b.len:
|
||||
let allocator = if a.p != nil and a.p.allocator != nil: a.p.allocator else: getLocalAllocator()
|
||||
if isLiteral(a) or (a.p.cap and not strlitFlag) < b.len:
|
||||
# we have to allocate the 'cap' here, consider
|
||||
# 'let y = newStringOfCap(); var x = y'
|
||||
# on the other hand... These get turned into moves now.
|
||||
frees(a)
|
||||
a.p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(b.len)))
|
||||
a.p.allocator = allocator
|
||||
a.p = cast[ptr NimStrPayload](allocShared0(contentSize(b.len)))
|
||||
a.p.cap = b.len
|
||||
a.len = b.len
|
||||
copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1)
|
||||
|
||||
proc nimPrepareStrMutationV2(s: var NimStringV2) {.compilerRtl.} =
|
||||
if s.p != nil and s.p.allocator == nil:
|
||||
if s.p != nil and (s.p.cap and strlitFlag) == strlitFlag:
|
||||
let oldP = s.p
|
||||
# can't mutate a literal, so we need a fresh copy here:
|
||||
let allocator = getLocalAllocator()
|
||||
s.p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(s.len)))
|
||||
s.p.allocator = allocator
|
||||
s.p = cast[ptr NimStrPayload](allocShared0(contentSize(s.len)))
|
||||
s.p.cap = s.len
|
||||
copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len+1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue