summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md5
-rw-r--r--compiler/commands.nim4
-rw-r--r--doc/advopt.txt7
-rw-r--r--doc/backends.rst38
-rw-r--r--doc/destructors.rst12
-rw-r--r--doc/docs.rst4
-rw-r--r--doc/mm.rst95
-rw-r--r--doc/nimc.rst22
-rw-r--r--doc/refc.rst (renamed from doc/gc.rst)109
-rw-r--r--koch.nim2
-rw-r--r--tools/kochdocs.nim2
11 files changed, 157 insertions, 143 deletions
diff --git a/changelog.md b/changelog.md
index 63c3eff40..258cf73e4 100644
--- a/changelog.md
+++ b/changelog.md
@@ -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
 
@@ -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".)
 
diff --git a/compiler/commands.nim b/compiler/commands.nim
index a8caad916..d5c5f24e4 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -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
@@ -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}:
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 063d018d1..79e784fde 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -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
@@ -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``
diff --git a/doc/backends.rst b/doc/backends.rst
index 377e899b0..d55503d10 100644
--- a/doc/backends.rst
+++ b/doc/backends.rst
@@ -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
 ===========
 
@@ -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
@@ -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()
diff --git a/doc/destructors.rst b/doc/destructors.rst
index 83a50230b..c98e94536 100644
--- a/doc/destructors.rst
+++ b/doc/destructors.rst
@@ -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)
@@ -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.
@@ -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
@@ -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.
 
 
@@ -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
diff --git a/doc/docs.rst b/doc/docs.rst
index b34383253..3c348fcb8 100644
--- a/doc/docs.rst
+++ b/doc/docs.rst
@@ -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>`_
diff --git a/doc/mm.rst b/doc/mm.rst
new file mode 100644
index 000000000..b6941a901
--- /dev/null
+++ b/doc/mm.rst
@@ -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.
diff --git a/doc/nimc.rst b/doc/nimc.rst
index 6be4c204e..eb066e748 100644
--- a/doc/nimc.rst
+++ b/doc/nimc.rst
@@ -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"
@@ -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``.
@@ -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.
 
@@ -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
 ===================================
@@ -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.
 
 
diff --git a/doc/gc.rst b/doc/refc.rst
index 5de02f73d..766097f23 100644
--- a/doc/gc.rst
+++ b/doc/refc.rst
@@ -1,81 +1,3 @@
-=======================
-Nim's Memory Management
-=======================
-
-.. default-role:: code
-.. include:: rstcommon.rst
-
-:Author: Andreas Rumpf
-:Version: |nimversion|
-
-..
-
-
-  "The road to hell is paved with good intentions."
-
-
-Introduction
-============
-
-A memory-management algorithm optimal for every use-case cannot exist.
-Nim provides multiple paradigms for needs ranging from large multi-threaded
-applications, to games, hard-realtime systems and small microcontrollers.
-
-This document describes how the management strategies work;
-How to tune the garbage collectors for your needs, like (soft) `realtime systems`:idx:,
-and how the memory management strategies other than garbage collectors work.
-
-.. note:: the default GC is incremental, thread-local and not "stop-the-world"
-
-Multi-paradigm Memory Management Strategies
-===========================================
-
-.. default-role:: option
-
-To choose the memory management strategy use the `--gc:` switch.
-
---gc:refc    This is the default GC. 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.
---gc:markAndSweep  Simple Mark-And-Sweep based garbage collector.
-  Heaps are thread-local.
---gc:boehm    Boehm based garbage collector, it offers a shared heap.
---gc:go    Go's garbage collector, useful for interoperability with Go.
-  Offers a shared heap.
---gc:arc    Plain reference counting with
-  `move semantic optimizations <destructors.html#move-semantics>`_, offers a shared heap.
-  It offers deterministic performance for `hard realtime`:idx: systems. Reference cycles
-  cause memory leaks, beware.
-
---gc:orc    Same as `--gc:arc` but adds a cycle collector based on "trial deletion".
-  Unfortunately, that makes its performance profile hard to reason about so it is less
-  useful for hard real-time systems.
-
---gc:none    No memory management strategy nor a garbage collector. Allocated memory is
-  simply never freed. You should use `--gc:arc` instead.
-
-
-================== ======== ================= ============== ===================
-Memory Management  Heap     Reference Cycles  Stop-The-World Command line switch
-================== ======== ================= ============== ===================
-RefC               Local    Cycle Collector   No             `--gc:refc`
-Mark & Sweep       Local    Cycle Collector   No             `--gc:markAndSweep`
-ARC                Shared   Leak              No             `--gc:arc`
-ORC                Shared   Cycle Collector   No             `--gc:orc`
-Boehm              Shared   Cycle Collector   Yes            `--gc:boehm`
-Go                 Shared   Cycle Collector   Yes            `--gc:go`
-None               Manual   Manual            Manual         `--gc: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.
-
-
 Tweaking the refc GC
 ====================
 
@@ -164,6 +86,35 @@ that up to 100 objects are traversed and freed before it checks again. Thus
 highly specialized environments or for older hardware.
 
 
+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()
+
+
+
 Keeping track of memory
 =======================
 
@@ -178,7 +129,7 @@ Other useful procs from `system <system.html>`_ you can use to keep track of mem
 * `GC_getStatistics()` Garbage collector statistics as a human-readable string.
 
 These numbers are usually only for the running thread, not for the whole heap,
-with the exception of `--gc:boehm`:option: and `--gc:go`:option:.
+with the exception of `--mm:boehm`:option: and `--mm:go`:option:.
 
 In addition to `GC_ref` and `GC_unref` you can avoid the garbage collector by manually
 allocating memory with procs like `alloc`, `alloc0`, `allocShared`, `allocShared0` or `allocCStringArray`.
diff --git a/koch.nim b/koch.nim
index f87828cdc..295b1584b 100644
--- a/koch.nim
+++ b/koch.nim
@@ -604,7 +604,7 @@ proc runCI(cmd: string) =
 
   when not defined(bsd):
     # the BSDs are overwhelmed already, so only run this test on the other machines:
-    kochExecFold("Boot Nim ORC", "boot -d:release --gc:orc --lib:lib")
+    kochExecFold("Boot Nim ORC", "boot -d:release --mm:orc --lib:lib")
 
 proc testUnixInstall(cmdLineRest: string) =
   csource("-d:danger" & cmdLineRest)
diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim
index 70ee5ad07..4fbea8c77 100644
--- a/tools/kochdocs.nim
+++ b/tools/kochdocs.nim
@@ -129,7 +129,7 @@ tut2.rst
 tut3.rst
 nimc.rst
 niminst.rst
-gc.rst
+mm.rst
 """.splitWhitespace().mapIt("doc" / it)
 
   doc0 = """