From 8875ca750f839de0c3eefdc73e665228f45b52e0 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 17 Nov 2016 19:57:10 +0100 Subject: deepCopy: proper sharing of refs --- lib/system/deepcopy.nim | 104 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 31 deletions(-) (limited to 'lib/system/deepcopy.nim') diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index 38cc8cbf3..0a661d0cd 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -7,18 +7,64 @@ # distribution, for details about the copyright. # -proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.benign.} -proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} = +type + PtrTable = ptr object + counter, max: int + data: array[0..0xff_ffff, (pointer, pointer)] + +template hashPtr(key: pointer): int = cast[int](key) shr 8 + +proc rehash(t: PtrTable): PtrTable = + let cap = (t.max+1) * 2 + result = cast[PtrTable](alloc0(sizeof(int)*2 + sizeof(pointer)*cap)) + 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 = cast[PtrTable](alloc0(sizeof(int)*2 + sizeof(pointer)*cap)) + 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 d = cast[ByteAddress](dest) s = cast[ByteAddress](src) case n.kind of nkSlot: genericDeepCopyAux(cast[pointer](d +% n.offset), - cast[pointer](s +% n.offset), n.typ) + cast[pointer](s +% n.offset), n.typ, tab) of nkList: for i in 0..n.len-1: - genericDeepCopyAux(dest, src, n.sons[i]) + genericDeepCopyAux(dest, src, n.sons[i], tab) of nkCase: var dd = selectBranch(dest, n) var m = selectBranch(src, n) @@ -29,10 +75,10 @@ proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} = copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset), n.typ.size) if m != nil: - genericDeepCopyAux(dest, src, m) + genericDeepCopyAux(dest, src, m, tab) of nkNone: sysAssert(false, "genericDeepCopyAux") -proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = +proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = var d = cast[ByteAddress](dest) s = cast[ByteAddress](src) @@ -60,22 +106,22 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), - mt.base) + mt.base, tab) of tyObject: # we need to copy m_type field for tyObject, as it could be empty for # sequence reallocations: if mt.base != nil: - genericDeepCopyAux(dest, src, mt.base) + genericDeepCopyAux(dest, src, mt.base, tab) else: var pint = cast[ptr PNimType](dest) pint[] = cast[ptr PNimType](src)[] - genericDeepCopyAux(dest, src, mt.node) + genericDeepCopyAux(dest, src, mt.node, tab) of tyTuple: - genericDeepCopyAux(dest, src, mt.node) + genericDeepCopyAux(dest, src, mt.node, tab) of tyArray, tyArrayConstr: for i in 0..(mt.size div mt.base.size)-1: genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size), - cast[pointer](s +% i*% mt.base.size), mt.base) + cast[pointer](s +% i*% mt.base.size), mt.base, tab) of tyRef: let s2 = cast[PPointer](src)[] if s2 == nil: @@ -84,30 +130,24 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = let z = mt.base.deepcopy(s2) unsureAsgnRef(cast[PPointer](dest), z) else: - # we modify the header of the cell temporarily; instead of the type - # field we store a forwarding pointer. XXX This is bad when the cloning - # fails due to OOM etc. - when declared(usrToCell): - # unfortunately we only have cycle detection for our native GCs. - 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 z = tab.get(s2) + if z == nil: + when declared(usrToCell) and false: + let x = usrToCell(s2) let realType = x.typ let z = newObj(realType, realType.base.size) unsureAsgnRef(cast[PPointer](dest), z) - x.typ = cast[PNimType](cast[int](z) or 1) - genericDeepCopyAux(z, s2, realType.base) - x.typ = realType + tab.put(s2, z) + genericDeepCopyAux(z, s2, realType.base, tab) + else: + # this version should work for any possible GC: + let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size else: mt.base.size + let z = newObj(mt, size) + unsureAsgnRef(cast[PPointer](dest), z) + tab.put(s2, z) + genericDeepCopyAux(z, s2, mt.base, tab) else: - let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size - else: mt.base.size - let z = newObj(mt, size) unsureAsgnRef(cast[PPointer](dest), z) - genericDeepCopyAux(z, s2, mt.base) of tyPtr: # no cycle check here, but also not really required let s2 = cast[PPointer](src)[] @@ -120,7 +160,9 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = proc genericDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} = GC_disable() - genericDeepCopyAux(dest, src, mt) + var tab = initPtrTable() + genericDeepCopyAux(dest, src, mt, tab) + deinit tab GC_enable() proc genericSeqDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} = -- cgit 1.4.1-2-gfad0 From 7c1b5b3c2ba0e76c55cd3ea34dd1ac5beea1af42 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 18 Nov 2016 09:54:12 +0100 Subject: fixes deepcopy regression --- lib/system/deepcopy.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/system/deepcopy.nim') diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index 0a661d0cd..b1609252c 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -13,10 +13,12 @@ type 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 = cast[PtrTable](alloc0(sizeof(int)*2 + sizeof(pointer)*cap)) + result = allocPtrTable() result.counter = t.counter result.max = cap-1 for i in 0..t.max: @@ -29,7 +31,7 @@ proc rehash(t: PtrTable): PtrTable = proc initPtrTable(): PtrTable = const cap = 32 - result = cast[PtrTable](alloc0(sizeof(int)*2 + sizeof(pointer)*cap)) + result = allocPtrTable() result.counter = 0 result.max = cap-1 -- cgit 1.4.1-2-gfad0 From 2316c71e09aef62f9f1a4897c47baccaea2623bf Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 24 Nov 2016 10:52:33 +0100 Subject: reverted deepcopy fix for now --- lib/system/deepcopy.nim | 106 +++++++++++++-------------------------------- tests/system/tdeepcopy.nim | 1 + 2 files changed, 32 insertions(+), 75 deletions(-) (limited to 'lib/system/deepcopy.nim') diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index b1609252c..38cc8cbf3 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -7,66 +7,18 @@ # distribution, for details about the copyright. # -type - PtrTable = ptr object - 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.} = +proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.benign.} +proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} = var d = cast[ByteAddress](dest) s = cast[ByteAddress](src) case n.kind of nkSlot: genericDeepCopyAux(cast[pointer](d +% n.offset), - cast[pointer](s +% n.offset), n.typ, tab) + cast[pointer](s +% n.offset), n.typ) of nkList: for i in 0..n.len-1: - genericDeepCopyAux(dest, src, n.sons[i], tab) + genericDeepCopyAux(dest, src, n.sons[i]) of nkCase: var dd = selectBranch(dest, 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), n.typ.size) if m != nil: - genericDeepCopyAux(dest, src, m, tab) + genericDeepCopyAux(dest, src, m) of nkNone: sysAssert(false, "genericDeepCopyAux") -proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = +proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = var d = cast[ByteAddress](dest) 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](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), - mt.base, tab) + mt.base) of tyObject: # we need to copy m_type field for tyObject, as it could be empty for # sequence reallocations: if mt.base != nil: - genericDeepCopyAux(dest, src, mt.base, tab) + genericDeepCopyAux(dest, src, mt.base) else: var pint = cast[ptr PNimType](dest) pint[] = cast[ptr PNimType](src)[] - genericDeepCopyAux(dest, src, mt.node, tab) + genericDeepCopyAux(dest, src, mt.node) of tyTuple: - genericDeepCopyAux(dest, src, mt.node, tab) + genericDeepCopyAux(dest, src, mt.node) of tyArray, tyArrayConstr: for i in 0..(mt.size div mt.base.size)-1: 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: let s2 = cast[PPointer](src)[] if s2 == nil: @@ -132,24 +84,30 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = let z = mt.base.deepcopy(s2) unsureAsgnRef(cast[PPointer](dest), z) else: - let z = tab.get(s2) - if z == nil: - when declared(usrToCell) and false: - let x = usrToCell(s2) - let realType = x.typ - let z = newObj(realType, realType.base.size) + # we modify the header of the cell temporarily; instead of the type + # field we store a forwarding pointer. XXX This is bad when the cloning + # fails due to OOM etc. + when declared(usrToCell): + # unfortunately we only have cycle detection for our native GCs. + 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) - tab.put(s2, z) - genericDeepCopyAux(z, s2, realType.base, tab) else: - # this version should work for any possible GC: - let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size else: mt.base.size - let z = newObj(mt, size) + let realType = x.typ + let z = newObj(realType, realType.base.size) unsureAsgnRef(cast[PPointer](dest), z) - tab.put(s2, z) - genericDeepCopyAux(z, s2, mt.base, tab) + x.typ = cast[PNimType](cast[int](z) or 1) + genericDeepCopyAux(z, s2, realType.base) + x.typ = realType else: + let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size + else: mt.base.size + let z = newObj(mt, size) unsureAsgnRef(cast[PPointer](dest), z) + genericDeepCopyAux(z, s2, mt.base) of tyPtr: # no cycle check here, but also not really required 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.} = GC_disable() - var tab = initPtrTable() - genericDeepCopyAux(dest, src, mt, tab) - deinit tab + genericDeepCopyAux(dest, src, mt) GC_enable() proc genericSeqDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} = diff --git a/tests/system/tdeepcopy.nim b/tests/system/tdeepcopy.nim index f7a6e87fa..5a582425a 100644 --- a/tests/system/tdeepcopy.nim +++ b/tests/system/tdeepcopy.nim @@ -1,5 +1,6 @@ discard """ output: "ok" + disabled: "true" """ import tables, lists -- cgit 1.4.1-2-gfad0 From e83d11e8f17c384aa9f717936128d7a2d9c2b512 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 26 Nov 2016 14:15:37 +0100 Subject: deepcopy fix --- lib/system/deepcopy.nim | 106 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 31 deletions(-) (limited to 'lib/system/deepcopy.nim') diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index 38cc8cbf3..b1609252c 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -7,18 +7,66 @@ # distribution, for details about the copyright. # -proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.benign.} -proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} = +type + PtrTable = ptr object + 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 d = cast[ByteAddress](dest) s = cast[ByteAddress](src) case n.kind of nkSlot: genericDeepCopyAux(cast[pointer](d +% n.offset), - cast[pointer](s +% n.offset), n.typ) + cast[pointer](s +% n.offset), n.typ, tab) of nkList: for i in 0..n.len-1: - genericDeepCopyAux(dest, src, n.sons[i]) + genericDeepCopyAux(dest, src, n.sons[i], tab) of nkCase: var dd = selectBranch(dest, n) var m = selectBranch(src, n) @@ -29,10 +77,10 @@ proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} = copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset), n.typ.size) if m != nil: - genericDeepCopyAux(dest, src, m) + genericDeepCopyAux(dest, src, m, tab) of nkNone: sysAssert(false, "genericDeepCopyAux") -proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = +proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = var d = cast[ByteAddress](dest) s = cast[ByteAddress](src) @@ -60,22 +108,22 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), - mt.base) + mt.base, tab) of tyObject: # we need to copy m_type field for tyObject, as it could be empty for # sequence reallocations: if mt.base != nil: - genericDeepCopyAux(dest, src, mt.base) + genericDeepCopyAux(dest, src, mt.base, tab) else: var pint = cast[ptr PNimType](dest) pint[] = cast[ptr PNimType](src)[] - genericDeepCopyAux(dest, src, mt.node) + genericDeepCopyAux(dest, src, mt.node, tab) of tyTuple: - genericDeepCopyAux(dest, src, mt.node) + genericDeepCopyAux(dest, src, mt.node, tab) of tyArray, tyArrayConstr: for i in 0..(mt.size div mt.base.size)-1: genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size), - cast[pointer](s +% i*% mt.base.size), mt.base) + cast[pointer](s +% i*% mt.base.size), mt.base, tab) of tyRef: let s2 = cast[PPointer](src)[] if s2 == nil: @@ -84,30 +132,24 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = let z = mt.base.deepcopy(s2) unsureAsgnRef(cast[PPointer](dest), z) else: - # we modify the header of the cell temporarily; instead of the type - # field we store a forwarding pointer. XXX This is bad when the cloning - # fails due to OOM etc. - when declared(usrToCell): - # unfortunately we only have cycle detection for our native GCs. - 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 z = tab.get(s2) + if z == nil: + when declared(usrToCell) and false: + let x = usrToCell(s2) let realType = x.typ let z = newObj(realType, realType.base.size) unsureAsgnRef(cast[PPointer](dest), z) - x.typ = cast[PNimType](cast[int](z) or 1) - genericDeepCopyAux(z, s2, realType.base) - x.typ = realType + tab.put(s2, z) + genericDeepCopyAux(z, s2, realType.base, tab) + else: + # this version should work for any possible GC: + let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size else: mt.base.size + let z = newObj(mt, size) + unsureAsgnRef(cast[PPointer](dest), z) + tab.put(s2, z) + genericDeepCopyAux(z, s2, mt.base, tab) else: - let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size - else: mt.base.size - let z = newObj(mt, size) unsureAsgnRef(cast[PPointer](dest), z) - genericDeepCopyAux(z, s2, mt.base) of tyPtr: # no cycle check here, but also not really required let s2 = cast[PPointer](src)[] @@ -120,7 +162,9 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = proc genericDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} = GC_disable() - genericDeepCopyAux(dest, src, mt) + var tab = initPtrTable() + genericDeepCopyAux(dest, src, mt, tab) + deinit tab GC_enable() proc genericSeqDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} = -- cgit 1.4.1-2-gfad0 From 734443d725724df0d328d27982fbc2c54d1ff683 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 28 Nov 2016 11:03:01 +0100 Subject: system.deepCopy should show old behaviour --- lib/system/deepcopy.nim | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/system/deepcopy.nim') diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index b1609252c..c137b3cf6 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -134,7 +134,7 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = else: let z = tab.get(s2) if z == nil: - when declared(usrToCell) and false: + when declared(usrToCell): let x = usrToCell(s2) let realType = x.typ let z = newObj(realType, realType.base.size) @@ -142,6 +142,11 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = tab.put(s2, z) genericDeepCopyAux(z, s2, realType.base, tab) else: + when false: + # addition check disabled + let x = usrToCell(s2) + let realType = x.typ + sysAssert realType == mt, " types do differ" # this version should work for any possible GC: let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size else: mt.base.size let z = newObj(mt, size) -- cgit 1.4.1-2-gfad0