Improved GC debugging
This commit is contained in:
parent
d09b72694e
commit
6f444582a4
|
@ -68,6 +68,7 @@ type
|
||||||
## this system and is not handled
|
## this system and is not handled
|
||||||
## manually by the VM
|
## manually by the VM
|
||||||
bytesAllocated: tuple[total, current: int]
|
bytesAllocated: tuple[total, current: int]
|
||||||
|
cycles: int
|
||||||
nextGC: int
|
nextGC: int
|
||||||
pointers: HashSet[uint64]
|
pointers: HashSet[uint64]
|
||||||
objects: seq[ptr HeapObject]
|
objects: seq[ptr HeapObject]
|
||||||
|
@ -108,6 +109,7 @@ proc newPeonGC*: PeonGC =
|
||||||
result.bytesAllocated = (0, 0)
|
result.bytesAllocated = (0, 0)
|
||||||
result.objects = @[]
|
result.objects = @[]
|
||||||
result.nextGC = FirstGC
|
result.nextGC = FirstGC
|
||||||
|
result.cycles = 0
|
||||||
|
|
||||||
|
|
||||||
proc collect*(self: var PeonVM)
|
proc collect*(self: var PeonVM)
|
||||||
|
@ -121,18 +123,18 @@ proc reallocate*(self: var PeonVM, p: pointer, oldSize: int, newSize: int): poin
|
||||||
if newSize == 0 and not p.isNil():
|
if newSize == 0 and not p.isNil():
|
||||||
when debugMem:
|
when debugMem:
|
||||||
if oldSize > 1:
|
if oldSize > 1:
|
||||||
echo &"DEBUG - Memory manager: Deallocating {oldSize} bytes of memory"
|
echo &"DEBUG - MM: Deallocating {oldSize} bytes of memory"
|
||||||
else:
|
else:
|
||||||
echo "DEBUG - Memory manager: Deallocating 1 byte of memory"
|
echo "DEBUG - MM: Deallocating 1 byte of memory"
|
||||||
elif (oldSize > 0 and not p.isNil() and newSize > oldSize) or oldSize == 0:
|
elif (oldSize > 0 and not p.isNil() and newSize > oldSize) or oldSize == 0:
|
||||||
when debugMem:
|
when debugMem:
|
||||||
if oldSize == 0:
|
if oldSize == 0:
|
||||||
if newSize > 1:
|
if newSize > 1:
|
||||||
echo &"DEBUG - Memory manager: Allocating {newSize} bytes of memory"
|
echo &"DEBUG - MM: Allocating {newSize} bytes of memory"
|
||||||
else:
|
else:
|
||||||
echo "DEBUG - Memory manager: Allocating 1 byte of memory"
|
echo "DEBUG - MM: Allocating 1 byte of memory"
|
||||||
else:
|
else:
|
||||||
echo &"DEBUG - Memory manager: Resizing {oldSize} bytes of memory to {newSize} bytes"
|
echo &"DEBUG - M: Resizing {oldSize} bytes of memory to {newSize} bytes"
|
||||||
self.gc.bytesAllocated.total += newSize - oldSize
|
self.gc.bytesAllocated.total += newSize - oldSize
|
||||||
when debugStressGC:
|
when debugStressGC:
|
||||||
self.collect()
|
self.collect()
|
||||||
|
@ -171,19 +173,20 @@ proc allocate*(self: var PeonVM, kind: ObjectKind, size: typedesc, count: int):
|
||||||
result = cast[ptr HeapObject](self.reallocate(nil, 0, sizeof(HeapObject)))
|
result = cast[ptr HeapObject](self.reallocate(nil, 0, sizeof(HeapObject)))
|
||||||
setkind(result[], kind, kind)
|
setkind(result[], kind, kind)
|
||||||
result.marked = false
|
result.marked = false
|
||||||
self.gc.bytesAllocated.total += sizeof(HeapObject)
|
|
||||||
self.gc.bytesAllocated.current += sizeof(HeapObject)
|
|
||||||
case kind:
|
case kind:
|
||||||
of String:
|
of String:
|
||||||
result.str = cast[ptr UncheckedArray[char]](self.reallocate(nil, 0, sizeof(size) * count))
|
result.str = cast[ptr UncheckedArray[char]](self.reallocate(nil, 0, sizeof(size) * count))
|
||||||
result.len = count
|
result.len = count
|
||||||
else:
|
else:
|
||||||
discard # TODO
|
discard # TODO
|
||||||
when debugAlloc:
|
|
||||||
echo &"DEBUG - GC: Allocated new object: {result[]}"
|
|
||||||
self.gc.bytesAllocated.current += sizeof(size) * count
|
|
||||||
self.gc.objects.add(result)
|
self.gc.objects.add(result)
|
||||||
self.gc.pointers.incl(cast[uint64](result))
|
self.gc.pointers.incl(cast[uint64](result))
|
||||||
|
when debugAlloc:
|
||||||
|
echo &"DEBUG - GC: Allocated new object: {result[]}"
|
||||||
|
echo &"DEBUG - GC: Current heap size: {self.gc.bytesAllocated.current}"
|
||||||
|
echo &"DEBUG - GC: Total bytes allocated: {self.gc.bytesAllocated.total}"
|
||||||
|
echo &"DEBUG - GC: Tracked objects: {self.gc.pointers.len()}"
|
||||||
|
echo &"DEBUG - GC: Completed GC cycles: {self.gc.cycles}"
|
||||||
|
|
||||||
|
|
||||||
proc mark(self: ptr HeapObject): bool =
|
proc mark(self: ptr HeapObject): bool =
|
||||||
|
@ -282,6 +285,11 @@ proc free(self: var PeonVM, obj: ptr HeapObject) =
|
||||||
discard # TODO
|
discard # TODO
|
||||||
self.free(HeapObject, obj)
|
self.free(HeapObject, obj)
|
||||||
self.gc.pointers.excl(cast[uint64](obj))
|
self.gc.pointers.excl(cast[uint64](obj))
|
||||||
|
when debugAlloc:
|
||||||
|
echo &"DEBUG - GC: Current heap size: {self.gc.bytesAllocated.current}"
|
||||||
|
echo &"DEBUG - GC: Total bytes allocated: {self.gc.bytesAllocated.total}"
|
||||||
|
echo &"DEBUG - GC: Tracked objects: {self.gc.pointers.len()}"
|
||||||
|
echo &"DEBUG - GC: Completed GC cycles: {self.gc.cycles}"
|
||||||
|
|
||||||
|
|
||||||
proc sweep(self: var PeonVM) =
|
proc sweep(self: var PeonVM) =
|
||||||
|
@ -329,6 +337,7 @@ proc collect(self: var PeonVM) =
|
||||||
let before = self.gc.bytesAllocated.current
|
let before = self.gc.bytesAllocated.current
|
||||||
let time = getMonoTime().ticks().float() / 1_000_000
|
let time = getMonoTime().ticks().float() / 1_000_000
|
||||||
echo &"DEBUG - GC: Starting collection cycle at heap size {self.gc.bytesAllocated.current}"
|
echo &"DEBUG - GC: Starting collection cycle at heap size {self.gc.bytesAllocated.current}"
|
||||||
|
inc(self.gc.cycles)
|
||||||
self.trace(self.markRoots())
|
self.trace(self.markRoots())
|
||||||
self.sweep()
|
self.sweep()
|
||||||
self.gc.nextGC = self.gc.bytesAllocated.current * HeapGrowFactor
|
self.gc.nextGC = self.gc.bytesAllocated.current * HeapGrowFactor
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
|
|
||||||
var x = 1000000;
|
var x = 1;
|
||||||
var y = "just a test";
|
var y = "just a test";
|
||||||
print(y);
|
print(y);
|
||||||
print("Starting GC torture test");
|
print("Starting GC torture test");
|
||||||
|
|
Loading…
Reference in New Issue