make the allocator take a special path for allocations bigger than 2GB; fixes #7120
This commit is contained in:
parent
c3d544221b
commit
6d4107b783
2 changed files with 30 additions and 2 deletions
|
|
@ -29,6 +29,8 @@ const
|
||||||
FliOffset = 6
|
FliOffset = 6
|
||||||
RealFli = MaxFli - FliOffset
|
RealFli = MaxFli - FliOffset
|
||||||
|
|
||||||
|
HugeChunkSize = int high(int32) - 1 # 2 GB, depends on TLSF's impl
|
||||||
|
|
||||||
type
|
type
|
||||||
PTrunk = ptr Trunk
|
PTrunk = ptr Trunk
|
||||||
Trunk = object
|
Trunk = object
|
||||||
|
|
@ -593,6 +595,26 @@ proc getBigChunk(a: var MemRegion, size: int): PBigChunk =
|
||||||
incl(a, a.chunkStarts, pageIndex(result))
|
incl(a, a.chunkStarts, pageIndex(result))
|
||||||
dec(a.freeMem, size)
|
dec(a.freeMem, size)
|
||||||
|
|
||||||
|
proc getHugeChunk(a: var MemRegion; size: int): PBigChunk =
|
||||||
|
result = cast[PBigChunk](osAllocPages(size))
|
||||||
|
incCurrMem(a, size)
|
||||||
|
# XXX add this to the heap links. But also remove it from it later.
|
||||||
|
when false: a.addHeapLink(result, size)
|
||||||
|
sysAssert((cast[ByteAddress](result) and PageMask) == 0, "getHugeChunk")
|
||||||
|
result.next = nil
|
||||||
|
result.prev = nil
|
||||||
|
result.size = size
|
||||||
|
# set 'used' to to true:
|
||||||
|
result.prevSize = 1
|
||||||
|
incl(a, a.chunkStarts, pageIndex(result))
|
||||||
|
|
||||||
|
proc freeHugeChunk(a: var MemRegion; c: PBigChunk) =
|
||||||
|
let size = c.size
|
||||||
|
sysAssert(size >= HugeChunkSize, "freeHugeChunk: invalid size")
|
||||||
|
excl(a.chunkStarts, pageIndex(c))
|
||||||
|
decCurrMem(a, size)
|
||||||
|
osDeallocPages(c, size)
|
||||||
|
|
||||||
proc getSmallChunk(a: var MemRegion): PSmallChunk =
|
proc getSmallChunk(a: var MemRegion): PSmallChunk =
|
||||||
var res = getBigChunk(a, PageSize)
|
var res = getBigChunk(a, PageSize)
|
||||||
sysAssert res.prev == nil, "getSmallChunk 1"
|
sysAssert res.prev == nil, "getSmallChunk 1"
|
||||||
|
|
@ -759,7 +781,8 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
|
||||||
else:
|
else:
|
||||||
size = requestedSize + bigChunkOverhead() # roundup(requestedSize+bigChunkOverhead(), PageSize)
|
size = requestedSize + bigChunkOverhead() # roundup(requestedSize+bigChunkOverhead(), PageSize)
|
||||||
# allocate a large block
|
# allocate a large block
|
||||||
var c = getBigChunk(a, size)
|
var c = if size >= HugeChunkSize: getHugeChunk(a, size)
|
||||||
|
else: getBigChunk(a, size)
|
||||||
sysAssert c.prev == nil, "rawAlloc 10"
|
sysAssert c.prev == nil, "rawAlloc 10"
|
||||||
sysAssert c.next == nil, "rawAlloc 11"
|
sysAssert c.next == nil, "rawAlloc 11"
|
||||||
result = addr(c.data)
|
result = addr(c.data)
|
||||||
|
|
@ -823,7 +846,8 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
|
||||||
sysAssert a.occ >= 0, "rawDealloc: negative occupied memory (case B)"
|
sysAssert a.occ >= 0, "rawDealloc: negative occupied memory (case B)"
|
||||||
a.deleted = getBottom(a)
|
a.deleted = getBottom(a)
|
||||||
del(a, a.root, cast[int](addr(c.data)))
|
del(a, a.root, cast[int](addr(c.data)))
|
||||||
freeBigChunk(a, c)
|
if c.size >= HugeChunkSize: freeHugeChunk(a, c)
|
||||||
|
else: freeBigChunk(a, c)
|
||||||
sysAssert(allocInv(a), "rawDealloc: end")
|
sysAssert(allocInv(a), "rawDealloc: end")
|
||||||
when logAlloc: cprintf("dealloc(pointer_%p)\n", p)
|
when logAlloc: cprintf("dealloc(pointer_%p)\n", p)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@ proc main =
|
||||||
quit "could not serve request!"
|
quit "could not serve request!"
|
||||||
dealloc p
|
dealloc p
|
||||||
# c_fprintf(stdout, "iteration: %ld size: %ld\n", i, size)
|
# c_fprintf(stdout, "iteration: %ld size: %ld\n", i, size)
|
||||||
|
when defined(cpu64):
|
||||||
|
# bug #7120
|
||||||
|
var x = alloc(((1 shl 29) - 4) * 8)
|
||||||
|
dealloc x
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue