diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 27 | ||||
-rw-r--r-- | compiler/cgen.nim | 8 | ||||
-rw-r--r-- | compiler/options.nim | 6 |
3 files changed, 29 insertions, 12 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 54e805a44..d73dac82f 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -169,7 +169,7 @@ proc canMove(p: BProc, n: PNode): bool = # result = false proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = - if dest.storage == OnStack or not usesWriteBarrier(p.config): + if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config): linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) elif dest.storage == OnHeap: # location is on heap @@ -265,7 +265,7 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = rdLoc(dest), rdLoc(src)) elif needToCopy notin flags or tfShallow in skipTypes(dest.t, abstractVarRange).flags: - if dest.storage == OnStack or not usesWriteBarrier(p.config): + if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config): linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", addrLoc(p.config, dest), addrLoc(p.config, src), rdLoc(dest)) @@ -302,7 +302,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = elif (needToCopy notin flags and src.storage != OnStatic) or canMove(p, src.lode): genRefAssign(p, dest, src, flags) else: - if dest.storage == OnStack or not usesWriteBarrier(p.config): + if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config): linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc) elif dest.storage == OnHeap: # we use a temporary to care for the dreaded self assignment: @@ -1193,13 +1193,19 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = let args = [getTypeDesc(p.module, typ), ti, sizeExpr] if a.storage == OnHeap and usesWriteBarrier(p.config): - # use newObjRC1 as an optimization if canFormAcycle(a.t): linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", a.rdLoc) else: linefmt(p, cpsStmts, "if ($1) { #nimGCunrefNoCycle($1); $1 = NIM_NIL; }$n", a.rdLoc) - b.r = ropecg(p.module, "($1) #newObjRC1($2, $3)", args) - linefmt(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc) + if p.config.selectedGC == gcGo: + # newObjRC1() would clash with unsureAsgnRef() - which is used by gcGo to + # implement the write barrier + b.r = ropecg(p.module, "($1) #newObj($2, $3)", args) + linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", addrLoc(p.config, a), b.rdLoc) + else: + # use newObjRC1 as an optimization + b.r = ropecg(p.module, "($1) #newObjRC1($2, $3)", args) + linefmt(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc) else: b.r = ropecg(p.module, "($1) #newObj($2, $3)", args) genAssignment(p, a, b, {}) # set the object type: @@ -1229,8 +1235,13 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope; lenIsZero: bool) = else: linefmt(p, cpsStmts, "if ($1) { #nimGCunrefNoCycle($1); $1 = NIM_NIL; }$n", dest.rdLoc) if not lenIsZero: - call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args) - linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc) + if p.config.selectedGC == gcGo: + # we need the write barrier + call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args) + linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", addrLoc(p.config, dest), call.rdLoc) + else: + call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args) + linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc) else: if lenIsZero: call.r = rope"NIM_NIL" diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 37b07d38d..86aa7fb45 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -702,8 +702,12 @@ proc closureSetup(p: BProc, prc: PSym) = #echo "created environment: ", env.id, " for ", prc.name.s assignLocalVar(p, ls) # generate cast assignment: - linefmt(p, cpsStmts, "$1 = ($2) ClE_0;$n", - rdLoc(env.loc), getTypeDesc(p.module, env.typ)) + if p.config.selectedGC == gcGo: + linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, ($2) ClE_0);$n", + addrLoc(p.config, env.loc), getTypeDesc(p.module, env.typ)) + else: + linefmt(p, cpsStmts, "$1 = ($2) ClE_0;$n", + rdLoc(env.loc), getTypeDesc(p.module, env.typ)) proc containsResult(n: PNode): bool = if n.kind == nkSym and n.sym.kind == skResult: diff --git a/compiler/options.nim b/compiler/options.nim index b4d2bb64e..4b7d664f4 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -104,8 +104,10 @@ type cmdJsonScript # compile a .json build file TStringSeq* = seq[string] TGCMode* = enum # the selected GC - gcNone, gcBoehm, gcGo, gcRegions, gcMarkAndSweep, gcDestructors, - gcRefc, gcV2 + gcNone, gcBoehm, gcRegions, gcMarkAndSweep, gcDestructors, + gcRefc, gcV2, gcGo + # gcRefc and the GCs that follow it use a write barrier, + # as far as usesWriteBarrier() is concerned IdeCmd* = enum ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod, |