This commit is contained in:
ringabout
2023-12-06 14:25:34 +00:00
committed by GitHub
parent 88c0ac44fc
commit f7bdec6f0d
7 changed files with 94 additions and 23 deletions

View File

@@ -1616,7 +1616,10 @@ when not defined(js) and defined(nimV2):
proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
when notJSnotNims and defined(nimSeqsV2):
include "system/strs_v2"
when defined(nimSeqsV3):
include "system/strs_v3"
else:
include "system/strs_v2"
include "system/seqs_v2"
when not defined(js):
@@ -1679,7 +1682,11 @@ when not defined(js):
result = newString(len)
else:
result = newStringOfCap(len)
when defined(nimSeqsV2):
when defined(nimSeqsV3):
let s = cast[ptr NimStringV3](addr result)
if len > 0:
s.len = len
elif defined(nimSeqsV2):
let s = cast[ptr NimStringV2](addr result)
if len > 0:
s.len = len

View File

@@ -61,7 +61,11 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
sysAssert(mt != nil, "genericAssignAux 2")
case mt.kind
of tyString:
when defined(nimSeqsV2):
when defined(nimSeqsV3):
var x = cast[ptr NimStringV3](dest)
var s2 = cast[ptr NimStringV3](s)[]
nimAsgnStrV2(x[], s2)
elif defined(nimSeqsV2):
var x = cast[ptr NimStringV2](dest)
var s2 = cast[ptr NimStringV2](s)[]
nimAsgnStrV2(x[], s2)
@@ -244,7 +248,11 @@ proc genericReset(dest: pointer, mt: PNimType) =
of tyRef:
unsureAsgnRef(cast[PPointer](dest), nil)
of tyString:
when defined(nimSeqsV2):
when defined(nimSeqsV3):
var s = cast[ptr NimStringV3](dest)
frees(s[])
zeroMem(dest, mt.size)
elif defined(nimSeqsV2):
var s = cast[ptr NimStringV2](dest)
frees(s[])
zeroMem(dest, mt.size)

View File

@@ -90,7 +90,11 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
sysAssert(mt != nil, "genericDeepCopyAux 2")
case mt.kind
of tyString:
when defined(nimSeqsV2):
when defined(nimSeqsV3):
var x = cast[ptr NimStringV3](dest)
var s2 = cast[ptr NimStringV3](s)[]
nimAsgnStrV2(x[], s2)
elif defined(nimSeqsV2):
var x = cast[ptr NimStringV2](dest)
var s2 = cast[ptr NimStringV2](s)[]
nimAsgnStrV2(x[], s2)

View File

@@ -11,25 +11,29 @@
type
NimStrPayloadBase = object
## cap lives at the negative offset of p: p - wordSize
cap: int
NimStrPayload {.core.} = object
data: UncheckedArray[char]
NimStringV3 {.core.} = object
rawlen: int ## the lowest bit is used to indict whether it's a const or intern string
## TODO: would it be better to use distinct?
p: ptr UncheckedArray[char] ## can be nil if len == 0.
## cap lives at the negative offset
## cap lives at the negative offset of p: p - wordSize
## non-zero terminated
const nimStrVersion {.core.} = 3
template isLiteral(s): bool = (s.rawlen and 1) == 1
template head(p: pointer): pointer =
cast[pointer](cast[int](p) -% sizeof(NimStrPayloadBase))
template cap(p: pointer): int =
cast[ptr NimStrPayloadBase](cast[int](p) -% sizeof(NimStrPayloadBase))[].cap
cast[ptr NimStrPayloadBase](head(p))[].cap
template `cap=`(p: pointer, size: int) =
cast[ptr NimStrPayloadBase](cast[int](p) -% sizeof(NimStrPayloadBase))[].cap = size
cast[ptr NimStrPayloadBase](head(p))[].cap = size
template len(s: NimStringV3): int = s.rawlen shr 1
@@ -41,24 +45,25 @@ proc markIntern(s: var NimStringV3): bool =
s.rawlen = s.rawlen or 1
result = not isLiteral(s)
proc unsafeUnmarkIntern(s: NimStringV3) =
proc unsafeUnmarkIntern(s: var NimStringV3) =
s.rawlen = s.rawlen and (not 1) # unmark?
when compileOption("threads"):
deallocShared(s.p -% sizeof(NimStrPayloadBase))
deallocShared(head(s.p))
else:
dealloc(s.p -% sizeof(NimStrPayloadBase))
dealloc(head(s.p))
template contentSize(cap): int = cap + sizeof(NimStrPayloadBase)
template frees(s) =
if not isLiteral(s):
when compileOption("threads"):
deallocShared(s.p -% sizeof(NimStrPayloadBase))
deallocShared(head(s.p))
else:
dealloc(s.p -% sizeof(NimStrPayloadBase))
dealloc(head(s.p))
template allocPayload(newLen: int): ptr UncheckedArray[char] =
when compileOption("threads"):
cast[ptr UncheckedArray[char]](allocShared(contentSize(newLen) +! sizeof(NimStrPayloadBase)))
cast[ptr UncheckedArray[char]](allocShared(contentSize(newLen)) +! sizeof(NimStrPayloadBase))
else:
cast[ptr UncheckedArray[char]](alloc(contentSize(newLen)) +! sizeof(NimStrPayloadBase))
@@ -99,10 +104,9 @@ proc prepareAdd(s: var NimStringV3; addLen: int) {.compilerRtl.} =
let oldCap = s.p.cap
if newLen > oldCap:
let newCap = max(newLen, resize(oldCap))
s.p = reallocPayload(s.p -% sizeof(NimStrPayloadBase), newCap)
s.p = reallocPayload(head(s.p), newCap)
s.p.cap = newCap
if newLen < newCap:
## TODO: be careful with off by one
zeroMem(cast[pointer](addr s.p[newLen]), newCap - newLen)
proc nimAddCharV1(s: var NimStringV3; c: char) {.compilerRtl, inl.} =
@@ -139,6 +143,7 @@ proc appendString(dest: var NimStringV3; src: NimStringV3) {.compilerproc, inlin
proc appendChar(dest: var NimStringV3; c: char) {.compilerproc, inline.} =
dest.p[dest.len] = c
incRawLen(dest)
proc rawNewString(space: int): NimStringV3 {.compilerproc.} =
# this is also 'system.newStringOfCap'.
@@ -169,15 +174,13 @@ proc setLengthStrV2(s: var NimStringV3, newLen: int) {.compilerRtl.} =
copyMem(unsafeAddr s.p[0], unsafeAddr oldP[0], min(s.len, newLen))
if newLen > s.len:
zeroMem(cast[pointer](addr s.p[s.len]), newLen - s.len)
# else:
# s.p.data[newLen] = '\0'
else:
zeroMem(cast[pointer](addr s.p[0]), newLen)
elif newLen > s.len:
let oldCap = s.p.cap
if newLen > oldCap:
let newCap = max(newLen, resize(oldCap))
s.p = reallocPayload0(s.p -% sizeof(NimStrPayloadBase), oldCap, newCap)
s.p = reallocPayload0(head(s.p), oldCap, newCap)
s.p.cap = newCap
s.rawlen = toRawLen(newLen)