diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-12-01 15:24:32 +0200 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-12-01 15:37:13 +0200 |
commit | e9e22ccb2adfe1a44e998405b2dfed9b46ddcb95 (patch) | |
tree | f157d6c1bc8e3b908c8175a3729ce2f8e7bc48f4 /compiler/ccgexprs.nim | |
parent | c67520a7c5d474be409bee98d9b258030115c259 (diff) | |
download | Nim-e9e22ccb2adfe1a44e998405b2dfed9b46ddcb95.tar.gz |
track the "owner" heap object in the ref write barrier
See the papers for reference counting with heap sliding views for details:
Diffstat (limited to 'compiler/ccgexprs.nim')
-rwxr-xr-x | compiler/ccgexprs.nim | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index ddc93d5a3..67d7b1a38 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -165,7 +165,7 @@ proc getStorageLoc(n: PNode): TStorageLoc = proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if dest.s == OnStack or optRefcGC notin gGlobalOptions: - lineF(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) + linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) if needToKeepAlive in flags: keepAlive(p, dest) elif dest.s == OnHeap: # location is on heap @@ -188,9 +188,19 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n", addrLoc(dest), rdLoc(src)) else: + if cnimdbg: + echo "ASSIGN REF ", dest.k, " ", dest.s, " ", dest.r.ropeToStr + if dest.heapRoot != nil: + echo "ROOTED AT ", dest.heapRoot.ropeToStr + linefmt(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n", addrLoc(dest), rdLoc(src)) else: + if cnimdbg: + echo "ASSIGN REF ", dest.k, " ", dest.s, " ", dest.r.ropeToStr + if dest.heapRoot != nil: + echo "ROOTED AT ", dest.heapRoot.ropeToStr + linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", addrLoc(dest), rdLoc(src)) if needToKeepAlive in flags: keepAlive(p, dest) @@ -562,10 +572,15 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) = InitLocExpr(p, e.sons[0], a) putIntoDest(p, d, e.typ, addrLoc(a)) +template inheritLocation(d: var TLoc, a: TLoc) = + if d.k == locNone: d.s = a.s + if d.heapRoot == nil: + d.heapRoot = if a.heapRoot != nil: a.heapRoot else: a.r + proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType = initLocExpr(p, e.sons[0], a) if e.sons[1].kind != nkSym: InternalError(e.info, "genRecordFieldAux") - if d.k == locNone: d.s = a.s + d.inheritLocation(a) discard getTypeDesc(p.module, a.t) # fill the record's fields.loc result = a.t @@ -598,7 +613,7 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) = a: TLoc i: int initLocExpr(p, e.sons[0], a) - if d.k == locNone: d.s = a.s + d.inheritLocation(a) discard getTypeDesc(p.module, a.t) # fill the record's fields.loc var ty = a.t var r = rdLoc(a) @@ -688,7 +703,7 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) = let idx = getOrdValue(e.sons[1]) if idx < firstOrd(ty) or idx > lastOrd(ty): localError(e.info, errIndexOutOfBounds) - if d.k == locNone: d.s = a.s + d.inheritLocation(a) putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)), rfmt(nil, "$1[($2)- $3]", rdLoc(a), rdCharLoc(b), first)) @@ -729,6 +744,7 @@ proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) = "if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n", rdLoc(b), rdLoc(a), lenField()) if d.k == locNone: d.s = OnHeap + d.heapRoot = a.r if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}: a.r = rfmt(nil, "(*$1)", a.r) putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), |