merge devel

This commit is contained in:
Andrii Riabushenko 2018-11-29 23:41:38 +00:00
commit 4c327d9ae2
8 changed files with 73 additions and 45 deletions

View file

@ -241,7 +241,7 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# (for objects, etc.): # (for objects, etc.):
if p.config.selectedGC == gcDestructors: if p.config.selectedGC == gcDestructors:
linefmt(p, cpsStmts, linefmt(p, cpsStmts,
"$1.len = $2.len; $1.p = $2.p;$n", "$1 = $2;$n",
rdLoc(dest), rdLoc(src)) rdLoc(dest), rdLoc(src))
elif needToCopy notin flags or elif needToCopy notin flags or
tfShallow in skipTypes(dest.t, abstractVarRange).flags: tfShallow in skipTypes(dest.t, abstractVarRange).flags:
@ -1339,9 +1339,17 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) =
getTemp(p, n.typ, tmp) getTemp(p, n.typ, tmp)
elif d.k == locNone: elif d.k == locNone:
getTemp(p, n.typ, d) getTemp(p, n.typ, d)
# generate call to newSeq before adding the elements per hand:
genNewSeqAux(p, dest[], intLiteral(sonsLen(n)), let l = intLiteral(sonsLen(n))
optNilSeqs notin p.options and n.len == 0) if p.config.selectedGC == gcDestructors:
let seqtype = n.typ
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
rdLoc dest[], l, getTypeDesc(p.module, seqtype.lastSon),
getSeqPayloadType(p.module, seqtype))
else:
# generate call to newSeq before adding the elements per hand:
genNewSeqAux(p, dest[], l,
optNilSeqs notin p.options and n.len == 0)
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
initLoc(arr, locExpr, n[i], OnHeap) initLoc(arr, locExpr, n[i], OnHeap)
arr.r = ropecg(p.module, "$1$3[$2]", rdLoc(dest[]), intLiteral(i), dataField(p)) arr.r = ropecg(p.module, "$1$3[$2]", rdLoc(dest[]), intLiteral(i), dataField(p))
@ -1364,7 +1372,13 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
getTemp(p, n.typ, d) getTemp(p, n.typ, d)
# generate call to newSeq before adding the elements per hand: # generate call to newSeq before adding the elements per hand:
let L = int(lengthOrd(p.config, n.sons[1].typ)) let L = int(lengthOrd(p.config, n.sons[1].typ))
genNewSeqAux(p, d, intLiteral(L), optNilSeqs notin p.options and L == 0) if p.config.selectedGC == gcDestructors:
let seqtype = n.typ
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
rdLoc d, rope L, getTypeDesc(p.module, seqtype.lastSon),
getSeqPayloadType(p.module, seqtype))
else:
genNewSeqAux(p, d, intLiteral(L), optNilSeqs notin p.options and L == 0)
initLocExpr(p, n.sons[1], a) initLocExpr(p, n.sons[1], a)
# bug #5007; do not produce excessive C source code: # bug #5007; do not produce excessive C source code:
if L < 10: if L < 10:

View file

@ -54,7 +54,7 @@ proc genStringLiteralV1(m: BModule; n: PNode): Rope =
proc genStringLiteralDataOnlyV2(m: BModule, s: string): Rope = proc genStringLiteralDataOnlyV2(m: BModule, s: string): Rope =
result = getTempName(m) result = getTempName(m)
addf(m.s[cfsData], "static const struct {$n" & addf(m.s[cfsData], "static const struct {$n" &
" NI cap; void* allocator; NIM_CHAR data[$2];$n" & " NI cap; void* allocator; NIM_CHAR data[$2+1];$n" &
"} $1 = { $2, NIM_NIL, $3 };$n", "} $1 = { $2, NIM_NIL, $3 };$n",
[result, rope(len(s)), makeCString(s)]) [result, rope(len(s)), makeCString(s)])

View file

@ -117,7 +117,7 @@ Remarks: Rule 1.2 is not yet implemented because ``sink`` is currently
import import
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
strutils, options, dfa, lowerings, tables, modulegraphs, strutils, options, dfa, lowerings, tables, modulegraphs,
lineinfos lineinfos, parampatterns
const const
InterestingSyms = {skVar, skResult, skLet} InterestingSyms = {skVar, skResult, skLet}
@ -262,7 +262,7 @@ template interestingSym(s: PSym): bool =
s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ) s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ)
template isUnpackedTuple(s: PSym): bool = template isUnpackedTuple(s: PSym): bool =
## we move out all elements of unpacked tuples, ## we move out all elements of unpacked tuples,
## hence unpacked tuples themselves don't need to be destroyed ## hence unpacked tuples themselves don't need to be destroyed
s.kind == skTemp and s.typ.kind == tyTuple s.kind == skTemp and s.typ.kind == tyTuple
@ -402,9 +402,10 @@ proc passCopyToSink(n: PNode; c: var Con): PNode =
var m = genCopy(c, n.typ, tmp, n) var m = genCopy(c, n.typ, tmp, n)
m.add p(n, c) m.add p(n, c)
result.add m result.add m
message(c.graph.config, n.info, hintPerformance, if isLValue(n):
("passing '$1' to a sink parameter introduces an implicit copy; " & message(c.graph.config, n.info, hintPerformance,
"use 'move($1)' to prevent it") % $n) ("passing '$1' to a sink parameter introduces an implicit copy; " &
"use 'move($1)' to prevent it") % $n)
else: else:
result.add newTree(nkAsgn, tmp, p(n, c)) result.add newTree(nkAsgn, tmp, p(n, c))
result.add tmp result.add tmp

View file

@ -1728,7 +1728,7 @@ proc processMagicType(c: PContext, m: PSym) =
of mBool: setMagicType(c.config, m, tyBool, 1) of mBool: setMagicType(c.config, m, tyBool, 1)
of mChar: setMagicType(c.config, m, tyChar, 1) of mChar: setMagicType(c.config, m, tyChar, 1)
of mString: of mString:
setMagicType(c.config, m, tyString, c.config.target.ptrSize) setMagicType(c.config, m, tyString, szUncomputedSize)
rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar)) rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar))
when false: when false:
if c.config.selectedGc == gcDestructors: if c.config.selectedGc == gcDestructors:
@ -1758,28 +1758,28 @@ proc processMagicType(c: PContext, m: PSym) =
of mVoidType: of mVoidType:
setMagicType(c.config, m, tyVoid, 0) setMagicType(c.config, m, tyVoid, 0)
of mArray: of mArray:
setMagicType(c.config, m, tyArray, 0) setMagicType(c.config, m, tyArray, szUncomputedSize)
of mOpenArray: of mOpenArray:
setMagicType(c.config, m, tyOpenArray, 0) setMagicType(c.config, m, tyOpenArray, szUncomputedSize)
of mVarargs: of mVarargs:
setMagicType(c.config, m, tyVarargs, 0) setMagicType(c.config, m, tyVarargs, szUncomputedSize)
of mRange: of mRange:
setMagicType(c.config, m, tyRange, 0) setMagicType(c.config, m, tyRange, szUncomputedSize)
rawAddSon(m.typ, newTypeS(tyNone, c)) rawAddSon(m.typ, newTypeS(tyNone, c))
of mSet: of mSet:
setMagicType(c.config, m, tySet, 0) setMagicType(c.config, m, tySet, szUncomputedSize)
of mUncheckedArray: of mUncheckedArray:
setMagicType(c.config, m, tyUncheckedArray, 0) setMagicType(c.config, m, tyUncheckedArray, szUncomputedSize)
of mSeq: of mSeq:
setMagicType(c.config, m, tySequence, 0) setMagicType(c.config, m, tySequence, szUncomputedSize)
if c.config.selectedGc == gcDestructors: if c.config.selectedGc == gcDestructors:
incl m.typ.flags, tfHasAsgn incl m.typ.flags, tfHasAsgn
assert c.graph.sysTypes[tySequence] == nil assert c.graph.sysTypes[tySequence] == nil
c.graph.sysTypes[tySequence] = m.typ c.graph.sysTypes[tySequence] = m.typ
of mOpt: of mOpt:
setMagicType(c.config, m, tyOpt, 0) setMagicType(c.config, m, tyOpt, szUncomputedSize)
of mOrdinal: of mOrdinal:
setMagicType(c.config, m, tyOrdinal, 0) setMagicType(c.config, m, tyOrdinal, szUncomputedSize)
rawAddSon(m.typ, newTypeS(tyNone, c)) rawAddSon(m.typ, newTypeS(tyNone, c))
of mPNimrodNode: of mPNimrodNode:
incl m.typ.flags, tfTriggersCompileTime incl m.typ.flags, tfTriggersCompileTime
@ -1787,7 +1787,7 @@ proc processMagicType(c: PContext, m: PSym) =
of mBuiltinType: of mBuiltinType:
case m.name.s case m.name.s
of "lent": setMagicType(c.config, m, tyLent, c.config.target.ptrSize) of "lent": setMagicType(c.config, m, tyLent, c.config.target.ptrSize)
of "sink": setMagicType(c.config, m, tySink, 0) of "sink": setMagicType(c.config, m, tySink, szUncomputedSize)
else: localError(c.config, m.info, errTypeExpected) else: localError(c.config, m.info, errTypeExpected)
else: localError(c.config, m.info, errTypeExpected) else: localError(c.config, m.info, errTypeExpected)

View file

@ -220,7 +220,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
typ.align = int16(conf.target.ptrSize) typ.align = int16(conf.target.ptrSize)
of tyString: of tyString:
if tfHasAsgn in typ.flags: if conf.selectedGC == gcDestructors:
typ.size = conf.target.ptrSize * 2 typ.size = conf.target.ptrSize * 2
else: else:
typ.size = conf.target.ptrSize typ.size = conf.target.ptrSize
@ -243,7 +243,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
return return
typ.align = int16(conf.target.ptrSize) typ.align = int16(conf.target.ptrSize)
if typ.kind == tySequence and tfHasAsgn in typ.flags: if typ.kind == tySequence and conf.selectedGC == gcDestructors:
typ.size = conf.target.ptrSize * 2 typ.size = conf.target.ptrSize * 2
else: else:
typ.size = conf.target.ptrSize typ.size = conf.target.ptrSize

View file

@ -11,19 +11,36 @@ type
AllocatorFlag* {.pure.} = enum ## flags describing the properties of the allocator AllocatorFlag* {.pure.} = enum ## flags describing the properties of the allocator
ThreadLocal ## the allocator is thread local only. ThreadLocal ## the allocator is thread local only.
ZerosMem ## the allocator always zeros the memory on an allocation 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.} alloc*: proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall.}
dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall.} dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall.}
realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall.} realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall.}
deallocAll*: proc (a: Allocator) {.nimcall.} deallocAll*: proc (a: Allocator) {.nimcall.}
flags*: set[AllocatorFlag] flags*: set[AllocatorFlag]
allocCount: int
deallocCount: int
var var
localAllocator {.threadvar.}: Allocator localAllocator {.threadvar.}: Allocator
sharedAllocator: Allocator sharedAllocator: Allocator
allocatorStorage {.threadvar.}: AllocatorObj
proc getLocalAllocator*(): Allocator = proc getLocalAllocator*(): Allocator =
result = localAllocator 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) = proc setLocalAllocator*(a: Allocator) =
localAllocator = a localAllocator = a
@ -34,15 +51,6 @@ proc getSharedAllocator*(): Allocator =
proc setSharedAllocator*(a: Allocator) = proc setSharedAllocator*(a: Allocator) =
sharedAllocator = a sharedAllocator = a
when false: proc allocCounters*(): (int, int) =
proc alloc*(size: int; alignment: int = 8): pointer = let a = getLocalAllocator()
let a = getCurrentAllocator() result = (a.allocCount, a.deallocCount)
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)

View file

@ -85,7 +85,7 @@ type
proc newSeqPayload(cap, elemSize: int): pointer {.compilerRtl.} = proc newSeqPayload(cap, elemSize: int): pointer {.compilerRtl.} =
# we have to use type erasure here as Nim does not support generic # we have to use type erasure here as Nim does not support generic
# compilerProcs. Oh well, this will all be inlined anyway. # compilerProcs. Oh well, this will all be inlined anyway.
if cap <= 0: if cap > 0:
let region = getLocalAllocator() let region = getLocalAllocator()
var p = cast[ptr PayloadBase](region.alloc(region, cap * elemSize + sizeof(int) + sizeof(Allocator))) var p = cast[ptr PayloadBase](region.alloc(region, cap * elemSize + sizeof(int) + sizeof(Allocator)))
p.region = region p.region = region
@ -126,18 +126,19 @@ proc grow*[T](x: var seq[T]; newLen: Natural; value: T) =
let oldLen = x.len let oldLen = x.len
if newLen <= oldLen: return if newLen <= oldLen: return
var xu = cast[ptr NimSeqV2[T]](addr x) var xu = cast[ptr NimSeqV2[T]](addr x)
if xu.p == nil or xu.p.cap < newLen:
xu.p = cast[typeof(xu.p)](prepareSeqAdd(oldLen, xu.p, newLen - oldLen, sizeof(T))) xu.p = cast[typeof(xu.p)](prepareSeqAdd(oldLen, xu.p, newLen - oldLen, sizeof(T)))
xu.len = newLen xu.len = newLen
for i in oldLen .. newLen-1: for i in oldLen .. newLen-1:
xu.p.data[i] = value xu.p.data[i] = value
proc setLen[T](s: var seq[T], newlen: Natural) = proc setLen[T](s: var seq[T], newlen: Natural) =
if newlen < s.len: {.noSideEffect.}:
shrink(s, newLen) if newlen < s.len:
else: shrink(s, newLen)
var v: T # get the default value of 'v' else:
grow(s, newLen, v) var v: T # get the default value of 'v'
grow(s, newLen, v)
when false: when false:
proc resize[T](s: var NimSeqV2[T]) = proc resize[T](s: var NimSeqV2[T]) =

View file

@ -4209,6 +4209,10 @@ when hasAlloc and not defined(nimscript) and not defined(JS) and
## for the implementation of ``spawn``. ## for the implementation of ``spawn``.
discard discard
proc deepCopy*[T](y: T): T =
## Convenience wrapper around `deepCopy` overload.
deepCopy(result, y)
include "system/deepcopy" include "system/deepcopy"
proc procCall*(x: untyped) {.magic: "ProcCall", compileTime.} = proc procCall*(x: untyped) {.magic: "ProcCall", compileTime.} =