merge devel
This commit is contained in:
commit
4c327d9ae2
8 changed files with 73 additions and 45 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
|
||||||
|
|
@ -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]) =
|
||||||
|
|
|
||||||
|
|
@ -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.} =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue