Skip to content

Commit

Permalink
renamed 'gc' switch to 'mm'; [backport:1.6] (#19187)
Browse files Browse the repository at this point in the history
* renamed 'gc' switch to 'mm'; [backport:1.6]
* better docs
  • Loading branch information
Araq authored Nov 24, 2021
1 parent c7c6b13 commit a0073d2
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 143 deletions.
5 changes: 3 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
Baz = object
```
- [Case statement macros](manual.html#macros-case-statement-macros) are no longer experimental,
meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them.
meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them.

## Compiler changes

Expand All @@ -63,5 +63,6 @@

## Tool changes


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

4 changes: 2 additions & 2 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ template deprecatedAlias(oldName, newName: string) =

proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo): bool =
case switch.normalize
of "gc":
of "gc", "mm":
case arg.normalize
of "boehm": result = conf.selectedGC == gcBoehm
of "refc": result = conf.selectedGC == gcRefc
Expand Down Expand Up @@ -596,7 +596,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
processOnOffSwitchG(conf, {optForceFullMake}, arg, pass, info)
of "project":
processOnOffSwitchG(conf, {optWholeProject, optGenIndex}, arg, pass, info)
of "gc":
of "gc", "mm":
if conf.backend == backendJs: return # for: bug #16033
expectArg(conf, switch, arg, pass, info)
if pass in {passCmd2, passPP}:
Expand Down
7 changes: 4 additions & 3 deletions doc/advopt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ Advanced options:
--skipUserCfg:on|off do not read the user's configuration file
--skipParentCfg:on|off do not read the parent dirs' configuration files
--skipProjCfg:on|off do not read the project's configuration file
--gc:refc|arc|orc|markAndSweep|boehm|go|none|regions
select the GC to use; default is 'refc'
--mm:orc|arc|refc|markAndSweep|boehm|go|none|regions
select which memory management to use; default is 'refc'
recommended is 'orc'
--exceptions:setjmp|cpp|goto|quirky
select the exception handling implementation
--index:on|off turn index file generation on|off
Expand Down Expand Up @@ -163,4 +164,4 @@ Advanced options:
--profileVM:on|off turn compile time VM profiler on|off
--sinkInference:on|off turn sink parameter inference on|off (default: on)
--panics:on|off turn panics into process terminations (default: off)
--deepcopy:on|off enable 'system.deepCopy' for ``--gc:arc|orc``
--deepcopy:on|off enable 'system.deepCopy' for ``--mm:arc|orc``
38 changes: 2 additions & 36 deletions doc/backends.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ file. However, you can also run the code with `nodejs`:idx:
If you experience errors saying that `globalThis` is not defined, be
sure to run a recent version of Node.js (at least 12.0).


Interfacing
===========

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


Custom data types
Expand All @@ -414,31 +408,3 @@ you can clean it up. And of course, once cleaned you should avoid accessing it
from Nim (or C for that matter). Typically C data structures have their own
`malloc_structure`:c: and `free_structure`:c: specific functions, so wrapping
these for the Nim side should be enough.


Thread coordination
-------------------

When the `NimMain()` function is called Nim initializes the garbage
collector to the current thread, which is usually the main thread of your
application. If your C code later spawns a different thread and calls Nim
code, the garbage collector will fail to work properly and you will crash.

As long as you don't use the threadvar emulation Nim uses native thread
variables, of which you get a fresh version whenever you create a thread. You
can then attach a GC to this thread via

.. code-block:: nim
system.setupForeignThreadGc()
It is **not** safe to disable the garbage collector and enable it after the
call from your background thread even if the code you are calling is short
lived.

Before the thread exits, you should tear down the thread's GC to prevent memory
leaks by calling

.. code-block:: nim
system.tearDownForeignThreadGc()
12 changes: 6 additions & 6 deletions doc/destructors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ written as:
dealloc(x.data)
proc `=trace`[T](x: var myseq[T]; env: pointer) =
# `=trace` allows the cycle collector `--gc:orc`
# `=trace` allows the cycle collector `--mm:orc`
# to understand how to trace the object graph.
if x.data != nil:
for i in 0..<x.len: `=trace`(x.data[i], env)
Expand Down Expand Up @@ -208,7 +208,7 @@ by the compiler. Notice that there is no `=` before the `{.error.}` pragma.
`=trace` hook
-------------

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

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


Expand Down Expand Up @@ -558,10 +558,10 @@ for expressions of type `lent T` or of type `var T`.
The cursor pragma
=================

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

.. code-block:: nim
Expand Down
4 changes: 2 additions & 2 deletions doc/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ The documentation consists of several documents:
- | `Tools documentation <tools.html>`_
| Description of some tools that come with the standard distribution.
- | `GC <gc.html>`_
| Additional documentation about Nim's multi-paradigm memory management strategies
- | `Memory management <mm.html>`_
| Additional documentation about Nim's memory management strategies
| and how to operate them in a realtime setting.
- | `Source code filters <filters.html>`_
Expand Down
95 changes: 95 additions & 0 deletions doc/mm.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
=======================
Nim's Memory Management
=======================

.. default-role:: code
.. include:: rstcommon.rst

:Author: Andreas Rumpf
:Version: |nimversion|

..

"The road to hell is paved with good intentions."


Multi-paradigm Memory Management Strategies
===========================================

.. default-role:: option

Nim offers multiple different memory management strategies.
To choose the memory management strategy use the `--mm:` switch.

**The recommended switch for newly written Nim code is `--mm:orc`.**


ARC/ORC
-------

`--mm:orc` is a memory management mode primarily based on reference counting. Cycles
in the object graph are handled by a "cycle collector" which is based on "trial deletion".
Since algorithms based on "tracing" are not used, the runtime behavior is oblivious to
the involved heap sizes.

The reference counting operations (= "RC ops") do not use atomic instructions and do not have to --
instead entire subgraphs are *moved* between threads. The Nim compiler also aggressively
optimizes away RC ops and exploits `move semantics <destructors.html#move-semantics>`_.

Nim performs a fair share of optimizations for ARC/ORC; you can inspect what it did
to your time critical function via `--expandArc:functionName`.

`--mm:arc` uses the same mechanism as `--mm:orc`, but it leaves out the cycle collector.
Both ARC and ORC offer deterministic performance for `hard realtime`:idx: systems, but
ARC can be easier to reason about for people coming from Ada/C++/C -- roughly speaking
the memory for a variable is freed when it goes "out of scope".

We generally advise you to use the `acyclic` annotation in order to optimize away the
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`.



Other MM modes
--------------

.. note:: The default `refc` GC is incremental, thread-local and not "stop-the-world".

--mm:refc This is the default memory management strategy. It's a
deferred reference counting based garbage collector
with a simple Mark&Sweep backup GC in order to collect cycles. Heaps are thread-local.
`This document <refc.html>`_ contains further information.
--mm:markAndSweep Simple Mark-And-Sweep based garbage collector.
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.

--mm:none No memory management strategy nor a garbage collector. Allocated memory is
simply never freed. You should use `--mm:arc` instead.

Here is a comparison of the different memory management modes:

================== ======== ================= ============== ===================
Memory Management Heap Reference Cycles Stop-The-World Command line switch
================== ======== ================= ============== ===================
ORC Shared Cycle Collector No `--mm:orc`
ARC Shared Leak No `--mm:arc`
RefC Local Cycle Collector No `--mm:refc`
Mark & Sweep Local Cycle Collector No `--mm:markAndSweep`
Boehm Shared Cycle Collector Yes `--mm:boehm`
Go Shared Cycle Collector Yes `--mm:go`
None Manual Manual Manual `--mm:none`
================== ======== ================= ============== ===================

.. default-role:: code
.. include:: rstcommon.rst

JavaScript's garbage collector is used for the `JavaScript and NodeJS
<backends.html#backends-the-javascript-target>`_ compilation targets.
The `NimScript <nims.html>`_ target uses the memory management strategy built into
the Nim compiler.
22 changes: 11 additions & 11 deletions doc/nimc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -408,13 +408,13 @@ to your usual `nim c`:cmd: or `nim cpp`:cmd: command and set the `passC`:option:
and `passL`:option: command line switches to something like:

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

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

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

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

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

Thread stack size
Thread stack size
=================

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

Currently only Zephyr and FreeRTOS support these configurations.
Currently only Zephyr and FreeRTOS support these configurations.

Nim for realtime systems
========================

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


Expand Down
Loading

0 comments on commit a0073d2

Please sign in to comment.