Skip to content

Commit 8fdc291

Browse files
committed
fixes the tracking of 'occupied memory'
1 parent fcd4cd8 commit 8fdc291

File tree

1 file changed

+96
-6
lines changed

1 file changed

+96
-6
lines changed

lib/system/alloc.nim

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ type
104104
slBitmap: array[RealFli, uint32]
105105
matrix: array[RealFli, array[MaxSli, PBigChunk]]
106106
llmem: PLLChunk
107-
currMem, maxMem, freeMem: int # memory sizes (allocated from OS)
107+
currMem, maxMem, freeMem, occ: int # memory sizes (allocated from OS)
108108
lastSize: int # needed for the case that OS gives us pages linearly
109109
chunkStarts: IntSet
110110
root, deleted, last, freeAvlNodes: PAvlNode
@@ -421,7 +421,7 @@ const nimMaxHeap {.intdefine.} = 0
421421
proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
422422
when not defined(emscripten):
423423
if not a.blockChunkSizeIncrease:
424-
let usedMem = a.currMem # - a.freeMem
424+
let usedMem = a.occ #a.currMem # - a.freeMem
425425
when nimMaxHeap != 0:
426426
if usedMem > nimMaxHeap * 1024 * 1024:
427427
raiseOutOfMem()
@@ -567,7 +567,6 @@ proc splitChunk(a: var MemRegion, c: PBigChunk, size: int) =
567567
addChunkToMatrix(a, rest)
568568

569569
proc getBigChunk(a: var MemRegion, size: int): PBigChunk =
570-
# use first fit for now:
571570
sysAssert(size > 0, "getBigChunk 2")
572571
var size = size # roundup(size, PageSize)
573572
var fl, sl: int
@@ -627,6 +626,85 @@ else:
627626
c = c.next
628627
result = true
629628

629+
when false:
630+
var
631+
rsizes: array[50_000, int]
632+
rsizesLen: int
633+
634+
proc trackSize(size: int) =
635+
rsizes[rsizesLen] = size
636+
inc rsizesLen
637+
638+
proc untrackSize(size: int) =
639+
for i in 0 .. rsizesLen-1:
640+
if rsizes[i] == size:
641+
rsizes[i] = rsizes[rsizesLen-1]
642+
dec rsizesLen
643+
return
644+
c_fprintf(stdout, "%ld\n", size)
645+
sysAssert(false, "untracked size!")
646+
else:
647+
template trackSize(x) = discard
648+
template untrackSize(x) = discard
649+
650+
when false:
651+
# not yet used by the GCs
652+
proc rawTryAlloc(a: var MemRegion; requestedSize: int): pointer =
653+
sysAssert(allocInv(a), "rawAlloc: begin")
654+
sysAssert(roundup(65, 8) == 72, "rawAlloc: roundup broken")
655+
sysAssert(requestedSize >= sizeof(FreeCell), "rawAlloc: requested size too small")
656+
var size = roundup(requestedSize, MemAlign)
657+
inc a.occ, size
658+
trackSize(size)
659+
sysAssert(size >= requestedSize, "insufficient allocated size!")
660+
#c_fprintf(stdout, "alloc; size: %ld; %ld\n", requestedSize, size)
661+
if size <= SmallChunkSize-smallChunkOverhead():
662+
# allocate a small block: for small chunks, we use only its next pointer
663+
var s = size div MemAlign
664+
var c = a.freeSmallChunks[s]
665+
if c == nil:
666+
result = nil
667+
else:
668+
sysAssert c.size == size, "rawAlloc 6"
669+
if c.freeList == nil:
670+
sysAssert(c.acc + smallChunkOverhead() + size <= SmallChunkSize,
671+
"rawAlloc 7")
672+
result = cast[pointer](cast[ByteAddress](addr(c.data)) +% c.acc)
673+
inc(c.acc, size)
674+
else:
675+
result = c.freeList
676+
sysAssert(c.freeList.zeroField == 0, "rawAlloc 8")
677+
c.freeList = c.freeList.next
678+
dec(c.free, size)
679+
sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 9")
680+
if c.free < size:
681+
listRemove(a.freeSmallChunks[s], c)
682+
sysAssert(allocInv(a), "rawAlloc: end listRemove test")
683+
sysAssert(((cast[ByteAddress](result) and PageMask) - smallChunkOverhead()) %%
684+
size == 0, "rawAlloc 21")
685+
sysAssert(allocInv(a), "rawAlloc: end small size")
686+
else:
687+
inc size, bigChunkOverhead()
688+
var fl, sl: int
689+
mappingSearch(size, fl, sl)
690+
sysAssert((size and PageMask) == 0, "getBigChunk: unaligned chunk")
691+
let c = findSuitableBlock(a, fl, sl)
692+
if c != nil:
693+
removeChunkFromMatrix2(a, c, fl, sl)
694+
if c.size >= size + PageSize:
695+
splitChunk(a, c, size)
696+
# set 'used' to to true:
697+
c.prevSize = 1
698+
incl(a, a.chunkStarts, pageIndex(c))
699+
dec(a.freeMem, size)
700+
result = addr(c.data)
701+
sysAssert((cast[ByteAddress](c) and (MemAlign-1)) == 0, "rawAlloc 13")
702+
sysAssert((cast[ByteAddress](c) and PageMask) == 0, "rawAlloc: Not aligned on a page boundary")
703+
if a.root == nil: a.root = getBottom(a)
704+
add(a, a.root, cast[ByteAddress](result), cast[ByteAddress](result)+%size)
705+
else:
706+
result = nil
707+
630708
proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
631709
sysAssert(allocInv(a), "rawAlloc: begin")
632710
sysAssert(roundup(65, 8) == 72, "rawAlloc: roundup broken")
@@ -676,6 +754,8 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
676754
sysAssert(((cast[ByteAddress](result) and PageMask) - smallChunkOverhead()) %%
677755
size == 0, "rawAlloc 21")
678756
sysAssert(allocInv(a), "rawAlloc: end small size")
757+
inc a.occ, size
758+
trackSize(c.size)
679759
else:
680760
size = requestedSize + bigChunkOverhead() # roundup(requestedSize+bigChunkOverhead(), PageSize)
681761
# allocate a large block
@@ -687,6 +767,8 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
687767
sysAssert((cast[ByteAddress](c) and PageMask) == 0, "rawAlloc: Not aligned on a page boundary")
688768
if a.root == nil: a.root = getBottom(a)
689769
add(a, a.root, cast[ByteAddress](result), cast[ByteAddress](result)+%size)
770+
inc a.occ, c.size
771+
trackSize(c.size)
690772
sysAssert(isAccessible(a, result), "rawAlloc 14")
691773
sysAssert(allocInv(a), "rawAlloc: end")
692774
when logAlloc: cprintf("var pointer_%p = alloc(%ld)\n", result, requestedSize)
@@ -703,6 +785,9 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
703785
# `p` is within a small chunk:
704786
var c = cast[PSmallChunk](c)
705787
var s = c.size
788+
dec a.occ, s
789+
untrackSize(s)
790+
sysAssert a.occ >= 0, "rawDealloc: negative occupied memory (case A)"
706791
sysAssert(((cast[ByteAddress](p) and PageMask) - smallChunkOverhead()) %%
707792
s == 0, "rawDealloc 3")
708793
var f = cast[ptr FreeCell](p)
@@ -733,6 +818,9 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
733818
when overwriteFree: c_memset(p, -1'i32, c.size -% bigChunkOverhead())
734819
# free big chunk
735820
var c = cast[PBigChunk](c)
821+
dec a.occ, c.size
822+
untrackSize(c.size)
823+
sysAssert a.occ >= 0, "rawDealloc: negative occupied memory (case B)"
736824
a.deleted = getBottom(a)
737825
del(a, a.root, cast[int](addr(c.data)))
738826
freeBigChunk(a, c)
@@ -851,7 +939,8 @@ proc deallocOsPages(a: var MemRegion) =
851939
proc getFreeMem(a: MemRegion): int {.inline.} = result = a.freeMem
852940
proc getTotalMem(a: MemRegion): int {.inline.} = result = a.currMem
853941
proc getOccupiedMem(a: MemRegion): int {.inline.} =
854-
result = a.currMem - a.freeMem
942+
result = a.occ
943+
# a.currMem - a.freeMem
855944

856945
# ---------------------- thread memory region -------------------------------
857946

@@ -893,7 +982,7 @@ template instantiateForRegion(allocator: untyped) =
893982
#sysAssert(result == countFreeMem())
894983

895984
proc getTotalMem(): int = return allocator.currMem
896-
proc getOccupiedMem(): int = return getTotalMem() - getFreeMem()
985+
proc getOccupiedMem(): int = return allocator.occ #getTotalMem() - getFreeMem()
897986
proc getMaxMem*(): int = return getMaxMem(allocator)
898987

899988
# -------------------- shared heap region ----------------------------------
@@ -944,7 +1033,8 @@ template instantiateForRegion(allocator: untyped) =
9441033
sharedMemStatsShared(sharedHeap.currMem)
9451034

9461035
proc getOccupiedSharedMem(): int =
947-
sharedMemStatsShared(sharedHeap.currMem - sharedHeap.freeMem)
1036+
sharedMemStatsShared(sharedHeap.occ)
1037+
#sharedMemStatsShared(sharedHeap.currMem - sharedHeap.freeMem)
9481038
{.pop.}
9491039

9501040
{.pop.}

0 commit comments

Comments
 (0)