more progress on destructor based strings

This commit is contained in:
Andreas Rumpf
2018-07-13 21:15:47 +02:00
parent 5b59852406
commit 74bf316619
16 changed files with 279 additions and 244 deletions

View File

@@ -202,11 +202,6 @@ proc objectInit(dest: pointer, typ: PNimType) =
# ---------------------- assign zero -----------------------------------------
proc nimDestroyRange[T](r: T) {.compilerProc.} =
# internal proc used for destroying sequences and arrays
mixin `=destroy`
for i in countup(0, r.len - 1): `=destroy`(r[i])
proc genericReset(dest: pointer, mt: PNimType) {.compilerProc, benign.}
proc genericResetAux(dest: pointer, n: ptr TNimNode) =
var d = cast[ByteAddress](dest)

View File

@@ -12,7 +12,6 @@
type
LibHandle = pointer # private type
ProcAddr = pointer # library loading and loading of procs:
{.deprecated: [TLibHandle: LibHandle, TProcAddr: ProcAddr].}
proc nimLoadLibrary(path: string): LibHandle {.compilerproc.}
proc nimUnloadLibrary(lib: LibHandle) {.compilerproc.}

View File

@@ -264,12 +264,13 @@ proc forAllChildren(cell: PCell, op: WalkOp) =
of tyRef, tyOptAsRef: # common case
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
of tySequence:
var d = cast[ByteAddress](cellToUsr(cell))
var s = cast[PGenericSeq](d)
if s != nil:
for i in 0..s.len-1:
forAllChildrenAux(cast[pointer](d +% i *% cell.typ.base.size +%
GenericSeqSize), cell.typ.base, op)
when not defined(gcDestructors):
var d = cast[ByteAddress](cellToUsr(cell))
var s = cast[PGenericSeq](d)
if s != nil:
for i in 0..s.len-1:
forAllChildrenAux(cast[pointer](d +% i *% cell.typ.base.size +%
GenericSeqSize), cell.typ.base, op)
else: discard
proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
@@ -310,53 +311,54 @@ proc newObjNoInit(typ: PNimType, size: int): pointer {.compilerRtl.} =
result = rawNewObj(typ, size, gch)
when defined(memProfiler): nimProfile(size)
proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} =
# `newObj` already uses locks, so no need for them here.
let size = addInt(mulInt(len, typ.base.size), GenericSeqSize)
result = newObj(typ, size)
cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).reserved = len
when defined(memProfiler): nimProfile(size)
proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
result = rawNewObj(typ, size, gch)
zeroMem(result, size)
when defined(memProfiler): nimProfile(size)
proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
let size = addInt(mulInt(len, typ.base.size), GenericSeqSize)
result = newObj(typ, size)
cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).reserved = len
when defined(memProfiler): nimProfile(size)
when not defined(gcDestructors):
proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} =
# `newObj` already uses locks, so no need for them here.
let size = addInt(mulInt(len, typ.base.size), GenericSeqSize)
result = newObj(typ, size)
cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).reserved = len
when defined(memProfiler): nimProfile(size)
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
acquire(gch)
collectCT(gch, newsize + sizeof(Cell))
var ol = usrToCell(old)
sysAssert(ol.typ != nil, "growObj: 1")
gcAssert(ol.typ.kind in {tyString, tySequence}, "growObj: 2")
proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
let size = addInt(mulInt(len, typ.base.size), GenericSeqSize)
result = newObj(typ, size)
cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).reserved = len
when defined(memProfiler): nimProfile(size)
var res = cast[PCell](rawAlloc(gch.region, newsize + sizeof(Cell)))
var elemSize = 1
if ol.typ.kind != tyString: elemSize = ol.typ.base.size
incTypeSize ol.typ, newsize
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
acquire(gch)
collectCT(gch, newsize + sizeof(Cell))
var ol = usrToCell(old)
sysAssert(ol.typ != nil, "growObj: 1")
gcAssert(ol.typ.kind in {tyString, tySequence}, "growObj: 2")
var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize
copyMem(res, ol, oldsize + sizeof(Cell))
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(Cell)),
newsize-oldsize)
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
when withBitvectors: incl(gch.allocated, res)
when useCellIds:
inc gch.idGenerator
res.id = gch.idGenerator
release(gch)
result = cellToUsr(res)
when defined(memProfiler): nimProfile(newsize-oldsize)
var res = cast[PCell](rawAlloc(gch.region, newsize + sizeof(Cell)))
var elemSize = 1
if ol.typ.kind != tyString: elemSize = ol.typ.base.size
incTypeSize ol.typ, newsize
proc growObj(old: pointer, newsize: int): pointer {.rtl.} =
result = growObj(old, newsize, gch)
var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize
copyMem(res, ol, oldsize + sizeof(Cell))
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(Cell)),
newsize-oldsize)
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
when withBitvectors: incl(gch.allocated, res)
when useCellIds:
inc gch.idGenerator
res.id = gch.idGenerator
release(gch)
result = cellToUsr(res)
when defined(memProfiler): nimProfile(newsize-oldsize)
proc growObj(old: pointer, newsize: int): pointer {.rtl.} =
result = growObj(old, newsize, gch)
{.push profiler:off.}

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
when declared(NimString):
when declared(ThisIsSystem):
# we are in system module:
{.pragma: codegenType, compilerproc.}
else:

View File

@@ -31,8 +31,6 @@ type
JSRef = ref RootObj # Fake type.
{.deprecated: [TSafePoint: SafePoint, TCallFrame: CallFrame].}
var
framePtr {.importc, nodecl, volatile.}: PCallFrame
excHandler {.importc, nodecl, volatile.}: int = 0
@@ -506,7 +504,7 @@ proc chckNilDisp(p: pointer) {.compilerproc.} =
if p == nil:
sysFatal(NilAccessError, "cannot dispatch; dispatcher is nil")
type NimString = string # hack for hti.nim
const ThisIsSystem = true # for hti.nim
include "system/hti"
proc isFatPointer(ti: PNimType): bool =

View File

@@ -554,7 +554,7 @@ else:
else:
include "system/gc"
when not declared(nimNewSeqOfCap):
when not declared(nimNewSeqOfCap) and not defined(gcDestructors):
proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
when defined(gcRegions):
let s = mulInt(cap, typ.base.size) # newStr already adds GenericSeqSize

View File

@@ -148,7 +148,7 @@ proc readLine(f: File, line: var TaintedString): bool =
if line.string.isNil:
line = TaintedString(newStringOfCap(80))
else:
when not defined(nimscript):
when not defined(nimscript) and not defined(gcDestructors):
sp = cint(cast[PGenericSeq](line.string).space)
line.string.setLen(sp)
while true:

View File

@@ -10,13 +10,12 @@
# Nim support for C/C++'s `wide strings`:idx:. This is part of the system
# module! Do not import it directly!
when not declared(NimString):
when not declared(ThisIsSystem):
{.error: "You must not import this module explicitly".}
type
Utf16Char* = distinct int16
WideCString* = ref UncheckedArray[Utf16Char]
{.deprecated: [TUtf16Char: Utf16Char].}
proc len*(w: WideCString): int =
## returns the length of a widestring. This traverses the whole string to