summary refs log tree commit diff stats
path: root/doc
ModeNameSize
-rw-r--r--advopt.txt11024log stats plain blame
-rw-r--r--apis.md3876log stats plain blame
-rw-r--r--astspec.txt27766log stats plain blame
-rw-r--r--backends.md14939log stats plain blame
-rw-r--r--basicopt.txt2079log stats plain blame
-rw-r--r--contributing.md30070log stats plain blame
-rw-r--r--destructors.md21201log stats plain blame
-rw-r--r--docgen.md21912log stats plain blame
-rw-r--r--docgen_sample.nim263log stats plain blame
-rw-r--r--docs.md1338log stats plain blame
-rw-r--r--docstyle.md5839log stats plain blame
-rw-r--r--drnim.md5768log stats plain blame
-rw-r--r--effects.txt1229log stats plain blame
-rw-r--r--estp.md5459log stats plain blame
-rw-r--r--filelist.txt2838log stats plain blame
-rw-r--r--filters.md5847log stats plain blame
-rw-r--r--grammar.txt10193log stats plain blame
-rw-r--r--hcr.md7356log stats plain blame
-rw-r--r--idetools.md19877log stats plain blame
-rw-r--r--intern.md20802log stats plain blame
-rw-r--r--keywords.txt364log stats plain blame
-rw-r--r--koch.md3194log stats plain blame
-rw-r--r--lib.md20044log stats plain blame
-rw-r--r--manual.md258830log stats plain blame
d---------manual43log stats plain
-rw-r--r--manual_experimental.md60870log stats plain blame
-rw-r--r--manual_experimental_strictnotnil.md9091log stats plain blame
-rw-r--r--markdown_rst.md9601log stats plain blame
-rw-r--r--mm.md4033log stats plain blame
-rw-r--r--mytest.cfg583log stats plain blame
-rw-r--r--nep1.md11993log stats plain blame
-rw-r--r--nimc.md30931log stats plain blame
-rw-r--r--nimdoc.cls7603log stats plain blame
-rw-r--r--nimdoc.css52560log stats plain blame
-rw-r--r--nimfix.md1687log stats plain blame
-rw-r--r--nimgrep.md4353log stats plain blame
-rw-r--r--nimgrep_cmdline.txt6641log stats plain blame
-rw-r--r--niminst.md6756log stats plain blame
-rw-r--r--nims.md10168log stats plain blame
-rw-r--r--nimsuggest.md6480log stats plain blame
-rw-r--r--overview.md157log stats plain blame
-rw-r--r--packaging.md1927log stats plain blame
-rw-r--r--pegdocs.txt10363log stats plain blame
-rw-r--r--readme.txt280log stats plain blame
-rw-r--r--refc.md6365log stats plain blame
-rw-r--r--regexprs.txt13862log stats plain blame
-rw-r--r--rstcommon.rst1182log stats plain blame
-rw-r--r--sets_fragment.txt3241log stats plain blame
-rw-r--r--spawn.txt3730log stats plain blame
-rw-r--r--subexes.txt2867log stats plain blame
-rw-r--r--testament.md9910log stats plain blame
-rw-r--r--tools.md1694log stats plain blame
-rw-r--r--tut1.md60777log stats plain blame
-rw-r--r--tut2.md21951log stats plain blame
-rw-r--r--tut3.md11385log stats plain blame
lass="p">(c): untyped = c.rc and colorMask template setColor(c, col) = when col == colGreen: c.rc = c.rc and not colorMask else: c.rc = c.rc and not colorMask or col proc nimIncRefCyclic(p: pointer) {.compilerRtl, inl.} = let h = head(p) inc h.rc, rcIncrement h.setColor colYellow # mark as potential cycle! proc markCyclic*[T](x: ref T) {.inline.} = ## Mark the underlying object as a candidate for cycle collections. ## Experimental API. Do not use! let h = head(cast[pointer](x)) h.setColor colYellow type GcEnv = object traceStack: CellSeq jumpStack: CellSeq proc trace(s: Cell; desc: PNimType; j: var GcEnv) {.inline.} = if desc.traceImpl != nil: var p = s +! sizeof(RefHeader) cast[TraceProc](desc.traceImpl)(p, addr(j)) proc free(s: Cell; desc: PNimType) {.inline.} = when traceCollector: cprintf("[From ] %p rc %ld color %ld in jumpstack %ld\n", s, s.rc shr rcShift, s.color, s.rc and jumpStackFlag) let p = s +! sizeof(RefHeader) if desc.disposeImpl != nil: cast[DisposeProc](desc.disposeImpl)(p) nimRawDispose(p) proc collect(s: Cell; desc: PNimType; j: var GcEnv) = #[ Algorithm from the paper: Collect(S) = If (Color(S) == red) then RC(S) = 1; Color(S) = green; for T in Sons(S) do Remove(<S, T>); if (Color(T) == red) then Collect(T); free_list = S; (Whatever that really means...) ]# if s.color == colRed: s.setColor colGreen trace(s, desc, j) while j.traceStack.len > 0: let (p, desc) = j.traceStack.pop() let t = head(p[]) #Remove(<S, T>): p[] = nil if t.color == colRed: t.setColor colGreen trace(t, desc, j) free(t, desc) free(s, desc) #cprintf("[Cycle free] %p %ld\n", s, s.rc shr rcShift) proc markRed(s: Cell; desc: PNimType; j: var GcEnv) = if s.color != colRed: s.setColor colRed trace(s, desc, j) while j.traceStack.len > 0: let (p, desc) = j.traceStack.pop() let t = head(p[]) when traceCollector: cprintf("[Cycle dec] %p %ld color %ld in jumpstack %ld\n", t, t.rc shr rcShift, t.color, t.rc and jumpStackFlag) dec t.rc, rcIncrement if (t.rc and not rcMask) >= 0 and (t.rc and jumpStackFlag) == 0: t.rc = t.rc or jumpStackFlag when traceCollector: cprintf("[Now in jumpstack] %p %ld color %ld in jumpstack %ld\n", t, t.rc shr rcShift, t.color, t.rc and jumpStackFlag) j.jumpStack.add(p, desc) if t.color != colRed: t.setColor colRed trace(t, desc, j) proc scanGreen(s: Cell; desc: PNimType; j: var GcEnv) = s.setColor colGreen trace(s, desc, j) while j.traceStack.len > 0: let (p, desc) = j.traceStack.pop() let t = head(p[]) if t.color != colGreen: t.setColor colGreen trace(t, desc, j) inc t.rc, rcIncrement when traceCollector: cprintf("[Cycle inc] %p %ld color %ld\n", t, t.rc shr rcShift, t.color) proc nimTraceRef(q: pointer; desc: PNimType; env: pointer) {.compilerRtl.} = let p = cast[ptr pointer](q) if p[] != nil: var j = cast[ptr GcEnv](env) j.traceStack.add(p, desc) proc nimTraceRefDyn(q: pointer; env: pointer) {.compilerRtl.} = let p = cast[ptr pointer](q) if p[] != nil: var j = cast[ptr GcEnv](env) j.traceStack.add(p, cast[ptr PNimType](p[])[]) proc scan(s: Cell; desc: PNimType; j: var GcEnv) = when traceCollector: cprintf("[doScanGreen] %p %ld\n", s, s.rc shr rcShift) # even after trial deletion, `s` is still alive, so undo # the decrefs by calling `scanGreen`: if (s.rc and not rcMask) >= 0: scanGreen(s, desc, j) s.setColor colYellow else: # first we have to repair all the nodes we have seen # that are still alive; we also need to mark what they # refer to as alive: while j.jumpStack.len > 0: let (p, desc) = j.jumpStack.pop let t = head(p[]) # not in jump stack anymore! t.rc = t.rc and not jumpStackFlag if t.color == colRed and (t.rc and not rcMask) >= 0: scanGreen(t, desc, j) t.setColor colYellow when traceCollector: cprintf("[jump stack] %p %ld\n", t, t.rc shr rcShift) # we have proven that `s` and its subgraph are dead, so we can # collect these nodes: collect(s, desc, j) proc traceCycle(s: Cell; desc: PNimType) {.noinline.} = when traceCollector: cprintf("[traceCycle] %p %ld\n", s, s.rc shr rcShift) var j: GcEnv init j.jumpStack init j.traceStack markRed(s, desc, j) scan(s, desc, j) while j.jumpStack.len > 0: let (p, desc) = j.jumpStack.pop let t = head(p[]) # not in jump stack anymore! t.rc = t.rc and not jumpStackFlag deinit j.jumpStack deinit j.traceStack proc nimDecRefIsLastCyclicDyn(p: pointer): bool {.compilerRtl, inl.} = if p != nil: var cell = head(p) if (cell.rc and not rcMask) == 0: result = true #cprintf("[DESTROY] %p\n", p) else: dec cell.rc, rcIncrement if cell.color == colYellow: let desc = cast[ptr PNimType](p)[] traceCycle(cell, desc) # According to Lins it's correct to do nothing else here. #cprintf("[DeCREF] %p\n", p) proc nimDecRefIsLastCyclicStatic(p: pointer; desc: PNimType): bool {.compilerRtl, inl.} = if p != nil: var cell = head(p) if (cell.rc and not rcMask) == 0: result = true #cprintf("[DESTROY] %p %s\n", p, desc.name) else: dec cell.rc, rcIncrement if cell.color == colYellow: traceCycle(cell, desc) #cprintf("[DeCREF] %p %s %ld\n", p, desc.name, cell.rc)