diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-09-16 23:54:21 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-09-16 23:54:31 +0200 |
commit | 62aa1a3cfe904da7309f0b067635bef5d2d57077 (patch) | |
tree | 5eb6ebbdab0c60d9a26a5fc2d64650f745cedd54 | |
parent | 77c6425e65cf0ee2d487e778a159b67669a48489 (diff) | |
download | Nim-62aa1a3cfe904da7309f0b067635bef5d2d57077.tar.gz |
gc:destructors progress
-rw-r--r-- | compiler/sempass2.nim | 1 | ||||
-rw-r--r-- | lib/system.nim | 4 | ||||
-rw-r--r-- | lib/system/gc_hooks.nim | 53 | ||||
-rw-r--r-- | lib/system/hti.nim | 14 | ||||
-rw-r--r-- | lib/system/mmdisp.nim | 6 | ||||
-rw-r--r-- | lib/system/repr.nim | 2 |
6 files changed, 72 insertions, 8 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 9957e772e..c114dde95 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -751,6 +751,7 @@ proc track(tracked: PEffects, n: PNode) = discard else: message(tracked.config, arg.info, warnProveInit, $arg) + createTypeBoundOps(tracked.graph, tracked.c, n[1].typ.lastSon, n.info) for i in 0 ..< safeLen(n): track(tracked, n.sons[i]) of nkDotExpr: diff --git a/lib/system.nim b/lib/system.nim index ebea457dd..f12ab2e8d 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3226,7 +3226,7 @@ when not defined(nimscript) and hasAlloc: gcOptimizeTime, ## optimize for speed gcOptimizeSpace ## optimize for memory footprint - when not defined(JS) and not defined(nimV2): + when not defined(JS) and not defined(gcDestructors): proc GC_disable*() {.rtl, inl, benign.} ## Disables the GC. If called `n` times, `n` calls to `GC_enable` ## are needed to reactivate the GC. @@ -3589,7 +3589,7 @@ when not defined(JS): #and not defined(nimscript): {.push stack_trace: off, profiler:off.} when hasAlloc: - when not defined(gcRegions) and not defined(nimV2): + when not defined(gcRegions) and not defined(gcDestructors): proc initGC() {.gcsafe.} proc initStackBottom() {.inline, compilerproc.} = diff --git a/lib/system/gc_hooks.nim b/lib/system/gc_hooks.nim new file mode 100644 index 000000000..70f02e657 --- /dev/null +++ b/lib/system/gc_hooks.nim @@ -0,0 +1,53 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2019 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Hooks for memory management. Can be used to implement custom garbage +## collectors etc. + +type + GlobalMarkerProc = proc () {.nimcall, benign, raises: [], tags: [].} +var + globalMarkersLen: int + globalMarkers: array[0..3499, GlobalMarkerProc] + threadLocalMarkersLen: int + threadLocalMarkers: array[0..3499, GlobalMarkerProc] + +proc nimRegisterGlobalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} = + if globalMarkersLen <= high(globalMarkers): + globalMarkers[globalMarkersLen] = markerProc + inc globalMarkersLen + else: + cstderr.rawWrite("[GC] cannot register global variable; too many global variables") + quit 1 + +proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} = + if threadLocalMarkersLen <= high(threadLocalMarkers): + threadLocalMarkers[threadLocalMarkersLen] = markerProc + inc threadLocalMarkersLen + else: + cstderr.rawWrite("[GC] cannot register thread local variable; too many thread local variables") + quit 1 + +proc traverseGlobals*() = + for i in 0..globalMarkersLen-1: + globalMarkers[i]() + +proc traverseThreadLocals*() = + for i in 0..threadLocalMarkersLen-1: + threadLocalMarkers[i]() + +var + newObjHook*: proc (typ: PNimType, size: int): pointer {.nimcall, tags: [], raises: [], gcsafe.} + traverseObjHook*: proc (p: pointer, op: int) {.nimcall, tags: [], raises: [], gcsafe.} + +proc nimGCvisit(p: pointer, op: int) {.inl, compilerRtl.} = + traverseObjHook(p, op) + +proc newObj(typ: PNimType, size: int): pointer {.inl, compilerRtl.} = + result = newObjHook(typ, size) diff --git a/lib/system/hti.nim b/lib/system/hti.nim index 3cb73f6d4..446468b8d 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -87,20 +87,28 @@ type ntfEnumHole = 2 # enum has holes and thus `$` for them needs the slow # version TNimType {.compilerproc.} = object + when defined(gcDestructors): + head*: pointer size: int kind: TNimKind flags: set[TNimTypeFlag] base: ptr TNimType node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum - finalizer: pointer # the finalizer for the type - marker: proc (p: pointer, op: int) {.nimcall, benign.} # marker proc for GC + finalizer*: pointer # the finalizer for the type + marker*: proc (p: pointer, op: int) {.nimcall, benign.} # marker proc for GC deepcopy: proc (p: pointer): pointer {.nimcall, benign.} when defined(nimTypeNames): name: cstring nextType: ptr TNimType instances: int # count the number of instances sizes: int # sizes of all instances in bytes - PNimType = ptr TNimType + +when defined(gcDestructors): + type + PNimType* = ptr TNimType +else: + type + PNimType = ptr TNimType when defined(nimTypeNames): # Declare this variable only once in system.nim diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 0d1bb1767..d2edacce7 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -505,10 +505,12 @@ else: elif defined(gcRegions): # XXX due to bootstrapping reasons, we cannot use compileOption("gc", "stack") here include "system/gc_regions" - elif defined(nimV2): + elif defined(nimV2) or defined(gcDestructors): var allocator {.rtlThreadVar.}: MemRegion instantiateForRegion(allocator) - elif defined(gcMarkAndSweep) or defined(gcDestructors): + when defined(gcDestructors): + include "system/gc_hooks" + elif defined(gcMarkAndSweep): # XXX use 'compileOption' here include "system/gc_ms" else: diff --git a/lib/system/repr.nim b/lib/system/repr.nim index a3212020a..97975277b 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -226,7 +226,7 @@ when not defined(useNimRtl): cl: var ReprClosure) = # we know that p is not nil here: when declared(CellSet): - when defined(boehmGC) or defined(gogc) or defined(nogc): + when defined(boehmGC) or defined(gogc) or defined(nogc) or defined(gcDestructors): var cell = cast[PCell](p) else: var cell = usrToCell(p) |