compiler takes advantage of 'new(Obj|New)RC1
This commit is contained in:
parent
98ed7fbf16
commit
3c53c4c2b0
3 changed files with 89 additions and 77 deletions
|
|
@ -899,25 +899,96 @@ proc genNew(p: BProc, e: PNode) =
|
||||||
refType = skipTypes(e.sons[1].typ, abstractVarRange)
|
refType = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
InitLocExpr(p, e.sons[1], a)
|
InitLocExpr(p, e.sons[1], a)
|
||||||
initLoc(b, locExpr, a.t, OnHeap)
|
initLoc(b, locExpr, a.t, OnHeap)
|
||||||
b.r = ropecg(p.module,
|
let args = [getTypeDesc(p.module, reftype),
|
||||||
"($1) #newObj($2, sizeof($3))", [getTypeDesc(p.module, reftype),
|
genTypeInfo(p.module, refType),
|
||||||
genTypeInfo(p.module, refType),
|
getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))]
|
||||||
getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])
|
if a.s == OnHeap and optRefcGc in gGlobalOptions:
|
||||||
genAssignment(p, a, b, {needToKeepAlive}) # set the object type:
|
# use newObjRC1 as an optimization; and we don't need 'keepAlive' either
|
||||||
|
appcg(p, cpsStmts, "if ($1) #nimGCunref($1);$n", a.rdLoc)
|
||||||
|
b.r = ropecg(p.module, "($1) #newObjRC1($2, sizeof($3))", args)
|
||||||
|
appcg(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc)
|
||||||
|
else:
|
||||||
|
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", args)
|
||||||
|
genAssignment(p, a, b, {needToKeepAlive}) # set the object type:
|
||||||
bt = skipTypes(refType.sons[0], abstractRange)
|
bt = skipTypes(refType.sons[0], abstractRange)
|
||||||
genObjectInit(p, cpsStmts, bt, a, false)
|
genObjectInit(p, cpsStmts, bt, a, false)
|
||||||
|
|
||||||
|
proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) =
|
||||||
|
let seqtype = skipTypes(dest.t, abstractVarRange)
|
||||||
|
let args = [getTypeDesc(p.module, seqtype),
|
||||||
|
genTypeInfo(p.module, seqType), length]
|
||||||
|
var call: TLoc
|
||||||
|
initLoc(call, locExpr, dest.t, OnHeap)
|
||||||
|
if dest.s == OnHeap and optRefcGc in gGlobalOptions:
|
||||||
|
appcg(p, cpsStmts, "if ($1) #nimGCunref($1);$n", dest.rdLoc)
|
||||||
|
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
|
||||||
|
appcg(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
|
||||||
|
else:
|
||||||
|
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
|
||||||
|
genAssignment(p, dest, call, {needToKeepAlive})
|
||||||
|
|
||||||
proc genNewSeq(p: BProc, e: PNode) =
|
proc genNewSeq(p: BProc, e: PNode) =
|
||||||
var
|
var a, b: TLoc
|
||||||
a, b, c: TLoc
|
|
||||||
var seqType = skipTypes(e.sons[1].typ, abstractVarRange)
|
|
||||||
InitLocExpr(p, e.sons[1], a)
|
InitLocExpr(p, e.sons[1], a)
|
||||||
InitLocExpr(p, e.sons[2], b)
|
InitLocExpr(p, e.sons[2], b)
|
||||||
initLoc(c, locExpr, a.t, OnHeap)
|
genNewSeqAux(p, a, b.rdLoc)
|
||||||
c.r = ropecg(p.module, "($1) #newSeq($2, $3)", [
|
|
||||||
getTypeDesc(p.module, seqtype),
|
proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
|
||||||
genTypeInfo(p.module, seqType), rdLoc(b)])
|
var arr: TLoc
|
||||||
genAssignment(p, a, c, {needToKeepAlive})
|
if d.k == locNone:
|
||||||
|
getTemp(p, t.typ, d)
|
||||||
|
# generate call to newSeq before adding the elements per hand:
|
||||||
|
genNewSeqAux(p, d, intLiteral(sonsLen(t)))
|
||||||
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
|
initLoc(arr, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap)
|
||||||
|
arr.r = ropef("$1->data[$2]", [rdLoc(d), intLiteral(i)])
|
||||||
|
arr.s = OnHeap # we know that sequences are on the heap
|
||||||
|
expr(p, t.sons[i], arr)
|
||||||
|
|
||||||
|
proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
|
||||||
|
var elem, a, arr: TLoc
|
||||||
|
if t.kind == nkBracket:
|
||||||
|
t.sons[1].typ = t.typ
|
||||||
|
genSeqConstr(p, t.sons[1], d)
|
||||||
|
return
|
||||||
|
if d.k == locNone:
|
||||||
|
getTemp(p, t.typ, d)
|
||||||
|
# generate call to newSeq before adding the elements per hand:
|
||||||
|
var L = int(lengthOrd(t.sons[1].typ))
|
||||||
|
|
||||||
|
genNewSeqAux(p, d, intLiteral(L))
|
||||||
|
initLocExpr(p, t.sons[1], a)
|
||||||
|
for i in countup(0, L - 1):
|
||||||
|
initLoc(elem, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap)
|
||||||
|
elem.r = ropef("$1->data[$2]", [rdLoc(d), intLiteral(i)])
|
||||||
|
elem.s = OnHeap # we know that sequences are on the heap
|
||||||
|
initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s)
|
||||||
|
arr.r = ropef("$1[$2]", [rdLoc(a), intLiteral(i)])
|
||||||
|
genAssignment(p, elem, arr, {afDestIsNil, needToCopy})
|
||||||
|
|
||||||
|
proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
|
var
|
||||||
|
a, b, f: TLoc
|
||||||
|
refType, bt: PType
|
||||||
|
ti: PRope
|
||||||
|
oldModule: BModule
|
||||||
|
refType = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
|
InitLocExpr(p, e.sons[1], a)
|
||||||
|
# This is a little hack:
|
||||||
|
# XXX this is also a bug, if the finalizer expression produces side-effects
|
||||||
|
oldModule = p.module
|
||||||
|
p.module = gNimDat
|
||||||
|
InitLocExpr(p, e.sons[2], f)
|
||||||
|
p.module = oldModule
|
||||||
|
initLoc(b, locExpr, a.t, OnHeap)
|
||||||
|
ti = genTypeInfo(p.module, refType)
|
||||||
|
appf(gNimDat.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
|
||||||
|
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
|
||||||
|
getTypeDesc(p.module, refType),
|
||||||
|
ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])
|
||||||
|
genAssignment(p, a, b, {needToKeepAlive}) # set the object type:
|
||||||
|
bt = skipTypes(refType.sons[0], abstractRange)
|
||||||
|
genObjectInit(p, cpsStmts, bt, a, false)
|
||||||
|
|
||||||
proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
|
|
@ -945,30 +1016,6 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
genOf(p, n.sons[1], n.sons[2].typ, d)
|
genOf(p, n.sons[1], n.sons[2].typ, d)
|
||||||
|
|
||||||
proc genNewFinalize(p: BProc, e: PNode) =
|
|
||||||
var
|
|
||||||
a, b, f: TLoc
|
|
||||||
refType, bt: PType
|
|
||||||
ti: PRope
|
|
||||||
oldModule: BModule
|
|
||||||
refType = skipTypes(e.sons[1].typ, abstractVarRange)
|
|
||||||
InitLocExpr(p, e.sons[1], a)
|
|
||||||
# This is a little hack:
|
|
||||||
# XXX this is also a bug, if the finalizer expression produces side-effects
|
|
||||||
oldModule = p.module
|
|
||||||
p.module = gNimDat
|
|
||||||
InitLocExpr(p, e.sons[2], f)
|
|
||||||
p.module = oldModule
|
|
||||||
initLoc(b, locExpr, a.t, OnHeap)
|
|
||||||
ti = genTypeInfo(p.module, refType)
|
|
||||||
appf(gNimDat.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
|
|
||||||
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
|
|
||||||
getTypeDesc(p.module, refType),
|
|
||||||
ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])
|
|
||||||
genAssignment(p, a, b, {needToKeepAlive}) # set the object type:
|
|
||||||
bt = skipTypes(refType.sons[0], abstractRange)
|
|
||||||
genObjectInit(p, cpsStmts, bt, a, false)
|
|
||||||
|
|
||||||
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# XXX we don't generate keep alive info for now here
|
# XXX we don't generate keep alive info for now here
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
|
|
@ -1277,46 +1324,6 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
|
||||||
else:
|
else:
|
||||||
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
||||||
|
|
||||||
proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
|
|
||||||
var newSeq, arr: TLoc
|
|
||||||
if d.k == locNone:
|
|
||||||
getTemp(p, t.typ, d)
|
|
||||||
# generate call to newSeq before adding the elements per hand:
|
|
||||||
initLoc(newSeq, locExpr, t.typ, OnHeap)
|
|
||||||
newSeq.r = ropecg(p.module, "($1) #newSeq($2, $3)",
|
|
||||||
[getTypeDesc(p.module, t.typ),
|
|
||||||
genTypeInfo(p.module, t.typ), intLiteral(sonsLen(t))])
|
|
||||||
genAssignment(p, d, newSeq, {afSrcIsNotNil, needToKeepAlive})
|
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
|
||||||
initLoc(arr, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap)
|
|
||||||
arr.r = ropef("$1->data[$2]", [rdLoc(d), intLiteral(i)])
|
|
||||||
arr.s = OnHeap # we know that sequences are on the heap
|
|
||||||
expr(p, t.sons[i], arr)
|
|
||||||
|
|
||||||
proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
|
|
||||||
var newSeq, elem, a, arr: TLoc
|
|
||||||
if t.kind == nkBracket:
|
|
||||||
t.sons[1].typ = t.typ
|
|
||||||
genSeqConstr(p, t.sons[1], d)
|
|
||||||
return
|
|
||||||
if d.k == locNone:
|
|
||||||
getTemp(p, t.typ, d)
|
|
||||||
# generate call to newSeq before adding the elements per hand:
|
|
||||||
var L = int(lengthOrd(t.sons[1].typ))
|
|
||||||
initLoc(newSeq, locExpr, t.typ, OnHeap)
|
|
||||||
newSeq.r = ropecg(p.module, "($1) #newSeq($2, $3)",
|
|
||||||
[getTypeDesc(p.module, t.typ),
|
|
||||||
genTypeInfo(p.module, t.typ), intLiteral(L)])
|
|
||||||
genAssignment(p, d, newSeq, {afSrcIsNotNil, needToKeepAlive})
|
|
||||||
initLocExpr(p, t.sons[1], a)
|
|
||||||
for i in countup(0, L - 1):
|
|
||||||
initLoc(elem, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap)
|
|
||||||
elem.r = ropef("$1->data[$2]", [rdLoc(d), intLiteral(i)])
|
|
||||||
elem.s = OnHeap # we know that sequences are on the heap
|
|
||||||
initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s)
|
|
||||||
arr.r = ropef("$1[$2]", [rdLoc(a), intLiteral(i)])
|
|
||||||
genAssignment(p, elem, arr, {afDestIsNil, needToCopy})
|
|
||||||
|
|
||||||
proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
if {optNanCheck, optInfCheck} * p.options != {}:
|
if {optNanCheck, optInfCheck} * p.options != {}:
|
||||||
const opr: array[mAddF64..mDivF64, string] = ["+", "-", "*", "/"]
|
const opr: array[mAddF64..mDivF64, string] = ["+", "-", "*", "/"]
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ proc decRef(c: PCell) {.inline.} =
|
||||||
if --c.refcount:
|
if --c.refcount:
|
||||||
rtlAddZCT(c)
|
rtlAddZCT(c)
|
||||||
elif canBeCycleRoot(c):
|
elif canBeCycleRoot(c):
|
||||||
|
# XXX if 'incRef' does this check, it should be unnecessary in 'decRef'
|
||||||
rtlAddCycleRoot(c)
|
rtlAddCycleRoot(c)
|
||||||
|
|
||||||
proc incRef(c: PCell) {.inline.} =
|
proc incRef(c: PCell) {.inline.} =
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -1,6 +1,10 @@
|
||||||
version 0.8.14
|
version 0.8.14
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
- compiler should generate better code wrt GC
|
||||||
|
- compiler should optimize string creation
|
||||||
|
- marker procs for the GC
|
||||||
|
- need to generate code to prevent tail call optimization
|
||||||
- warning for implicit openArray -> varargs convention
|
- warning for implicit openArray -> varargs convention
|
||||||
- implement explicit varargs; **but** ``len(varargs)`` problem remains!
|
- implement explicit varargs; **but** ``len(varargs)`` problem remains!
|
||||||
--> solve by implicit conversion from varargs to openarray
|
--> solve by implicit conversion from varargs to openarray
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue