Minor changes and fixes
This commit is contained in:
parent
ae6da275fa
commit
95315a0094
|
@ -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:
|
||||
|
|
22
src/main.nim
22
src/main.nim
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue