diff options
-rw-r--r-- | compiler/ccgexprs.nim | 17 | ||||
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | lib/system/gc.nim | 5 | ||||
-rw-r--r-- | tests/gc/growobjcrash.nim | 4 |
4 files changed, 17 insertions, 10 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 2e9fb2cc2..96f172422 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1092,17 +1092,20 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = # seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x)); # seq->data[seq->len-1] = x; let seqAppendPattern = if not p.module.compileToCpp: - "$1 = ($2) #incrSeqV3(&($1)->Sup, $3);$n" + "($2) #incrSeqV3(&($1)->Sup, $3)" else: - "$1 = ($2) #incrSeqV3($1, $3);$n" - var a, b, dest, tmpL: TLoc + "($2) #incrSeqV3($1, $3)" + var a, b, dest, tmpL, call: TLoc initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) let seqType = skipTypes(e.sons[1].typ, {tyVar}) - lineCg(p, cpsStmts, seqAppendPattern, [ - rdLoc(a), - getTypeDesc(p.module, e.sons[1].typ), - genTypeInfo(p.module, seqType, e.info)]) + initLoc(call, locCall, e, OnHeap) + call.r = ropecg(p.module, seqAppendPattern, [rdLoc(a), + getTypeDesc(p.module, e.sons[1].typ), + genTypeInfo(p.module, seqType, e.info)]) + # emit the write barrier if required, but we can always move here, so + # use 'genRefAssign' for the seq. + genRefAssign(p, a, call, {}) #if bt != b.t: # echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t) initLoc(dest, locExpr, e.sons[2], OnHeap) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 8b2d36722..9dfe69442 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -72,3 +72,4 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimNoZeroTerminator") defineSymbol("nimNotNil") defineSymbol("nimVmExportFixed") + defineSymbol("nimIncrSeqV3") diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 425963f3f..74ac68eea 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -548,7 +548,10 @@ proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer = gcTrace(res, csAllocated) track("growObj old", ol, 0) track("growObj new", res, newsize) - when reallyDealloc: + when defined(nimIncrSeqV3): + # since we steal the old seq's contents, we set the old length to 0. + cast[PGenericSeq](old).len = 0 + elif reallyDealloc: sysAssert(allocInv(gch.region), "growObj before dealloc") if ol.refcount shr rcShift <=% 1: # free immediately to save space: diff --git a/tests/gc/growobjcrash.nim b/tests/gc/growobjcrash.nim index a16468c7e..b8ff4f908 100644 --- a/tests/gc/growobjcrash.nim +++ b/tests/gc/growobjcrash.nim @@ -14,11 +14,11 @@ proc handleRequest(query: string): StringTableRef = let x = foo result = x() -const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 700_000 +const Limit = 5*1024*1024 proc main = var counter = 0 - for i in 0 .. 100_000: + for i in 0 .. 10_000_000: for k, v in handleRequest("nick=Elina2&type=activate"): inc counter if counter mod 100 == 0: |