fixes #2070
This commit is contained in:
parent
03019849fc
commit
683b82a2ec
2 changed files with 29 additions and 19 deletions
|
|
@ -528,20 +528,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
||||||
newsize-oldsize)
|
newsize-oldsize)
|
||||||
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
||||||
sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
|
# This can be wrong for intermediate temps that are nevertheless on the
|
||||||
#if res.refcount <% rcIncrement:
|
# heap because of lambda lifting:
|
||||||
# add(gch.zct, res)
|
#gcAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
|
||||||
#else: # XXX: what to do here?
|
|
||||||
# decRef(ol)
|
|
||||||
if (ol.refcount and ZctFlag) != 0:
|
|
||||||
var j = gch.zct.len-1
|
|
||||||
var d = gch.zct.d
|
|
||||||
while j >= 0:
|
|
||||||
if d[j] == ol:
|
|
||||||
d[j] = res
|
|
||||||
break
|
|
||||||
dec(j)
|
|
||||||
if canbeCycleRoot(ol): excl(gch.cycleRoots, ol)
|
|
||||||
when logGC:
|
when logGC:
|
||||||
writeCell("growObj old cell", ol)
|
writeCell("growObj old cell", ol)
|
||||||
writeCell("growObj new cell", res)
|
writeCell("growObj new cell", res)
|
||||||
|
|
@ -549,7 +538,26 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
gcTrace(res, csAllocated)
|
gcTrace(res, csAllocated)
|
||||||
when reallyDealloc:
|
when reallyDealloc:
|
||||||
sysAssert(allocInv(gch.region), "growObj before dealloc")
|
sysAssert(allocInv(gch.region), "growObj before dealloc")
|
||||||
rawDealloc(gch.region, ol)
|
if ol.refcount shr rcShift <=% 1:
|
||||||
|
# free immediately to save space:
|
||||||
|
if (ol.refcount and ZctFlag) != 0:
|
||||||
|
var j = gch.zct.len-1
|
||||||
|
var d = gch.zct.d
|
||||||
|
while j >= 0:
|
||||||
|
if d[j] == ol:
|
||||||
|
d[j] = res
|
||||||
|
break
|
||||||
|
dec(j)
|
||||||
|
if canbeCycleRoot(ol): excl(gch.cycleRoots, ol)
|
||||||
|
rawDealloc(gch.region, ol)
|
||||||
|
else:
|
||||||
|
# we split the old refcount in 2 parts. XXX This is still not entirely
|
||||||
|
# correct if the pointer that receives growObj's result is on the stack.
|
||||||
|
# A better fix would be to emit the location specific write barrier for
|
||||||
|
# 'growObj', but this is lost of more work and who knows what new problems
|
||||||
|
# this would create.
|
||||||
|
res.refcount = rcIncrement
|
||||||
|
decRef(ol)
|
||||||
else:
|
else:
|
||||||
sysAssert(ol.typ != nil, "growObj: 5")
|
sysAssert(ol.typ != nil, "growObj: 5")
|
||||||
zeroMem(ol, sizeof(TCell))
|
zeroMem(ol, sizeof(TCell))
|
||||||
|
|
|
||||||
|
|
@ -297,10 +297,12 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
||||||
newsize-oldsize)
|
newsize-oldsize)
|
||||||
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
||||||
when withBitvectors: excl(gch.allocated, ol)
|
when false:
|
||||||
when reallyDealloc: rawDealloc(gch.region, ol)
|
# this is wrong since seqs can be shared via 'shallow':
|
||||||
else:
|
when withBitvectors: excl(gch.allocated, ol)
|
||||||
zeroMem(ol, sizeof(TCell))
|
when reallyDealloc: rawDealloc(gch.region, ol)
|
||||||
|
else:
|
||||||
|
zeroMem(ol, sizeof(TCell))
|
||||||
when withBitvectors: incl(gch.allocated, res)
|
when withBitvectors: incl(gch.allocated, res)
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
inc gch.idGenerator
|
inc gch.idGenerator
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue