new runtime: added typelayouts.nim

This commit is contained in:
Andreas Rumpf 2018-01-04 15:59:03 +01:00
commit 2e635ab28c
3 changed files with 64 additions and 17 deletions

View file

@ -9,23 +9,66 @@
## Default ref implementation used by Nim's core.
import allocators
# We cannot use the allocator interface here as we require a heap walker to
# exist. Thus we import 'alloc' directly here to get our own heap that is
# all under the GC's control and can use the ``allObjects`` iterator which
# is crucial for the "sweep" phase.
import typelayouts, alloc
type
TracingGc = ptr object of Allocator
visit*: proc (fieldAddr: ptr pointer; a: Allocator) {.nimcall.}
GcColor = enum
white = 0, black = 1, grey = 2 ## to flip the meaning of white/black
## perform (1 - col)
GcHeader = object
t: ptr TypeLayout
color: GcColor
Cell = ptr GcHeader
GcFrame {.core.} = object
prev: ptr GcFrame
marker: proc (self: GcFrame; a: Allocator)
Phase = enum
None, Marking, Sweeping
GcHeap = object
r: MemRegion
phase: Phase
currBlack, currWhite: GcColor
greyStack: seq[Cell]
var
gch {.threadvar.}: GcHeap
proc `=trace`[T](a: ref T) =
if not marked(a):
mark(a)
`=trace`(a[])
template usrToCell(p: pointer): Cell =
template cellToUsr(cell: Cell): pointer =
cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(GcHeader)))
template usrToCell(usr: pointer): Cell =
cast[Cell](cast[ByteAddress](usr)-%ByteAddress(sizeof(GcHeader)))
template markGrey(x: Cell) =
if x.color == gch.currWhite and phase == Marking:
x.color = grey
add(gch.greyStack, x)
proc `=`[T](dest: var ref T; src: ref T) =
## full write barrier implementation.
if src != nil:
let s = usrToCell(src)
markGrey(s)
system.`=`(dest, src)
proc linkGcFrame(f: ptr GcFrame) {.core.}
proc unlinkGcFrame() {.core.}
@ -38,8 +81,7 @@ proc registerThreadvar(p: pointer; t: ptr TypeLayout) {.core.}
proc unregisterThreadvar(p: pointer; t: ptr TypeLayout) {.core.}
proc newImpl(t: ptr TypeLayout): pointer =
let a = getCurrentAllocator()
let r = cast[ptr GcHeader](a.alloc(a, t.size + sizeof(GcHeader), t.alignment))
let r = cast[Cell](rawAlloc(t.size + sizeof(GcHeader)))
r.typ = t
result = r +! sizeof(GcHeader)