reverted deepcopy fix for now
This commit is contained in:
parent
633dcca71b
commit
2316c71e09
2 changed files with 32 additions and 75 deletions
|
|
@ -7,66 +7,18 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
type
|
proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.benign.}
|
||||||
PtrTable = ptr object
|
proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} =
|
||||||
counter, max: int
|
|
||||||
data: array[0..0xff_ffff, (pointer, pointer)]
|
|
||||||
|
|
||||||
template hashPtr(key: pointer): int = cast[int](key) shr 8
|
|
||||||
template allocPtrTable: untyped =
|
|
||||||
cast[PtrTable](alloc0(sizeof(int)*2 + sizeof(pointer)*2*cap))
|
|
||||||
|
|
||||||
proc rehash(t: PtrTable): PtrTable =
|
|
||||||
let cap = (t.max+1) * 2
|
|
||||||
result = allocPtrTable()
|
|
||||||
result.counter = t.counter
|
|
||||||
result.max = cap-1
|
|
||||||
for i in 0..t.max:
|
|
||||||
let k = t.data[i][0]
|
|
||||||
if k != nil:
|
|
||||||
var h = hashPtr(k)
|
|
||||||
while result.data[h and result.max][0] != nil: inc h
|
|
||||||
result.data[h and result.max] = t.data[i]
|
|
||||||
dealloc t
|
|
||||||
|
|
||||||
proc initPtrTable(): PtrTable =
|
|
||||||
const cap = 32
|
|
||||||
result = allocPtrTable()
|
|
||||||
result.counter = 0
|
|
||||||
result.max = cap-1
|
|
||||||
|
|
||||||
template deinit(t: PtrTable) = dealloc(t)
|
|
||||||
|
|
||||||
proc get(t: PtrTable; key: pointer): pointer =
|
|
||||||
var h = hashPtr(key)
|
|
||||||
while true:
|
|
||||||
let k = t.data[h and t.max][0]
|
|
||||||
if k == nil: break
|
|
||||||
if k == key:
|
|
||||||
return t.data[h and t.max][1]
|
|
||||||
inc h
|
|
||||||
|
|
||||||
proc put(t: var PtrTable; key, val: pointer) =
|
|
||||||
if (t.max+1) * 2 < t.counter * 3: t = rehash(t)
|
|
||||||
var h = hashPtr(key)
|
|
||||||
while t.data[h and t.max][0] != nil: inc h
|
|
||||||
t.data[h and t.max] = (key, val)
|
|
||||||
inc t.counter
|
|
||||||
|
|
||||||
proc genericDeepCopyAux(dest, src: pointer, mt: PNimType;
|
|
||||||
tab: var PtrTable) {.benign.}
|
|
||||||
proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode;
|
|
||||||
tab: var PtrTable) {.benign.} =
|
|
||||||
var
|
var
|
||||||
d = cast[ByteAddress](dest)
|
d = cast[ByteAddress](dest)
|
||||||
s = cast[ByteAddress](src)
|
s = cast[ByteAddress](src)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSlot:
|
of nkSlot:
|
||||||
genericDeepCopyAux(cast[pointer](d +% n.offset),
|
genericDeepCopyAux(cast[pointer](d +% n.offset),
|
||||||
cast[pointer](s +% n.offset), n.typ, tab)
|
cast[pointer](s +% n.offset), n.typ)
|
||||||
of nkList:
|
of nkList:
|
||||||
for i in 0..n.len-1:
|
for i in 0..n.len-1:
|
||||||
genericDeepCopyAux(dest, src, n.sons[i], tab)
|
genericDeepCopyAux(dest, src, n.sons[i])
|
||||||
of nkCase:
|
of nkCase:
|
||||||
var dd = selectBranch(dest, n)
|
var dd = selectBranch(dest, n)
|
||||||
var m = selectBranch(src, n)
|
var m = selectBranch(src, n)
|
||||||
|
|
@ -77,10 +29,10 @@ proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode;
|
||||||
copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
|
copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
|
||||||
n.typ.size)
|
n.typ.size)
|
||||||
if m != nil:
|
if m != nil:
|
||||||
genericDeepCopyAux(dest, src, m, tab)
|
genericDeepCopyAux(dest, src, m)
|
||||||
of nkNone: sysAssert(false, "genericDeepCopyAux")
|
of nkNone: sysAssert(false, "genericDeepCopyAux")
|
||||||
|
|
||||||
proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
|
proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) =
|
||||||
var
|
var
|
||||||
d = cast[ByteAddress](dest)
|
d = cast[ByteAddress](dest)
|
||||||
s = cast[ByteAddress](src)
|
s = cast[ByteAddress](src)
|
||||||
|
|
@ -108,22 +60,22 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
|
||||||
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
|
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
|
||||||
cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +%
|
cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +%
|
||||||
GenericSeqSize),
|
GenericSeqSize),
|
||||||
mt.base, tab)
|
mt.base)
|
||||||
of tyObject:
|
of tyObject:
|
||||||
# we need to copy m_type field for tyObject, as it could be empty for
|
# we need to copy m_type field for tyObject, as it could be empty for
|
||||||
# sequence reallocations:
|
# sequence reallocations:
|
||||||
if mt.base != nil:
|
if mt.base != nil:
|
||||||
genericDeepCopyAux(dest, src, mt.base, tab)
|
genericDeepCopyAux(dest, src, mt.base)
|
||||||
else:
|
else:
|
||||||
var pint = cast[ptr PNimType](dest)
|
var pint = cast[ptr PNimType](dest)
|
||||||
pint[] = cast[ptr PNimType](src)[]
|
pint[] = cast[ptr PNimType](src)[]
|
||||||
genericDeepCopyAux(dest, src, mt.node, tab)
|
genericDeepCopyAux(dest, src, mt.node)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
genericDeepCopyAux(dest, src, mt.node, tab)
|
genericDeepCopyAux(dest, src, mt.node)
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
for i in 0..(mt.size div mt.base.size)-1:
|
for i in 0..(mt.size div mt.base.size)-1:
|
||||||
genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size),
|
genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size),
|
||||||
cast[pointer](s +% i*% mt.base.size), mt.base, tab)
|
cast[pointer](s +% i*% mt.base.size), mt.base)
|
||||||
of tyRef:
|
of tyRef:
|
||||||
let s2 = cast[PPointer](src)[]
|
let s2 = cast[PPointer](src)[]
|
||||||
if s2 == nil:
|
if s2 == nil:
|
||||||
|
|
@ -132,24 +84,30 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
|
||||||
let z = mt.base.deepcopy(s2)
|
let z = mt.base.deepcopy(s2)
|
||||||
unsureAsgnRef(cast[PPointer](dest), z)
|
unsureAsgnRef(cast[PPointer](dest), z)
|
||||||
else:
|
else:
|
||||||
let z = tab.get(s2)
|
# we modify the header of the cell temporarily; instead of the type
|
||||||
if z == nil:
|
# field we store a forwarding pointer. XXX This is bad when the cloning
|
||||||
when declared(usrToCell) and false:
|
# fails due to OOM etc.
|
||||||
|
when declared(usrToCell):
|
||||||
|
# unfortunately we only have cycle detection for our native GCs.
|
||||||
let x = usrToCell(s2)
|
let x = usrToCell(s2)
|
||||||
|
let forw = cast[int](x.typ)
|
||||||
|
if (forw and 1) == 1:
|
||||||
|
# we stored a forwarding pointer, so let's use that:
|
||||||
|
let z = cast[pointer](forw and not 1)
|
||||||
|
unsureAsgnRef(cast[PPointer](dest), z)
|
||||||
|
else:
|
||||||
let realType = x.typ
|
let realType = x.typ
|
||||||
let z = newObj(realType, realType.base.size)
|
let z = newObj(realType, realType.base.size)
|
||||||
unsureAsgnRef(cast[PPointer](dest), z)
|
unsureAsgnRef(cast[PPointer](dest), z)
|
||||||
tab.put(s2, z)
|
x.typ = cast[PNimType](cast[int](z) or 1)
|
||||||
genericDeepCopyAux(z, s2, realType.base, tab)
|
genericDeepCopyAux(z, s2, realType.base)
|
||||||
|
x.typ = realType
|
||||||
else:
|
else:
|
||||||
# this version should work for any possible GC:
|
let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size
|
||||||
let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size else: mt.base.size
|
else: mt.base.size
|
||||||
let z = newObj(mt, size)
|
let z = newObj(mt, size)
|
||||||
unsureAsgnRef(cast[PPointer](dest), z)
|
unsureAsgnRef(cast[PPointer](dest), z)
|
||||||
tab.put(s2, z)
|
genericDeepCopyAux(z, s2, mt.base)
|
||||||
genericDeepCopyAux(z, s2, mt.base, tab)
|
|
||||||
else:
|
|
||||||
unsureAsgnRef(cast[PPointer](dest), z)
|
|
||||||
of tyPtr:
|
of tyPtr:
|
||||||
# no cycle check here, but also not really required
|
# no cycle check here, but also not really required
|
||||||
let s2 = cast[PPointer](src)[]
|
let s2 = cast[PPointer](src)[]
|
||||||
|
|
@ -162,9 +120,7 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
|
||||||
|
|
||||||
proc genericDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} =
|
proc genericDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} =
|
||||||
GC_disable()
|
GC_disable()
|
||||||
var tab = initPtrTable()
|
genericDeepCopyAux(dest, src, mt)
|
||||||
genericDeepCopyAux(dest, src, mt, tab)
|
|
||||||
deinit tab
|
|
||||||
GC_enable()
|
GC_enable()
|
||||||
|
|
||||||
proc genericSeqDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} =
|
proc genericSeqDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} =
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
output: "ok"
|
output: "ok"
|
||||||
|
disabled: "true"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import tables, lists
|
import tables, lists
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue