forward type alignment information to seqs (#12430)
This commit is contained in:
parent
a8f030fea2
commit
4005f0d0e4
25 changed files with 152 additions and 114 deletions
|
|
@ -245,7 +245,7 @@ proc setLengthStr(s: NimString, newLen: int): NimString {.compilerRtl.} =
|
|||
|
||||
# ----------------- sequences ----------------------------------------------
|
||||
|
||||
proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerproc.} =
|
||||
proc incrSeq(seq: PGenericSeq, elemSize, elemAlign: int): PGenericSeq {.compilerproc.} =
|
||||
# increments the length by one:
|
||||
# this is needed for supporting ``add``;
|
||||
#
|
||||
|
|
@ -255,18 +255,16 @@ proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerproc.} =
|
|||
result = seq
|
||||
if result.len >= result.space:
|
||||
let r = resize(result.space)
|
||||
result = cast[PGenericSeq](growObj(result, elemSize * r +
|
||||
GenericSeqSize))
|
||||
result = cast[PGenericSeq](growObj(result, align(GenericSeqSize, elemAlign) + elemSize * r))
|
||||
result.reserved = r
|
||||
inc(result.len)
|
||||
|
||||
proc incrSeqV2(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerproc.} =
|
||||
proc incrSeqV2(seq: PGenericSeq, elemSize, elemAlign: int): PGenericSeq {.compilerproc.} =
|
||||
# incrSeq version 2
|
||||
result = seq
|
||||
if result.len >= result.space:
|
||||
let r = resize(result.space)
|
||||
result = cast[PGenericSeq](growObj(result, elemSize * r +
|
||||
GenericSeqSize))
|
||||
result = cast[PGenericSeq](growObj(result, align(GenericSeqSize, elemAlign) + elemSize * r))
|
||||
result.reserved = r
|
||||
|
||||
template `+!`(p: pointer, s: int): pointer =
|
||||
|
|
@ -283,21 +281,19 @@ proc incrSeqV3(s: PGenericSeq, typ: PNimType): PGenericSeq {.compilerproc.} =
|
|||
when defined(nimIncrSeqV3):
|
||||
result = cast[PGenericSeq](newSeq(typ, r))
|
||||
result.len = s.len
|
||||
copyMem(result +! GenericSeqSize, s +! GenericSeqSize, s.len * typ.base.size)
|
||||
copyMem(result +! align(GenericSeqSize, typ.base.align), s +! align(GenericSeqSize, typ.base.align), s.len * typ.base.size)
|
||||
# since we steal the content from 's', it's crucial to set s's len to 0.
|
||||
s.len = 0
|
||||
else:
|
||||
result = cast[PGenericSeq](growObj(result, typ.base.size * r +
|
||||
GenericSeqSize))
|
||||
result = cast[PGenericSeq](growObj(result, align(GenericSeqSize, typ.base.align) + typ.base.size * r))
|
||||
result.reserved = r
|
||||
|
||||
proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||
proc setLengthSeq(seq: PGenericSeq, elemSize, elemAlign, newLen: int): PGenericSeq {.
|
||||
compilerRtl, inl.} =
|
||||
result = seq
|
||||
if result.space < newLen:
|
||||
let r = max(resize(result.space), newLen)
|
||||
result = cast[PGenericSeq](growObj(result, elemSize * r +
|
||||
GenericSeqSize))
|
||||
result = cast[PGenericSeq](growObj(result, align(GenericSeqSize, elemAlign) + elemSize * r))
|
||||
result.reserved = r
|
||||
elif newLen < result.len:
|
||||
# we need to decref here, otherwise the GC leaks!
|
||||
|
|
@ -307,8 +303,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
|||
when false: # compileOption("gc", "v2"):
|
||||
for i in newLen..result.len-1:
|
||||
let len0 = gch.tempStack.len
|
||||
forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%
|
||||
GenericSeqSize +% (i*%elemSize)),
|
||||
forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +% align(GenericSeqSize, elemAlign) +% (i*%elemSize)),
|
||||
extGetCellType(result).base, waPush)
|
||||
let len1 = gch.tempStack.len
|
||||
for i in len0 ..< len1:
|
||||
|
|
@ -318,7 +313,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
|||
if ntfNoRefs notin extGetCellType(result).base.flags:
|
||||
for i in newLen..result.len-1:
|
||||
forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%
|
||||
GenericSeqSize +% (i*%elemSize)),
|
||||
align(GenericSeqSize, elemAlign) +% (i*%elemSize)),
|
||||
extGetCellType(result).base, waZctDecRef)
|
||||
|
||||
# XXX: zeroing out the memory can still result in crashes if a wiped-out
|
||||
|
|
@ -327,7 +322,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
|||
# presence of user defined destructors, the user will expect the cell to be
|
||||
# "destroyed" thus creating the same problem. We can destroy the cell in the
|
||||
# finalizer of the sequence, but this makes destruction non-deterministic.
|
||||
zeroMem(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +%
|
||||
zeroMem(cast[pointer](cast[ByteAddress](result) +% align(GenericSeqSize, elemAlign) +%
|
||||
(newLen*%elemSize)), (result.len-%newLen) *% elemSize)
|
||||
result.len = newLen
|
||||
|
||||
|
|
@ -339,10 +334,11 @@ proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
|||
else:
|
||||
when defined(nimIncrSeqV3):
|
||||
let elemSize = typ.base.size
|
||||
let elemAlign = typ.base.align
|
||||
if s.space < newLen:
|
||||
let r = max(resize(s.space), newLen)
|
||||
result = cast[PGenericSeq](newSeq(typ, r))
|
||||
copyMem(result +! GenericSeqSize, s +! GenericSeqSize, s.len * elemSize)
|
||||
copyMem(result +! align(GenericSeqSize, elemAlign), s +! align(GenericSeqSize, elemAlign), s.len * elemSize)
|
||||
# since we steal the content from 's', it's crucial to set s's len to 0.
|
||||
s.len = 0
|
||||
elif newLen < s.len:
|
||||
|
|
@ -354,7 +350,7 @@ proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
|||
if ntfNoRefs notin typ.base.flags:
|
||||
for i in newLen..result.len-1:
|
||||
forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%
|
||||
GenericSeqSize +% (i*%elemSize)),
|
||||
align(GenericSeqSize, elemAlign) +% (i*%elemSize)),
|
||||
extGetCellType(result).base, waZctDecRef)
|
||||
|
||||
# XXX: zeroing out the memory can still result in crashes if a wiped-out
|
||||
|
|
@ -363,7 +359,7 @@ proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
|||
# presence of user defined destructors, the user will expect the cell to be
|
||||
# "destroyed" thus creating the same problem. We can destroy the cell in the
|
||||
# finalizer of the sequence, but this makes destruction non-deterministic.
|
||||
zeroMem(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +%
|
||||
zeroMem(cast[pointer](cast[ByteAddress](result) +% align(GenericSeqSize, elemAlign) +%
|
||||
(newLen*%elemSize)), (result.len-%newLen) *% elemSize)
|
||||
else:
|
||||
result = s
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue