ARC: optimize complete object constructors to use nimNewObjUninit
This commit is contained in:
parent
ab35f07e77
commit
a10cc18247
5 changed files with 40 additions and 12 deletions
|
|
@ -1001,6 +1001,8 @@ const
|
||||||
resultPos* = 7
|
resultPos* = 7
|
||||||
dispatcherPos* = 8
|
dispatcherPos* = 8
|
||||||
|
|
||||||
|
nfAllFieldsSet* = nfBase2
|
||||||
|
|
||||||
nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
|
nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
|
||||||
nkCommand, nkCallStrLit, nkHiddenCallConv}
|
nkCommand, nkCallStrLit, nkHiddenCallConv}
|
||||||
nkIdentKinds* = {nkIdent, nkSym, nkAccQuoted, nkOpenSymChoice,
|
nkIdentKinds* = {nkIdent, nkSym, nkAccQuoted, nkOpenSymChoice,
|
||||||
|
|
|
||||||
|
|
@ -1197,7 +1197,7 @@ proc genDefault(p: BProc; n: PNode; d: var TLoc) =
|
||||||
if d.k == locNone: getTemp(p, n.typ, d, needsInit=true)
|
if d.k == locNone: getTemp(p, n.typ, d, needsInit=true)
|
||||||
else: resetLoc(p, d)
|
else: resetLoc(p, d)
|
||||||
|
|
||||||
proc rawGenNew(p: BProc, a: var TLoc, sizeExpr: Rope) =
|
proc rawGenNew(p: BProc, a: var TLoc, sizeExpr: Rope; needsInit: bool) =
|
||||||
var sizeExpr = sizeExpr
|
var sizeExpr = sizeExpr
|
||||||
let typ = a.t
|
let typ = a.t
|
||||||
var b: TLoc
|
var b: TLoc
|
||||||
|
|
@ -1209,8 +1209,12 @@ proc rawGenNew(p: BProc, a: var TLoc, sizeExpr: Rope) =
|
||||||
sizeExpr = "sizeof($1)" % [getTypeDesc(p.module, bt)]
|
sizeExpr = "sizeof($1)" % [getTypeDesc(p.module, bt)]
|
||||||
|
|
||||||
if optTinyRtti in p.config.globalOptions:
|
if optTinyRtti in p.config.globalOptions:
|
||||||
b.r = ropecg(p.module, "($1) #nimNewObj($2)",
|
if needsInit:
|
||||||
[getTypeDesc(p.module, typ), sizeExpr])
|
b.r = ropecg(p.module, "($1) #nimNewObj($2)",
|
||||||
|
[getTypeDesc(p.module, typ), sizeExpr])
|
||||||
|
else:
|
||||||
|
b.r = ropecg(p.module, "($1) #nimNewObjUninit($2)",
|
||||||
|
[getTypeDesc(p.module, typ), sizeExpr])
|
||||||
genAssignment(p, a, b, {})
|
genAssignment(p, a, b, {})
|
||||||
else:
|
else:
|
||||||
let ti = genTypeInfo(p.module, typ, a.lode.info)
|
let ti = genTypeInfo(p.module, typ, a.lode.info)
|
||||||
|
|
@ -1254,9 +1258,9 @@ proc genNew(p: BProc, e: PNode) =
|
||||||
if e.len == 3:
|
if e.len == 3:
|
||||||
var se: TLoc
|
var se: TLoc
|
||||||
initLocExpr(p, e[2], se)
|
initLocExpr(p, e[2], se)
|
||||||
rawGenNew(p, a, se.rdLoc)
|
rawGenNew(p, a, se.rdLoc, needsInit = true)
|
||||||
else:
|
else:
|
||||||
rawGenNew(p, a, nil)
|
rawGenNew(p, a, nil, needsInit = true)
|
||||||
gcUsage(p.config, e)
|
gcUsage(p.config, e)
|
||||||
|
|
||||||
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope; lenIsZero: bool) =
|
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope; lenIsZero: bool) =
|
||||||
|
|
@ -1356,7 +1360,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
getTemp(p, t, tmp)
|
getTemp(p, t, tmp)
|
||||||
r = rdLoc(tmp)
|
r = rdLoc(tmp)
|
||||||
if isRef:
|
if isRef:
|
||||||
rawGenNew(p, tmp, nil)
|
rawGenNew(p, tmp, nil, needsInit = nfAllFieldsSet notin e.flags)
|
||||||
t = t.lastSon.skipTypes(abstractInstOwned)
|
t = t.lastSon.skipTypes(abstractInstOwned)
|
||||||
r = "(*$1)" % [r]
|
r = "(*$1)" % [r]
|
||||||
gcUsage(p.config, e)
|
gcUsage(p.config, e)
|
||||||
|
|
@ -2180,7 +2184,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
if optTinyRtti in p.config.globalOptions:
|
if optTinyRtti in p.config.globalOptions:
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, e[1], a)
|
initLocExpr(p, e[1], a)
|
||||||
rawGenNew(p, a, nil)
|
rawGenNew(p, a, nil, needsInit = true)
|
||||||
gcUsage(p.config, e)
|
gcUsage(p.config, e)
|
||||||
else:
|
else:
|
||||||
genNewFinalize(p, e)
|
genNewFinalize(p, e)
|
||||||
|
|
@ -2811,7 +2815,7 @@ proc getNullValueAux(p: BProc; t: PType; obj, constOrNil: PNode,
|
||||||
# else branch
|
# else branch
|
||||||
selectedBranch = i
|
selectedBranch = i
|
||||||
assert(selectedBranch >= 1)
|
assert(selectedBranch >= 1)
|
||||||
|
|
||||||
result.add "{"
|
result.add "{"
|
||||||
var countB = 0
|
var countB = 0
|
||||||
let b = lastSon(obj[selectedBranch])
|
let b = lastSon(obj[selectedBranch])
|
||||||
|
|
@ -2822,10 +2826,10 @@ proc getNullValueAux(p: BProc; t: PType; obj, constOrNil: PNode,
|
||||||
getNullValueAux(p, t, b, constOrNil, result, countB, isConst, info)
|
getNullValueAux(p, t, b, constOrNil, result, countB, isConst, info)
|
||||||
result.add "}"
|
result.add "}"
|
||||||
elif b.kind == nkSym:
|
elif b.kind == nkSym:
|
||||||
result.add "." & mangleRecFieldName(p.module, b.sym) & " = "
|
result.add "." & mangleRecFieldName(p.module, b.sym) & " = "
|
||||||
getNullValueAux(p, t, b, constOrNil, result, countB, isConst, info)
|
getNullValueAux(p, t, b, constOrNil, result, countB, isConst, info)
|
||||||
result.add "}"
|
result.add "}"
|
||||||
|
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if count > 0: result.add ", "
|
if count > 0: result.add ", "
|
||||||
inc count
|
inc count
|
||||||
|
|
|
||||||
|
|
@ -485,7 +485,8 @@ proc cycleCheck(n: PNode; c: var Con) =
|
||||||
break
|
break
|
||||||
|
|
||||||
proc p(n: PNode; c: var Con; mode: ProcessMode): PNode =
|
proc p(n: PNode; c: var Con; mode: ProcessMode): PNode =
|
||||||
if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt, nkIfExpr, nkCaseStmt, nkWhen}:
|
if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt,
|
||||||
|
nkIfExpr, nkCaseStmt, nkWhen}:
|
||||||
handleNested(n): p(node, c, mode)
|
handleNested(n): p(node, c, mode)
|
||||||
elif mode == sinkArg:
|
elif mode == sinkArg:
|
||||||
if n.containsConstSeq:
|
if n.containsConstSeq:
|
||||||
|
|
@ -493,7 +494,8 @@ proc p(n: PNode; c: var Con; mode: ProcessMode): PNode =
|
||||||
# sink parameter (bug #11524). Note that the string implementation is
|
# sink parameter (bug #11524). Note that the string implementation is
|
||||||
# different and can deal with 'const string sunk into var'.
|
# different and can deal with 'const string sunk into var'.
|
||||||
result = passCopyToSink(n, c)
|
result = passCopyToSink(n, c)
|
||||||
elif n.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkClosure} + nkCallKinds + nkLiterals:
|
elif n.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkClosure, nkNilLit} +
|
||||||
|
nkCallKinds + nkLiterals:
|
||||||
result = p(n, c, consumed)
|
result = p(n, c, consumed)
|
||||||
elif n.kind == nkSym and isSinkParam(n.sym):
|
elif n.kind == nkSym and isSinkParam(n.sym):
|
||||||
# Sinked params can be consumed only once. We need to reset the memory
|
# Sinked params can be consumed only once. We need to reset the memory
|
||||||
|
|
|
||||||
|
|
@ -388,3 +388,6 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# 2) No such field exists in the constructed type
|
# 2) No such field exists in the constructed type
|
||||||
localError(c.config, field.info, errUndeclaredFieldX % id.s)
|
localError(c.config, field.info, errUndeclaredFieldX % id.s)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if initResult == initFull:
|
||||||
|
incl result.flags, nfAllFieldsSet
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,23 @@ proc nimNewObj(size: int): pointer {.compilerRtl.} =
|
||||||
when traceCollector:
|
when traceCollector:
|
||||||
cprintf("[Allocated] %p\n", result -! sizeof(RefHeader))
|
cprintf("[Allocated] %p\n", result -! sizeof(RefHeader))
|
||||||
|
|
||||||
|
proc nimNewObjUninit(size: int): pointer {.compilerRtl.} =
|
||||||
|
# Same as 'newNewObj' but do not initialize the memory to zero.
|
||||||
|
# The codegen proved for us that this is not necessary.
|
||||||
|
let s = size + sizeof(RefHeader)
|
||||||
|
when defined(nimscript):
|
||||||
|
discard
|
||||||
|
elif defined(useMalloc):
|
||||||
|
var orig = cast[ptr RefHeader](c_malloc(cuint s))
|
||||||
|
elif compileOption("threads"):
|
||||||
|
var orig = cast[ptr RefHeader](allocShared(s))
|
||||||
|
else:
|
||||||
|
var orig = cast[ptr RefHeader](alloc(s))
|
||||||
|
orig.rc = 0
|
||||||
|
result = orig +! sizeof(RefHeader)
|
||||||
|
when traceCollector:
|
||||||
|
cprintf("[Allocated] %p\n", result -! sizeof(RefHeader))
|
||||||
|
|
||||||
proc nimDecWeakRef(p: pointer) {.compilerRtl, inl.} =
|
proc nimDecWeakRef(p: pointer) {.compilerRtl, inl.} =
|
||||||
dec head(p).rc, rcIncrement
|
dec head(p).rc, rcIncrement
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue