mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 11:54:11 +00:00
added system.newSeqOfCap for improved efficiency
This commit is contained in:
@@ -545,7 +545,7 @@ type
|
||||
mEcho, mShallowCopy, mSlurp, mStaticExec,
|
||||
mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
|
||||
mUnaryLt, mInc, mDec, mOrd,
|
||||
mNew, mNewFinalize, mNewSeq,
|
||||
mNew, mNewFinalize, mNewSeq, mNewSeqOfCap,
|
||||
mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq,
|
||||
mXLenStr, mXLenSeq,
|
||||
mIncl, mExcl, mCard, mChr,
|
||||
|
||||
@@ -1141,6 +1141,16 @@ proc genNewSeq(p: BProc, e: PNode) =
|
||||
genNewSeqAux(p, a, b.rdLoc)
|
||||
gcUsage(e)
|
||||
|
||||
proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
|
||||
let seqtype = skipTypes(e.typ, abstractVarRange)
|
||||
var a: TLoc
|
||||
initLocExpr(p, e.sons[1], a)
|
||||
putIntoDest(p, d, e.typ, ropecg(p.module,
|
||||
"($1)#nimNewSeqOfCap($2, $3)", [
|
||||
getTypeDesc(p.module, seqtype),
|
||||
genTypeInfo(p.module, seqtype), a.rdLoc]))
|
||||
gcUsage(e)
|
||||
|
||||
proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
var tmp: TLoc
|
||||
var t = e.typ.skipTypes(abstractInst)
|
||||
@@ -1712,6 +1722,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
of mNew: genNew(p, e)
|
||||
of mNewFinalize: genNewFinalize(p, e)
|
||||
of mNewSeq: genNewSeq(p, e)
|
||||
of mNewSeqOfCap: genNewSeqOfCap(p, e, d)
|
||||
of mSizeOf:
|
||||
let t = e.sons[1].typ.skipTypes({tyTypeDesc})
|
||||
putIntoDest(p, d, e.typ, "((NI)sizeof($1))" % [getTypeDesc(p.module, t)])
|
||||
|
||||
@@ -1755,6 +1755,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||
else:
|
||||
binaryExpr(p, n, r, "", "isset($1[$2])")
|
||||
of mNewSeq: genNewSeq(p, n)
|
||||
of mNewSeqOfCap: unaryExpr(p, n, r, "", "[]" | "array()")
|
||||
of mOf: genOf(p, n, r)
|
||||
of mReset: genReset(p, n)
|
||||
of mEcho: genEcho(p, n, r)
|
||||
|
||||
@@ -597,16 +597,27 @@ proc genNew(c: PCtx; n: PNode) =
|
||||
c.freeTemp(dest)
|
||||
|
||||
proc genNewSeq(c: PCtx; n: PNode) =
|
||||
let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(n.sons[1].typ)
|
||||
let t = n.sons[1].typ
|
||||
let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(t)
|
||||
else: c.genx(n.sons[1])
|
||||
let tmp = c.genx(n.sons[2])
|
||||
c.gABx(n, opcNewSeq, dest, c.genType(n.sons[1].typ.skipTypes(
|
||||
c.gABx(n, opcNewSeq, dest, c.genType(t.skipTypes(
|
||||
abstractVar-{tyTypeDesc})))
|
||||
c.gABx(n, opcNewSeq, tmp, 0)
|
||||
c.freeTemp(tmp)
|
||||
c.genAsgnPatch(n.sons[1], dest)
|
||||
c.freeTemp(dest)
|
||||
|
||||
proc genNewSeqOfCap(c: PCtx; n: PNode; dest: var TDest) =
|
||||
let t = n.typ
|
||||
let tmp = c.getTemp(n.sons[1].typ)
|
||||
c.gABx(n, opcLdNull, dest, c.genType(t))
|
||||
c.gABx(n, opcLdImmInt, tmp, 0)
|
||||
c.gABx(n, opcNewSeq, dest, c.genType(t.skipTypes(
|
||||
abstractVar-{tyTypeDesc})))
|
||||
c.gABx(n, opcNewSeq, tmp, 0)
|
||||
c.freeTemp(tmp)
|
||||
|
||||
proc genUnaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
||||
let tmp = c.genx(n.sons[1])
|
||||
if dest < 0: dest = c.getTemp(n.typ)
|
||||
@@ -782,6 +793,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||
of mNewSeq:
|
||||
unused(n, dest)
|
||||
c.genNewSeq(n)
|
||||
of mNewSeqOfCap: c.genNewSeqOfCap(n, dest)
|
||||
of mNewString:
|
||||
genUnaryABC(c, n, dest, opcNewStr)
|
||||
# XXX buggy
|
||||
|
||||
@@ -669,6 +669,12 @@ proc newSeq*[T](len = 0.Natural): seq[T] =
|
||||
## #inputStrings[3] = "out of bounds"
|
||||
newSeq(result, len)
|
||||
|
||||
proc newSeqOfCap*[T](cap: Natural): seq[T] {.
|
||||
magic: "NewSeqOfCap", noSideEffect.} =
|
||||
## creates a new sequence of type ``seq[T]`` with length 0 and capacity
|
||||
## ``cap``.
|
||||
discard
|
||||
|
||||
proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.
|
||||
magic: "LengthOpenArray", noSideEffect.}
|
||||
proc len*(x: string): int {.magic: "LengthStr", noSideEffect.}
|
||||
|
||||
@@ -354,6 +354,12 @@ elif defined(gogc):
|
||||
cast[PGenericSeq](result).reserved = len
|
||||
cast[PGenericSeq](result).elemSize = typ.base.size
|
||||
|
||||
proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
|
||||
result = newObj(typ, cap * typ.base.size + GenericSeqSize)
|
||||
cast[PGenericSeq](result).len = 0
|
||||
cast[PGenericSeq](result).reserved = cap
|
||||
cast[PGenericSeq](result).elemSize = typ.base.size
|
||||
|
||||
proc growObj(old: pointer, newsize: int): pointer =
|
||||
# the Go GC doesn't have a realloc
|
||||
var
|
||||
@@ -447,6 +453,7 @@ elif defined(nogc) and defined(useMalloc):
|
||||
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
|
||||
cast[PGenericSeq](result).len = len
|
||||
cast[PGenericSeq](result).reserved = len
|
||||
|
||||
proc newObjNoInit(typ: PNimType, size: int): pointer =
|
||||
result = alloc(size)
|
||||
|
||||
@@ -506,6 +513,7 @@ elif defined(nogc):
|
||||
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
|
||||
cast[PGenericSeq](result).len = len
|
||||
cast[PGenericSeq](result).reserved = len
|
||||
|
||||
proc growObj(old: pointer, newsize: int): pointer =
|
||||
result = realloc(old, newsize)
|
||||
|
||||
@@ -545,4 +553,10 @@ else:
|
||||
else:
|
||||
include "system/gc"
|
||||
|
||||
when not declared(nimNewSeqOfCap):
|
||||
proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
|
||||
result = newObj(typ, addInt(mulInt(cap, typ.base.size), GenericSeqSize))
|
||||
cast[PGenericSeq](result).len = 0
|
||||
cast[PGenericSeq](result).reserved = cap
|
||||
|
||||
{.pop.}
|
||||
|
||||
Reference in New Issue
Block a user