mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
preparations for string optimizations
This commit is contained in:
@@ -373,11 +373,13 @@ static N_INLINE(NI32, float32ToInt32)(float x) {
|
||||
|
||||
#define float64ToInt64(x) ((NI64) (x))
|
||||
|
||||
#define NIM_STRLIT_FLAG ((NU)(1) << ((NIM_INTBITS) - 2)) /* This has to be the same as system.strlitFlag! */
|
||||
|
||||
#define STRING_LITERAL(name, str, length) \
|
||||
static const struct { \
|
||||
TGenericSeq Sup; \
|
||||
NIM_CHAR data[(length) + 1]; \
|
||||
} name = {{length, length}, str}
|
||||
static const struct { \
|
||||
TGenericSeq Sup; \
|
||||
NIM_CHAR data[(length) + 1]; \
|
||||
} name = {{length, (NI) ((NU)length | NIM_STRLIT_FLAG)}, str}
|
||||
|
||||
typedef struct TStringDesc* string;
|
||||
|
||||
|
||||
@@ -409,8 +409,7 @@ when not defined(JS):
|
||||
|
||||
when not defined(JS) and not defined(nimscript):
|
||||
template space(s: PGenericSeq): int {.dirty.} =
|
||||
s.reserved and not seqShallowFlag
|
||||
|
||||
s.reserved and not (seqShallowFlag or strlitFlag)
|
||||
include "system/hti"
|
||||
|
||||
type
|
||||
@@ -1329,6 +1328,9 @@ const
|
||||
## "amd64", "mips", "mipsel", "arm", "arm64", "mips64", "mips64el".
|
||||
|
||||
seqShallowFlag = low(int)
|
||||
strlitFlag = 1 shl (sizeof(int)*8 - 2) # later versions of the codegen \
|
||||
# emit this flag
|
||||
# for string literals, it allows for some optimizations.
|
||||
|
||||
{.push profiler: off.}
|
||||
when defined(nimKnowsNimvm):
|
||||
@@ -3720,7 +3722,9 @@ proc shallow*(s: var string) {.noSideEffect, inline.} =
|
||||
## purposes.
|
||||
when not defined(JS) and not defined(nimscript):
|
||||
var s = cast[PGenericSeq](s)
|
||||
s.reserved = s.reserved or seqShallowFlag
|
||||
# string literals cannot become 'shallow':
|
||||
if (s.reserved and strlitFlag) == 0:
|
||||
s.reserved = s.reserved or seqShallowFlag
|
||||
|
||||
type
|
||||
NimNodeObj = object
|
||||
|
||||
@@ -95,6 +95,11 @@ proc cstrToNimstr(str: cstring): NimString {.compilerRtl.} =
|
||||
if str == nil: NimString(nil)
|
||||
else: toNimStr(str, str.len)
|
||||
|
||||
when defined(nimImmutableStrings):
|
||||
template wasMoved(x: NimString): bool = (x.reserved and seqShallowFlag) != 0
|
||||
else:
|
||||
template wasMoved(x: NimString): bool = false
|
||||
|
||||
proc copyString(src: NimString): NimString {.compilerRtl.} =
|
||||
if src != nil:
|
||||
if (src.reserved and seqShallowFlag) != 0:
|
||||
@@ -103,6 +108,16 @@ proc copyString(src: NimString): NimString {.compilerRtl.} =
|
||||
result = rawNewStringNoInit(src.len)
|
||||
result.len = src.len
|
||||
copyMem(addr(result.data), addr(src.data), src.len + 1)
|
||||
sysAssert((seqShallowFlag and result.reserved) == 0, "copyString")
|
||||
when defined(nimImmutableStrings):
|
||||
if (src.reserved and strlitFlag) != 0:
|
||||
result.reserved = (result.reserved and not strlitFlag) or seqShallowFlag
|
||||
|
||||
proc newOwnedString(src: NimString; n: int): NimString =
|
||||
result = rawNewStringNoInit(n)
|
||||
result.len = n
|
||||
copyMem(addr(result.data), addr(src.data), n)
|
||||
result.data[n] = '\0'
|
||||
|
||||
proc copyStringRC1(src: NimString): NimString {.compilerRtl.} =
|
||||
if src != nil:
|
||||
@@ -116,6 +131,10 @@ proc copyStringRC1(src: NimString): NimString {.compilerRtl.} =
|
||||
result = rawNewStringNoInit(src.len)
|
||||
result.len = src.len
|
||||
copyMem(addr(result.data), addr(src.data), src.len + 1)
|
||||
sysAssert((seqShallowFlag and result.reserved) == 0, "copyStringRC1")
|
||||
when defined(nimImmutableStrings):
|
||||
if (src.reserved and strlitFlag) != 0:
|
||||
result.reserved = (result.reserved and not strlitFlag) or seqShallowFlag
|
||||
|
||||
proc copyDeepString(src: NimString): NimString {.inline.} =
|
||||
if src != nil:
|
||||
@@ -144,6 +163,8 @@ proc addChar(s: NimString, c: char): NimString =
|
||||
result = cast[NimString](growObj(result,
|
||||
sizeof(TGenericSeq) + r + 1))
|
||||
result.reserved = r
|
||||
elif wasMoved(s):
|
||||
result = newOwnedString(s, s.len)
|
||||
result.data[result.len] = c
|
||||
result.data[result.len+1] = '\0'
|
||||
inc(result.len)
|
||||
@@ -180,7 +201,7 @@ proc addChar(s: NimString, c: char): NimString =
|
||||
# s = rawNewString(0);
|
||||
|
||||
proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} =
|
||||
if dest.len + addlen <= dest.space:
|
||||
if dest.len + addlen <= dest.space and not wasMoved(dest):
|
||||
result = dest
|
||||
else: # slow path:
|
||||
var sp = max(resize(dest.space), dest.len + addlen)
|
||||
@@ -201,7 +222,9 @@ proc appendChar(dest: NimString, c: char) {.compilerproc, inline.} =
|
||||
|
||||
proc setLengthStr(s: NimString, newLen: int): NimString {.compilerRtl.} =
|
||||
var n = max(newLen, 0)
|
||||
if n <= s.space:
|
||||
if wasMoved(s):
|
||||
result = newOwnedString(s, n)
|
||||
elif n <= s.space:
|
||||
result = s
|
||||
else:
|
||||
result = resizeString(s, n)
|
||||
|
||||
Reference in New Issue
Block a user