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

View File

@ -14,12 +14,23 @@
## Peon's main executable ## 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 # Builtins & external libs
import std/strformat import std/strformat
import std/strutils import std/strutils
import std/terminal import std/terminal
import std/parseopt import std/parseopt
import std/times when debugSerializer:
import std/times
import std/os import std/os
# Thanks art <3 # Thanks art <3
@ -30,15 +41,6 @@ import jale/plugin/editor_history
import jale/keycodes import jale/keycodes
import jale/multiline 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 # Forward declarations
proc getLineEditor: LineEditor proc getLineEditor: LineEditor