Minor changes and fixes

This commit is contained in:
Mattia Giambirtone 2022-08-18 11:15:55 +02:00
parent ae6da275fa
commit 95315a0094
2 changed files with 37 additions and 37 deletions

View File

@ -25,7 +25,7 @@ import ../frontend/meta/bytecode
import ../util/multibyte
when debugVM or debugMem:
when debugVM or debugMem or debugGC:
import std/strformat
import std/terminal
@ -97,7 +97,6 @@ proc collect*(self: PeonGC)
proc reallocate*(self: PeonGC, p: pointer, oldSize: int, newSize: int): pointer =
## Simple wrapper around realloc/dealloc
self.bytesAllocated.total += newSize - oldSize
self.bytesAllocated.current += newSize - oldSize
if self.bytesAllocated.current > self.nextGC:
self.collect()
@ -110,6 +109,7 @@ proc reallocate*(self: PeonGC, p: pointer, oldSize: int, newSize: int): pointer
echo "DEBUG - Memory manager: Deallocating 1 byte of memory"
dealloc(p)
elif (oldSize > 0 and not p.isNil() and newSize > oldSize) or oldSize == 0:
self.bytesAllocated.total += newSize - oldSize
when debugStressGC:
self.collect()
when debugMem:
@ -127,7 +127,6 @@ proc reallocate*(self: PeonGC, p: pointer, oldSize: int, newSize: int): pointer
elif oldSize > 0 and p.isNil():
echo &"DEBUG - Memory manager: Warning, asked to realloc() nil pointer from {oldSize} to {newSize} bytes, ignoring request"
except NilAccessDefect:
raise
stderr.write("Peon: could not manage memory, segmentation fault\n")
quit(139) # For now, there's not much we can do if we can't get the memory we need, so we exit
@ -173,33 +172,32 @@ proc mark(self: ptr HeapObject): bool =
return true
proc mark(self: PeonGC): seq[ptr HeapObject] =
## Marks objects *not* to be
proc markRoots(self: PeonGC): seq[ptr HeapObject] =
## Marks root objects *not* to be
## collected by the GC and returns
## them
## their addresses
# Unlike what bob does in his book,
# we keep track of objects in a different
# way due to how the whole thing is designed.
# Specifically, we don't have neat structs for
# all peon objects
# When we allocate() an object, we keep track
# of the box it created along with its type and
# other metadata, as well as the address of said
# box. Then, we can go through the various sources
# of roots in the VM, see if they match any pointers
# we already know about (using a hash set so it's
# really fast), and then we can be sure that anything
# that's in the difference (i.e. mathematical set difference)
# between our full list of pointers and the live ones
# is not a root object, so if it's not indirectly reachable
# through a root itself, it can be freed. I'm not sure if I
# can call this GC strategy precise, since technically there
# is a chance for a regular value to collide with one of the
# pointers we allocated and that would cause a memory leak,
# but with a 64-bit address-space it probably hardly matters,
# so I guess this is a mostly-precise Mark&Sweep collector
var live: HashSet[uint64] = initHashSet[uint64]()
# all peon objects: When we allocate() an object,
# we keep track of the small wrapper it created
# along with its type and other metadata. Then,
# we can go through the various sources of roots
# in the VM, see if they match any pointers we
# already know about (we store them a hash set so
# it's really fast), and then we can be sure that
# anything that's in the difference (i.e. mathematical
# set difference) between our full list of pointers
# and the live ones is not a root object, so if it's not
# indirectly reachable through a root itself, it can be
# freed. I'm not sure if I can call this GC strategy precise,
# since technically there is a chance for a regular value to
# collide with one of the pointers we allocated and that would
# cause a memory leak, but with a 64-bit address-space it probably
# hardly matters, so I guess this is a mostly-precise Mark&Sweep collector
var live = initHashSet[uint64]()
for obj in self.vm.calls:
if obj in self.pointers:
live.incl(obj)
@ -217,8 +215,8 @@ proc mark(self: PeonGC): seq[ptr HeapObject] =
if obj.mark():
result.add(obj)
when debugMem:
if result.len() > 0:
echo &"DEBUG - GC: Marking object: {result[^1][]}"
if obj.marked:
echo &"DEBUG - GC: Marking object: {obj[]}"
proc trace(self: PeonGC, roots: seq[ptr HeapObject]) =
@ -282,7 +280,7 @@ proc collect(self: PeonGC) =
let before = self.bytesAllocated.current
when debugGC:
echo "DEBUG - GC: Starting collection cycle"
self.trace(self.mark())
self.trace(self.markRoots())
self.sweep()
self.nextGC = self.bytesAllocated.current * HeapGrowFactor
when debugGC:

View File

@ -14,12 +14,23 @@
## Peon's main executable
# Our stuff
import frontend/lexer as l
import frontend/parser as p
import frontend/compiler as c
import backend/vm as v
import util/serializer as s
import util/debugger
import util/symbols
import config
# Builtins & external libs
import std/strformat
import std/strutils
import std/terminal
import std/parseopt
import std/times
when debugSerializer:
import std/times
import std/os
# Thanks art <3
@ -30,15 +41,6 @@ import jale/plugin/editor_history
import jale/keycodes
import jale/multiline
# Our stuff
import frontend/lexer as l
import frontend/parser as p
import frontend/compiler as c
import backend/vm as v
import util/serializer as s
import util/debugger
import util/symbols
import config
# Forward declarations
proc getLineEditor: LineEditor