summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-09-16 23:54:21 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-09-16 23:54:31 +0200
commit62aa1a3cfe904da7309f0b067635bef5d2d57077 (patch)
tree5eb6ebbdab0c60d9a26a5fc2d64650f745cedd54
parent77c6425e65cf0ee2d487e778a159b67669a48489 (diff)
downloadNim-62aa1a3cfe904da7309f0b067635bef5d2d57077.tar.gz
gc:destructors progress
-rw-r--r--compiler/sempass2.nim1
-rw-r--r--lib/system.nim4
-rw-r--r--lib/system/gc_hooks.nim53
-rw-r--r--lib/system/hti.nim14
-rw-r--r--lib/system/mmdisp.nim6
-rw-r--r--lib/system/repr.nim2
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)