mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-20 22:00:57 +00:00
progress
This commit is contained in:
@@ -748,12 +748,19 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
|
||||
# YRC uses dedicated runtime procs for the entire write barrier:
|
||||
if c.g.config.selectedGC == gcYrc:
|
||||
let desc =
|
||||
if isFinal(elemType):
|
||||
let ti = genBuiltin(c, mGetTypeInfoV2, "getTypeInfoV2", newNodeIT(nkType, x.info, elemType))
|
||||
ti.typ = getSysType(c.g, c.info, tyPointer)
|
||||
ti
|
||||
else:
|
||||
newNodeIT(nkNilLit, c.info, getSysType(c.g, c.info, tyPointer))
|
||||
case c.kind
|
||||
of attachedAsgn, attachedDup:
|
||||
body.add callCodegenProc(c.g, "nimAsgnYrc", c.info, genAddr(c, x), y)
|
||||
body.add callCodegenProc(c.g, "nimAsgnYrc", c.info, genAddr(c, x), y, desc)
|
||||
return
|
||||
of attachedSink:
|
||||
body.add callCodegenProc(c.g, "nimSinkYrc", c.info, genAddr(c, x), y)
|
||||
body.add callCodegenProc(c.g, "nimSinkYrc", c.info, genAddr(c, x), y, desc)
|
||||
return
|
||||
else: discard # fall through for destructor, trace, wasMoved
|
||||
|
||||
@@ -842,13 +849,15 @@ proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
xenv.typ = getSysType(c.g, c.info, tyPointer)
|
||||
|
||||
# YRC uses dedicated runtime procs for the write barrier on the env pointer:
|
||||
# Closure envs are always polymorphic, so pass nil for desc (uses Dyn variant):
|
||||
if c.g.config.selectedGC == gcYrc:
|
||||
let nilDesc = newNodeIT(nkNilLit, c.info, getSysType(c.g, c.info, tyPointer))
|
||||
case c.kind
|
||||
of attachedAsgn, attachedDup:
|
||||
body.add callCodegenProc(c.g, "nimAsgnYrc", c.info, genAddr(c, xenv), y)
|
||||
body.add callCodegenProc(c.g, "nimAsgnYrc", c.info, genAddr(c, xenv), y, nilDesc)
|
||||
return
|
||||
of attachedSink:
|
||||
body.add callCodegenProc(c.g, "nimSinkYrc", c.info, genAddr(c, xenv), y)
|
||||
body.add callCodegenProc(c.g, "nimSinkYrc", c.info, genAddr(c, xenv), y, nilDesc)
|
||||
return
|
||||
else: discard # fall through for destructor, trace, wasMoved
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ proc GC_partialCollect*(limit: int) =
|
||||
roots.len = limit
|
||||
|
||||
proc GC_fullCollect* =
|
||||
collectCycles()
|
||||
GC_runOrc()
|
||||
|
||||
proc GC_enableMarkAndSweep*() = GC_enableOrc()
|
||||
proc GC_disableMarkAndSweep*() = GC_disableOrc()
|
||||
@@ -448,7 +448,13 @@ proc unsureAsgnRef(dest: ptr pointer, src: pointer) {.inline.} =
|
||||
dest[] = src
|
||||
if src != nil: nimIncRefCyclic(src, true)
|
||||
|
||||
proc nimAsgnYrc(dest: ptr pointer; src: pointer) {.compilerRtl.} =
|
||||
proc yrcDec(tmp: pointer; desc: PNimTypeV2) {.inline.} =
|
||||
if desc != nil:
|
||||
discard nimDecRefIsLastCyclicStatic(tmp, desc)
|
||||
else:
|
||||
discard nimDecRefIsLastCyclicDyn(tmp)
|
||||
|
||||
proc nimAsgnYrc(dest: ptr pointer; src: pointer; desc: PNimTypeV2) {.compilerRtl.} =
|
||||
## YRC write barrier for ref copy assignment.
|
||||
## Atomically stores src into dest, then buffers RC adjustments.
|
||||
## Freeing is always done by the cycle collector, never inline.
|
||||
@@ -457,15 +463,15 @@ proc nimAsgnYrc(dest: ptr pointer; src: pointer) {.compilerRtl.} =
|
||||
if src != nil:
|
||||
nimIncRefCyclic(src, true)
|
||||
if tmp != nil:
|
||||
discard nimDecRefIsLastCyclicDyn(tmp)
|
||||
yrcDec(tmp, desc)
|
||||
|
||||
proc nimSinkYrc(dest: ptr pointer; src: pointer) {.compilerRtl.} =
|
||||
proc nimSinkYrc(dest: ptr pointer; src: pointer; desc: PNimTypeV2) {.compilerRtl.} =
|
||||
## YRC write barrier for ref sink (move). No incRef on source.
|
||||
## Freeing is always done by the cycle collector, never inline.
|
||||
let tmp = dest[]
|
||||
atomicStoreN(dest, src, ATOMIC_RELEASE)
|
||||
if tmp != nil:
|
||||
discard nimDecRefIsLastCyclicDyn(tmp)
|
||||
yrcDec(tmp, desc)
|
||||
|
||||
proc nimMarkCyclic(p: pointer) {.compilerRtl, inl.} =
|
||||
when optimizedOrc:
|
||||
|
||||
Reference in New Issue
Block a user