fixes #6403
This commit is contained in:
parent
1c0c9d8959
commit
3936587c06
2 changed files with 26 additions and 15 deletions
|
|
@ -747,9 +747,8 @@ type
|
||||||
OnUnknown, # location is unknown (stack, heap or static)
|
OnUnknown, # location is unknown (stack, heap or static)
|
||||||
OnStatic, # in a static section
|
OnStatic, # in a static section
|
||||||
OnStack, # location is on hardware stack
|
OnStack, # location is on hardware stack
|
||||||
OnHeap, # location is on heap or global
|
OnHeap # location is on heap or global
|
||||||
# (reference counting needed)
|
# (reference counting needed)
|
||||||
OnHeapNew # location is on the heap and was just new()'ed
|
|
||||||
TLocFlags* = set[TLocFlag]
|
TLocFlags* = set[TLocFlag]
|
||||||
TLoc* = object
|
TLoc* = object
|
||||||
k*: TLocKind # kind of location
|
k*: TLocKind # kind of location
|
||||||
|
|
|
||||||
|
|
@ -157,10 +157,23 @@ proc getStorageLoc(n: PNode): TStorageLoc =
|
||||||
result = getStorageLoc(n.sons[0])
|
result = getStorageLoc(n.sons[0])
|
||||||
else: result = OnUnknown
|
else: result = OnUnknown
|
||||||
|
|
||||||
|
proc canMove(n: PNode): bool =
|
||||||
|
# for now we're conservative here:
|
||||||
|
if n.kind == nkBracket:
|
||||||
|
# This needs to be kept consistent with 'const' seq code
|
||||||
|
# generation!
|
||||||
|
if not isDeepConstExpr(n) or n.len == 0:
|
||||||
|
if skipTypes(n.typ, abstractVarRange).kind == tySequence:
|
||||||
|
return true
|
||||||
|
result = n.kind in nkCallKinds
|
||||||
|
#if result:
|
||||||
|
# echo n.info, " optimized ", n
|
||||||
|
# result = false
|
||||||
|
|
||||||
proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
if dest.storage == OnStack or not usesNativeGC():
|
if dest.storage == OnStack or not usesNativeGC():
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||||
elif dest.storage in {OnHeap, OnHeapNew}:
|
elif dest.storage == OnHeap:
|
||||||
# location is on heap
|
# location is on heap
|
||||||
# now the writer barrier is inlined for performance:
|
# now the writer barrier is inlined for performance:
|
||||||
#
|
#
|
||||||
|
|
@ -202,7 +215,7 @@ proc asgnComplexity(n: PNode): int =
|
||||||
proc optAsgnLoc(a: TLoc, t: PType, field: Rope): TLoc =
|
proc optAsgnLoc(a: TLoc, t: PType, field: Rope): TLoc =
|
||||||
assert field != nil
|
assert field != nil
|
||||||
result.k = locField
|
result.k = locField
|
||||||
result.storage = if a.storage == OnHeapNew: OnHeap else: a.storage
|
result.storage = a.storage
|
||||||
result.lode = lodeTyp t
|
result.lode = lodeTyp t
|
||||||
result.r = rdLoc(a) & "." & field
|
result.r = rdLoc(a) & "." & field
|
||||||
|
|
||||||
|
|
@ -274,18 +287,18 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
of tyRef:
|
of tyRef:
|
||||||
genRefAssign(p, dest, src, flags)
|
genRefAssign(p, dest, src, flags)
|
||||||
of tySequence:
|
of tySequence:
|
||||||
if (needToCopy notin flags and src.storage != OnStatic) or src.storage == OnHeapNew:
|
if (needToCopy notin flags and src.storage != OnStatic) or canMove(src.lode):
|
||||||
genRefAssign(p, dest, src, flags)
|
genRefAssign(p, dest, src, flags)
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
|
linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
|
||||||
addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t))
|
addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t))
|
||||||
of tyString:
|
of tyString:
|
||||||
if (needToCopy notin flags and src.storage != OnStatic) or src.storage == OnHeapNew:
|
if (needToCopy notin flags and src.storage != OnStatic) or canMove(src.lode):
|
||||||
genRefAssign(p, dest, src, flags)
|
genRefAssign(p, dest, src, flags)
|
||||||
else:
|
else:
|
||||||
if dest.storage == OnStack or not usesNativeGC():
|
if dest.storage == OnStack or not usesNativeGC():
|
||||||
linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc)
|
linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc)
|
||||||
elif dest.storage in {OnHeap, OnHeapNew}:
|
elif dest.storage == OnHeap:
|
||||||
# we use a temporary to care for the dreaded self assignment:
|
# we use a temporary to care for the dreaded self assignment:
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
getTemp(p, ty, tmp)
|
getTemp(p, ty, tmp)
|
||||||
|
|
@ -357,7 +370,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||||
else: internalError("genAssignment: " & $ty.kind)
|
else: internalError("genAssignment: " & $ty.kind)
|
||||||
|
|
||||||
if optMemTracker in p.options and dest.storage in {OnHeap, OnHeapNew, OnUnknown}:
|
if optMemTracker in p.options and dest.storage in {OnHeap, OnUnknown}:
|
||||||
#writeStackTrace()
|
#writeStackTrace()
|
||||||
#echo p.currLineInfo, " requesting"
|
#echo p.currLineInfo, " requesting"
|
||||||
linefmt(p, cpsStmts, "#memTrackerWrite((void*)$1, $2, $3, $4);$n",
|
linefmt(p, cpsStmts, "#memTrackerWrite((void*)$1, $2, $3, $4);$n",
|
||||||
|
|
@ -720,7 +733,7 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
putIntoDest(p, d, e, addrLoc(a), a.storage)
|
putIntoDest(p, d, e, addrLoc(a), a.storage)
|
||||||
|
|
||||||
template inheritLocation(d: var TLoc, a: TLoc) =
|
template inheritLocation(d: var TLoc, a: TLoc) =
|
||||||
if d.k == locNone: d.storage = if a.storage == OnHeapNew: OnHeap else: a.storage
|
if d.k == locNone: d.storage = a.storage
|
||||||
|
|
||||||
proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc) =
|
proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc) =
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, e.sons[0], a)
|
||||||
|
|
@ -1087,7 +1100,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
||||||
var sizeExpr = sizeExpr
|
var sizeExpr = sizeExpr
|
||||||
let typ = a.t
|
let typ = a.t
|
||||||
var b: TLoc
|
var b: TLoc
|
||||||
initLoc(b, locExpr, a.lode, OnHeapNew)
|
initLoc(b, locExpr, a.lode, OnHeap)
|
||||||
let refType = typ.skipTypes(abstractInst)
|
let refType = typ.skipTypes(abstractInst)
|
||||||
assert refType.kind == tyRef
|
assert refType.kind == tyRef
|
||||||
let bt = refType.lastSon
|
let bt = refType.lastSon
|
||||||
|
|
@ -1097,7 +1110,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
||||||
let args = [getTypeDesc(p.module, typ),
|
let args = [getTypeDesc(p.module, typ),
|
||||||
genTypeInfo(p.module, typ),
|
genTypeInfo(p.module, typ),
|
||||||
sizeExpr]
|
sizeExpr]
|
||||||
if a.storage in {OnHeap, OnHeapNew} and usesNativeGC():
|
if a.storage == OnHeap and usesNativeGC():
|
||||||
# use newObjRC1 as an optimization
|
# use newObjRC1 as an optimization
|
||||||
if canFormAcycle(a.t):
|
if canFormAcycle(a.t):
|
||||||
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", a.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", a.rdLoc)
|
||||||
|
|
@ -1127,8 +1140,8 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope) =
|
||||||
let args = [getTypeDesc(p.module, seqtype),
|
let args = [getTypeDesc(p.module, seqtype),
|
||||||
genTypeInfo(p.module, seqtype), length]
|
genTypeInfo(p.module, seqtype), length]
|
||||||
var call: TLoc
|
var call: TLoc
|
||||||
initLoc(call, locExpr, dest.lode, OnHeapNew)
|
initLoc(call, locExpr, dest.lode, OnHeap)
|
||||||
if dest.storage in {OnHeap, OnHeapNew} and usesNativeGC():
|
if dest.storage == OnHeap and usesNativeGC():
|
||||||
if canFormAcycle(dest.t):
|
if canFormAcycle(dest.t):
|
||||||
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", dest.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", dest.rdLoc)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1154,7 +1167,6 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
|
||||||
"($1)#nimNewSeqOfCap($2, $3)", [
|
"($1)#nimNewSeqOfCap($2, $3)", [
|
||||||
getTypeDesc(p.module, seqtype),
|
getTypeDesc(p.module, seqtype),
|
||||||
genTypeInfo(p.module, seqtype), a.rdLoc]))
|
genTypeInfo(p.module, seqtype), a.rdLoc]))
|
||||||
d.storage = OnHeapNew
|
|
||||||
gcUsage(e)
|
gcUsage(e)
|
||||||
|
|
||||||
proc genConstExpr(p: BProc, n: PNode): Rope
|
proc genConstExpr(p: BProc, n: PNode): Rope
|
||||||
|
|
@ -1256,7 +1268,7 @@ proc genNewFinalize(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)
|
||||||
initLocExpr(p, e.sons[2], f)
|
initLocExpr(p, e.sons[2], f)
|
||||||
initLoc(b, locExpr, a.lode, OnHeapNew)
|
initLoc(b, locExpr, a.lode, OnHeap)
|
||||||
ti = genTypeInfo(p.module, refType)
|
ti = genTypeInfo(p.module, refType)
|
||||||
addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
|
addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
|
||||||
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
|
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue