mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 22:33:49 +00:00
new runtime: added typelayouts.nim
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
19
lib/core/typelayouts.nim
Normal file
19
lib/core/typelayouts.nim
Normal file
@@ -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".}
|
||||
Reference in New Issue
Block a user