summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2021-05-12 22:00:37 +0200
committerGitHub <noreply@github.com>2021-05-12 22:00:37 +0200
commit3bc625aff1664eb4206ae90d0a132c8f717e651d (patch)
tree5ffd5edee1fd4dbc1cc76f00f1dd3131dd332076 /lib
parent60b4fa71a8ce1abc43b6f6bba3c3aa1f69b15092 (diff)
downloadNim-3bc625aff1664eb4206ae90d0a132c8f717e651d.tar.gz
ORC: progress (#18000)
* ORC: progress

* ORC: bugfix; don't follow acyclic data even if only at runtime the subtype is marked as acyclic

* progress

* minor style changes
Diffstat (limited to 'lib')
-rw-r--r--lib/std/packedsets.nim2
-rw-r--r--lib/system.nim1
-rw-r--r--lib/system/orc.nim31
3 files changed, 24 insertions, 10 deletions
diff --git a/lib/std/packedsets.nim b/lib/std/packedsets.nim
index 2b5896be0..e209d2aae 100644
--- a/lib/std/packedsets.nim
+++ b/lib/std/packedsets.nim
@@ -38,7 +38,7 @@ const
   IntMask = 1 shl IntShift - 1
 
 type
-  Trunk = ref object
+  Trunk {.acyclic.} = ref object
     next: Trunk                                 # all nodes are connected with this pointer
     key: int                                    # start address at bit 0
     bits: array[0..IntsPerTrunk - 1, BitScalar] # a bit vector
diff --git a/lib/system.nim b/lib/system.nim
index aecda4a70..9317c3440 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1805,6 +1805,7 @@ when not defined(js) and defined(nimV2):
       traceImpl: pointer
       disposeImpl: pointer
       typeInfoV1: pointer # for backwards compat, usually nil
+      flags: int
     PNimTypeV2 = ptr TNimTypeV2
 
 when notJSnotNims and defined(nimSeqsV2):
diff --git a/lib/system/orc.nim b/lib/system/orc.nim
index 8a62ef4bb..df81afcf1 100644
--- a/lib/system/orc.nim
+++ b/lib/system/orc.nim
@@ -109,9 +109,21 @@ proc free(s: Cell; desc: PNimTypeV2) {.inline.} =
 
   nimRawDispose(p, desc.align)
 
+template orcAssert(cond, msg) =
+  when logOrc:
+    if not cond:
+      cfprintf(cstderr, "[Bug!] %s\n", msg)
+      quit 1
+
+when logOrc:
+  proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
+
 proc nimTraceRef(q: pointer; desc: PNimTypeV2; env: pointer) {.compilerRtl, inline.} =
   let p = cast[ptr pointer](q)
   if p[] != nil:
+
+    orcAssert strstr(desc.name, "TType") == nil, "following a TType but it's acyclic!"
+
     var j = cast[ptr GcEnv](env)
     j.traceStack.add(head p[], desc)
 
@@ -121,12 +133,6 @@ proc nimTraceRefDyn(q: pointer; env: pointer) {.compilerRtl, inline.} =
     var j = cast[ptr GcEnv](env)
     j.traceStack.add(head p[], cast[ptr PNimTypeV2](p[])[])
 
-template orcAssert(cond, msg) =
-  when logOrc:
-    if not cond:
-      cfprintf(cstderr, "[Bug!] %s\n", msg)
-      quit 1
-
 var
   roots {.threadvar.}: CellSeq
 
@@ -402,6 +408,8 @@ proc registerCycle(s: Cell; desc: PNimTypeV2) =
   when logOrc:
     writeCell("[added root]", s, desc)
 
+  orcAssert strstr(desc.name, "TType") == nil, "added a TType as a root!"
+
 proc GC_runOrc* =
   ## Forces a cycle collection pass.
   collectCycles()
@@ -436,10 +444,15 @@ proc GC_disableMarkAndSweep*() =
   ## For `--gc:orc` an alias for `GC_disableOrc`.
   GC_disableOrc()
 
+const
+  acyclicFlag = 1 # see also cggtypes.nim, proc genTypeInfoV2Impl
+
 when optimizedOrc:
-  template markedAsCyclic(s: Cell): bool = (s.rc and maybeCycle) != 0
+  template markedAsCyclic(s: Cell; desc: PNimTypeV2): bool =
+    (desc.flags and acyclicFlag) == 0 and (s.rc and maybeCycle) != 0
 else:
-  template markedAsCyclic(s: Cell): bool = true
+  template markedAsCyclic(s: Cell; desc: PNimTypeV2): bool =
+    (desc.flags and acyclicFlag) == 0
 
 proc rememberCycle(isDestroyAction: bool; s: Cell; desc: PNimTypeV2) {.noinline.} =
   if isDestroyAction:
@@ -448,7 +461,7 @@ proc rememberCycle(isDestroyAction: bool; s: Cell; desc: PNimTypeV2) {.noinline.
   else:
     # do not call 'rememberCycle' again unless this cell
     # got an 'incRef' event:
-    if s.rootIdx == 0 and markedAsCyclic(s):
+    if s.rootIdx == 0 and markedAsCyclic(s, desc):
       s.setColor colBlack
       registerCycle(s, desc)