diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-01-04 15:59:03 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-01-04 15:59:03 +0100 |
commit | 2e635ab28cb60be5e63e01ecf074596ccc385696 (patch) | |
tree | 9f500368898e755323aa08c0b8959c4eab08f9fc /lib | |
parent | 80fef7c8182f8b1427697ef923266094bb49abb2 (diff) | |
download | Nim-2e635ab28cb60be5e63e01ecf074596ccc385696.tar.gz |
new runtime: added typelayouts.nim
Diffstat (limited to 'lib')
-rw-r--r-- | lib/core/allocators.nim | 14 | ||||
-rw-r--r-- | lib/core/refs.nim | 48 | ||||
-rw-r--r-- | lib/core/typelayouts.nim | 19 |
3 files changed, 64 insertions, 17 deletions
diff --git a/lib/core/allocators.nim b/lib/core/allocators.nim index 093da296a..d6608a203 100644 --- a/lib/core/allocators.nim +++ b/lib/core/allocators.nim @@ -8,24 +8,10 @@ # type - TypeLayout* = object - size*, alignment*: int - destructor*: proc (self: pointer; a: Allocator) {.nimcall.} - trace*: proc (self: pointer; a: Allocator) {.nimcall.} - when false: - construct*: proc (self: pointer; a: Allocator) {.nimcall.} - copy*, deepcopy*, sink*: proc (self, other: pointer; a: Allocator) {.nimcall.} - Allocator* {.inheritable.} = ptr object alloc*: proc (a: Allocator; size: int; alignment = 8): pointer {.nimcall.} dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall.} realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall.} - visit*: proc (fieldAddr: ptr pointer; a: Allocator) {.nimcall.} - -#proc allocArray(a: Allocator; L, elem: TypeLayout; n: int): pointer -#proc deallocArray(a: Allocator; p: pointer; L, elem: TypeLayout; n: int) - -proc getTypeLayout*(t: typedesc): ptr TypeLayout {.magic: "getTypeLayout".} var currentAllocator {.threadvar.}: Allocator diff --git a/lib/core/refs.nim b/lib/core/refs.nim index 71c999a74..e1575b68c 100644 --- a/lib/core/refs.nim +++ b/lib/core/refs.nim @@ -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) diff --git a/lib/core/typelayouts.nim b/lib/core/typelayouts.nim new file mode 100644 index 000000000..445ce77c4 --- /dev/null +++ b/lib/core/typelayouts.nim @@ -0,0 +1,19 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +type + TypeLayout* = object + size*, alignment*: int + destructor*: proc (self: pointer; a: Allocator) {.nimcall.} + trace*: proc (self: pointer; a: Allocator) {.nimcall.} + when false: + construct*: proc (self: pointer; a: Allocator) {.nimcall.} + copy*, deepcopy*, sink*: proc (self, other: pointer; a: Allocator) {.nimcall.} + +proc getTypeLayout(t: typedesc): ptr TypeLayout {.magic: "getTypeLayout".} |