make it work with C++; documentation updated

This commit is contained in:
Araq
2026-07-23 20:49:01 +02:00
parent 2174e91812
commit 4990a325ea
2 changed files with 29 additions and 4 deletions

View File

@@ -94,11 +94,21 @@ proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
body.add genBuiltin(c, mWasMoved, "wasMoved", x)
proc genAddr(c: var TLiftCtx; x: PNode): PNode =
if x.kind == nkHiddenDeref:
# These synthesized addresses are always passed to codegen procs that expect a
# genuine pointer (nimAsgnYrc, nimSinkYrc, destructors, ...). `addr(deref x)`
# collapses to `x` only when `x` is a real pointer; on the C++ backend a `var`
# parameter is a C++ reference, so we must keep the `nkHiddenAddr` to actually
# take its address (`&dest`) instead of passing the reference's value. Likewise
# `tfVarIsPtr` keeps the C++ backend from lowering the synthesized address back
# to a reference and dropping the `&` (e.g. a closure's `tyPointer` env). See
# #26026 CI (yrc + cpp).
if x.kind == nkHiddenDeref and c.g.config.backend != backendCpp:
checkSonsLen(x, 1, c.g.config)
result = x[0]
else:
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(x.typ.owner, x.typ, c.idgen))
let addrTyp = makeVarType(x.typ.owner, x.typ, c.idgen)
addrTyp.incl tfVarIsPtr
result = newNodeIT(nkHiddenAddr, x.info, addrTyp)
result.add x
proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =

View File

@@ -50,9 +50,23 @@ cycle collector's overhead
but `--mm:orc` also produces more machine code than `--mm:arc`, so if you're on a target
where code size matters and you know that your code does not produce cycles, you can
use `--mm:arc`. Notice that the default `async`:idx: implementation produces cycles
and leaks memory with `--mm:arc`, in other words, for `async` you need to use `--mm:orc`.
and leaks memory with `--mm:arc`, in other words, for `async` you need to use `--mm:orc`
or `--mm:yrc`.
Atomic ARC/YRC
--------------
ARC/ORC are not threadsafe if `ref` or other automatically managed types are
accessed across thread boundaries.
Moving isolated subgraphs between threads is supported for ARC/ORC and the language has support
for that in the form of `isolate`. The modes `mm:atomicArc` and `mm:yrc` do offer this thread safety -- at the cost of atomic instructions. Whether that cost is acceptable depends on your program, it hard to give general guidelines. On a modern CPU the potential speedups in the form of increased multi-threading capabilities should outweigh the costs of atomic instructions by far. On an embedded device the atomics would probably only hurt though.
`mm:atomicArc` is a threadsafe variant of ARC: All the optimizations in the form of move semantics etc are still applied. `mm:yrc` is the threadsafe variant of ORC.
YRC is a novel concurrent cycle collection algorithm -- these are beasts to verify
and to get correct so there are dragons lurking here, use at your own risk.
Other MM modes
--------------
@@ -66,7 +80,7 @@ Other MM modes
Heaps are thread-local.
--mm:boehm Boehm based garbage collector, it offers a shared heap.
--mm:go Go's garbage collector, useful for interoperability with Go.
Offers a shared heap.
Offers a shared heap. Note that `mm:go` has seen little real world use. Use at your own risk.
--mm:none No memory management strategy nor a garbage collector. Allocated memory is
simply never freed. You should use `--mm:arc` instead.
@@ -76,6 +90,7 @@ Here is a comparison of the different memory management modes:
================== ======== ================= ============== ====== =================== ===================
Memory Management Heap Reference Cycles Stop-The-World Atomic Valgrind compatible Command line switch
================== ======== ================= ============== ====== =================== ===================
YRC Shared Cycle Collector No Yes Yes `--mm:yrc`
ORC Shared Cycle Collector No No Yes `--mm:orc`
ARC Shared Leak No No Yes `--mm:arc`
Atomic ARC Shared Leak No Yes Yes `--mm:atomicArc`