Skip to content

Commit fa63787

Browse files
AraqJaremy Creechley
authored andcommitted
renamed 'gc' switch to 'mm'; [backport:1.6] (nim-lang#19187)
* renamed 'gc' switch to 'mm'; [backport:1.6] * better docs
1 parent c1856a7 commit fa63787

File tree

11 files changed

+157
-143
lines changed

11 files changed

+157
-143
lines changed

changelog.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
Baz = object
5454
```
5555
- [Case statement macros](manual.html#macros-case-statement-macros) are no longer experimental,
56-
meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them.
56+
meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them.
5757

5858
## Compiler changes
5959

@@ -63,5 +63,6 @@
6363

6464
## Tool changes
6565

66-
66+
- The `gc` switch has been renamed to `mm` ("memory management") in order to reflect the
67+
reality better. (Nim moved away from all techniques based on "tracing".)
6768

compiler/commands.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ template deprecatedAlias(oldName, newName: string) =
248248

249249
proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo): bool =
250250
case switch.normalize
251-
of "gc":
251+
of "gc", "mm":
252252
case arg.normalize
253253
of "boehm": result = conf.selectedGC == gcBoehm
254254
of "refc": result = conf.selectedGC == gcRefc
@@ -596,7 +596,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
596596
processOnOffSwitchG(conf, {optForceFullMake}, arg, pass, info)
597597
of "project":
598598
processOnOffSwitchG(conf, {optWholeProject, optGenIndex}, arg, pass, info)
599-
of "gc":
599+
of "gc", "mm":
600600
if conf.backend == backendJs: return # for: bug #16033
601601
expectArg(conf, switch, arg, pass, info)
602602
if pass in {passCmd2, passPP}:

doc/advopt.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ Advanced options:
122122
--skipUserCfg:on|off do not read the user's configuration file
123123
--skipParentCfg:on|off do not read the parent dirs' configuration files
124124
--skipProjCfg:on|off do not read the project's configuration file
125-
--gc:refc|arc|orc|markAndSweep|boehm|go|none|regions
126-
select the GC to use; default is 'refc'
125+
--mm:orc|arc|refc|markAndSweep|boehm|go|none|regions
126+
select which memory management to use; default is 'refc'
127+
recommended is 'orc'
127128
--exceptions:setjmp|cpp|goto|quirky
128129
select the exception handling implementation
129130
--index:on|off turn index file generation on|off
@@ -163,4 +164,4 @@ Advanced options:
163164
--profileVM:on|off turn compile time VM profiler on|off
164165
--sinkInference:on|off turn sink parameter inference on|off (default: on)
165166
--panics:on|off turn panics into process terminations (default: off)
166-
--deepcopy:on|off enable 'system.deepCopy' for ``--gc:arc|orc``
167+
--deepcopy:on|off enable 'system.deepCopy' for ``--mm:arc|orc``

doc/backends.rst

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ file. However, you can also run the code with `nodejs`:idx:
105105
If you experience errors saying that `globalThis` is not defined, be
106106
sure to run a recent version of Node.js (at least 12.0).
107107

108-
108+
109109
Interfacing
110110
===========
111111

@@ -387,14 +387,8 @@ A similar thing happens with C code invoking Nim code which returns a
387387
proc gimme(): cstring {.exportc.} =
388388
result = "Hey there C code! " & $rand(100)
389389
390-
Since Nim's garbage collector is not aware of the C code, once the
390+
Since Nim's reference counting mechanism is not aware of the C code, once the
391391
`gimme` proc has finished it can reclaim the memory of the `cstring`.
392-
However, from a practical standpoint, the C code invoking the `gimme`
393-
function directly will be able to use it since Nim's garbage collector has
394-
not had a chance to run *yet*. This gives you enough time to make a copy for
395-
the C side of the program, as calling any further Nim procs *might* trigger
396-
garbage collection making the previously returned string garbage. Or maybe you
397-
are `yourself triggering the collection <gc.html>`_.
398392

399393

400394
Custom data types
@@ -414,31 +408,3 @@ you can clean it up. And of course, once cleaned you should avoid accessing it
414408
from Nim (or C for that matter). Typically C data structures have their own
415409
`malloc_structure`:c: and `free_structure`:c: specific functions, so wrapping
416410
these for the Nim side should be enough.
417-
418-
419-
Thread coordination
420-
-------------------
421-
422-
When the `NimMain()` function is called Nim initializes the garbage
423-
collector to the current thread, which is usually the main thread of your
424-
application. If your C code later spawns a different thread and calls Nim
425-
code, the garbage collector will fail to work properly and you will crash.
426-
427-
As long as you don't use the threadvar emulation Nim uses native thread
428-
variables, of which you get a fresh version whenever you create a thread. You
429-
can then attach a GC to this thread via
430-
431-
.. code-block:: nim
432-
433-
system.setupForeignThreadGc()
434-
435-
It is **not** safe to disable the garbage collector and enable it after the
436-
call from your background thread even if the code you are calling is short
437-
lived.
438-
439-
Before the thread exits, you should tear down the thread's GC to prevent memory
440-
leaks by calling
441-
442-
.. code-block:: nim
443-
444-
system.tearDownForeignThreadGc()

doc/destructors.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ written as:
4343
dealloc(x.data)
4444
4545
proc `=trace`[T](x: var myseq[T]; env: pointer) =
46-
# `=trace` allows the cycle collector `--gc:orc`
46+
# `=trace` allows the cycle collector `--mm:orc`
4747
# to understand how to trace the object graph.
4848
if x.data != nil:
4949
for i in 0..<x.len: `=trace`(x.data[i], env)
@@ -208,7 +208,7 @@ by the compiler. Notice that there is no `=` before the `{.error.}` pragma.
208208
`=trace` hook
209209
-------------
210210

211-
A custom **container** type can support Nim's cycle collector `--gc:orc` via
211+
A custom **container** type can support Nim's cycle collector `--mm:orc` via
212212
the `=trace` hook. If the container does not implement `=trace`, cyclic data
213213
structures which are constructed with the help of the container might leak
214214
memory or resources, but memory safety is not compromised.
@@ -224,7 +224,7 @@ to calls of the built-in `=trace` operation.
224224

225225
Usually there will only be a need for a custom `=trace` when a custom `=destroy` that deallocates
226226
manually allocated resources is also used, and then only when there is a chance of cyclic
227-
references from items within the manually allocated resources when it is desired that `--gc:orc`
227+
references from items within the manually allocated resources when it is desired that `--mm:orc`
228228
is able to break and collect these cyclic referenced resources. Currently however, there is a
229229
mutual use problem in that whichever of `=destroy`/`=trace` is used first will automatically
230230
create a version of the other which will then conflict with the creation of the second of the
@@ -256,7 +256,7 @@ The general pattern in using `=destroy` with `=trace` looks like:
256256
257257
# following may be other custom "hooks" as required...
258258
259-
**Note**: The `=trace` hooks (which are only used by `--gc:orc`) are currently more experimental and less refined
259+
**Note**: The `=trace` hooks (which are only used by `--mm:orc`) are currently more experimental and less refined
260260
than the other hooks.
261261

262262

@@ -558,10 +558,10 @@ for expressions of type `lent T` or of type `var T`.
558558
The cursor pragma
559559
=================
560560

561-
Under the `--gc:arc|orc`:option: modes Nim's `ref` type is implemented
561+
Under the `--mm:arc|orc`:option: modes Nim's `ref` type is implemented
562562
via the same runtime "hooks" and thus via reference counting.
563563
This means that cyclic structures cannot be freed
564-
immediately (`--gc:orc`:option: ships with a cycle collector).
564+
immediately (`--mm:orc`:option: ships with a cycle collector).
565565
With the `cursor` pragma one can break up cycles declaratively:
566566

567567
.. code-block:: nim

doc/docs.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ The documentation consists of several documents:
2222
- | `Tools documentation <tools.html>`_
2323
| Description of some tools that come with the standard distribution.
2424
25-
- | `GC <gc.html>`_
26-
| Additional documentation about Nim's multi-paradigm memory management strategies
25+
- | `Memory management <mm.html>`_
26+
| Additional documentation about Nim's memory management strategies
2727
| and how to operate them in a realtime setting.
2828
2929
- | `Source code filters <filters.html>`_

doc/mm.rst

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
=======================
2+
Nim's Memory Management
3+
=======================
4+
5+
.. default-role:: code
6+
.. include:: rstcommon.rst
7+
8+
:Author: Andreas Rumpf
9+
:Version: |nimversion|
10+
11+
..
12+
13+
14+
"The road to hell is paved with good intentions."
15+
16+
17+
Multi-paradigm Memory Management Strategies
18+
===========================================
19+
20+
.. default-role:: option
21+
22+
Nim offers multiple different memory management strategies.
23+
To choose the memory management strategy use the `--mm:` switch.
24+
25+
**The recommended switch for newly written Nim code is `--mm:orc`.**
26+
27+
28+
ARC/ORC
29+
-------
30+
31+
`--mm:orc` is a memory management mode primarily based on reference counting. Cycles
32+
in the object graph are handled by a "cycle collector" which is based on "trial deletion".
33+
Since algorithms based on "tracing" are not used, the runtime behavior is oblivious to
34+
the involved heap sizes.
35+
36+
The reference counting operations (= "RC ops") do not use atomic instructions and do not have to --
37+
instead entire subgraphs are *moved* between threads. The Nim compiler also aggressively
38+
optimizes away RC ops and exploits `move semantics <destructors.html#move-semantics>`_.
39+
40+
Nim performs a fair share of optimizations for ARC/ORC; you can inspect what it did
41+
to your time critical function via `--expandArc:functionName`.
42+
43+
`--mm:arc` uses the same mechanism as `--mm:orc`, but it leaves out the cycle collector.
44+
Both ARC and ORC offer deterministic performance for `hard realtime`:idx: systems, but
45+
ARC can be easier to reason about for people coming from Ada/C++/C -- roughly speaking
46+
the memory for a variable is freed when it goes "out of scope".
47+
48+
We generally advise you to use the `acyclic` annotation in order to optimize away the
49+
cycle collector's overhead
50+
but `--mm:orc` also produces more machine code than `--mm:arc`, so if you're on a target
51+
where code size matters and you know that your code does not produce cycles, you can
52+
use `--mm:arc`. Notice that the default `async`:idx: implementation produces cycles
53+
and leaks memory with `--mm:arc`, in other words, for `async` you need to use `--mm:orc`.
54+
55+
56+
57+
Other MM modes
58+
--------------
59+
60+
.. note:: The default `refc` GC is incremental, thread-local and not "stop-the-world".
61+
62+
--mm:refc This is the default memory management strategy. It's a
63+
deferred reference counting based garbage collector
64+
with a simple Mark&Sweep backup GC in order to collect cycles. Heaps are thread-local.
65+
`This document <refc.html>`_ contains further information.
66+
--mm:markAndSweep Simple Mark-And-Sweep based garbage collector.
67+
Heaps are thread-local.
68+
--mm:boehm Boehm based garbage collector, it offers a shared heap.
69+
--mm:go Go's garbage collector, useful for interoperability with Go.
70+
Offers a shared heap.
71+
72+
--mm:none No memory management strategy nor a garbage collector. Allocated memory is
73+
simply never freed. You should use `--mm:arc` instead.
74+
75+
Here is a comparison of the different memory management modes:
76+
77+
================== ======== ================= ============== ===================
78+
Memory Management Heap Reference Cycles Stop-The-World Command line switch
79+
================== ======== ================= ============== ===================
80+
ORC Shared Cycle Collector No `--mm:orc`
81+
ARC Shared Leak No `--mm:arc`
82+
RefC Local Cycle Collector No `--mm:refc`
83+
Mark & Sweep Local Cycle Collector No `--mm:markAndSweep`
84+
Boehm Shared Cycle Collector Yes `--mm:boehm`
85+
Go Shared Cycle Collector Yes `--mm:go`
86+
None Manual Manual Manual `--mm:none`
87+
================== ======== ================= ============== ===================
88+
89+
.. default-role:: code
90+
.. include:: rstcommon.rst
91+
92+
JavaScript's garbage collector is used for the `JavaScript and NodeJS
93+
<backends.html#backends-the-javascript-target>`_ compilation targets.
94+
The `NimScript <nims.html>`_ target uses the memory management strategy built into
95+
the Nim compiler.

doc/nimc.rst

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,13 @@ to your usual `nim c`:cmd: or `nim cpp`:cmd: command and set the `passC`:option:
408408
and `passL`:option: command line switches to something like:
409409

410410
.. code-block:: cmd
411-
nim c ... --d:nimAllocPagesViaMalloc --gc:orc --passC="-I$DEVKITPRO/libnx/include" ...
411+
nim c ... --d:nimAllocPagesViaMalloc --mm:orc --passC="-I$DEVKITPRO/libnx/include" ...
412412
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
413413
414414
or setup a ``nim.cfg`` file like so::
415415

416416
#nim.cfg
417-
--gc:orc
417+
--mm:orc
418418
--d:nimAllocPagesViaMalloc
419419
--passC="-I$DEVKITPRO/libnx/include"
420420
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
@@ -485,10 +485,10 @@ Define Effect
485485
`useMalloc` Makes Nim use C's `malloc`:idx: instead of Nim's
486486
own memory manager, albeit prefixing each allocation with
487487
its size to support clearing memory on reallocation.
488-
This only works with `--gc:none`:option:,
489-
`--gc:arc`:option: and `--gc:orc`:option:.
488+
This only works with `--mm:none`:option:,
489+
`--mm:arc`:option: and `--mm:orc`:option:.
490490
`useRealtimeGC` Enables support of Nim's GC for *soft* realtime
491-
systems. See the documentation of the `gc <gc.html>`_
491+
systems. See the documentation of the `mm <mm.html>`_
492492
for further information.
493493
`logGC` Enable GC logging to stdout.
494494
`nodejs` The JS target is actually ``node.js``.
@@ -614,9 +614,9 @@ A good start is to use the `any` operating target together with the
614614

615615
.. code:: cmd
616616
617-
nim c --os:any --gc:arc -d:useMalloc [...] x.nim
617+
nim c --os:any --mm:arc -d:useMalloc [...] x.nim
618618
619-
- `--gc:arc`:option: will enable the reference counting memory management instead
619+
- `--mm:arc`:option: will enable the reference counting memory management instead
620620
of the default garbage collector. This enables Nim to use heap memory which
621621
is required for strings and seqs, for example.
622622

@@ -654,7 +654,7 @@ devices. This allocator gets blocks/pages of memory via a currently undocumented
654654
`osalloc` API which usually uses POSIX's `mmap` call. On many environments `mmap`
655655
is not available but C's `malloc` is. You can use the `nimAllocPagesViaMalloc`
656656
define to use `malloc` instead of `mmap`. `nimAllocPagesViaMalloc` is currently
657-
only supported with `--gc:arc` or `--gc:orc`. (Since version 1.6)
657+
only supported with `--mm:arc` or `--mm:orc`. (Since version 1.6)
658658

659659
nimPage256 / nimPage512 / nimPage1k
660660
===================================
@@ -681,19 +681,19 @@ nimMemAlignTiny
681681
Sets `MemAlign` to `4` bytes which reduces the memory alignment
682682
to better match some embedded devices.
683683

684-
Thread stack size
684+
Thread stack size
685685
=================
686686

687687
Nim's thread API provides a simple wrapper around more advanced
688688
RTOS task features. Customizing the stack size and stack guard size can
689689
be done by setting `-d:nimThreadStackSize=16384` or `-d:nimThreadStackGuard=32`.
690690

691-
Currently only Zephyr and FreeRTOS support these configurations.
691+
Currently only Zephyr and FreeRTOS support these configurations.
692692

693693
Nim for realtime systems
694694
========================
695695

696-
See the documentation of Nim's soft realtime `GC <gc.html>`_ for further
696+
See the `--mm:arc` or `--mm:orc` memory management settings in `MM <mm.html>`_ for further
697697
information.
698698

699699

0 commit comments

Comments
 (0)