mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-03 18:34:43 +00:00
Improve description of how =trace is used (#18491)
* [skip ci] thamming_orc test created/destroyed counts match The thamming_orc.nim code now counts all created objects being tested, not just the ones following the "first 20" test, and the position of the `destroyed += 1` counter has been adjusted so it counts all the calls that are as a result of `=trace` tracing and not just the original destruction calls. * Improve description of how `=trace` is used The following nuances weren't previously fully explained: 1. That `=trace` is only used by `--gc:orc`. 2. That `=trace` is almost certainly used along with `=destroy` when manual resource allocation has been used, but it is only required if there is a possibility of cyclic references in the wrapped types (ie. generic types). 3. That, currently, a forward definition is required for the second of the pair to avoid an auto compiler generation conflict. The pattern of the use of `=trace` has also been made more extensive, showing how both a custom `=destroy` and `=trace` are used for manual allocation of resources when there is any possibility of a cyclic reference in the resource-wrapped values. * Update doc/destructors.rst Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
@@ -222,16 +222,33 @@ The prototype of this hook for a type `T` needs to be:
|
||||
`env` is used by ORC to keep track of its internal state, it should be passed around
|
||||
to calls of the built-in `=trace` operation.
|
||||
|
||||
The general pattern in `=trace` looks like:
|
||||
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` be 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 pair. The work around for this problem is to forward declare the second of the "hooks" to prevent the automatic creation.
|
||||
|
||||
The general pattern in using `=destroy` with `=trace` looks like:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
proc `=trace`(dest: var T; env: pointer) =
|
||||
for child in childrenThatCanContainPointers(dest):
|
||||
`=trace`(child, env)
|
||||
type
|
||||
Test[T] = object
|
||||
size: Natural
|
||||
arr: ptr UncheckedArray[T] # raw pointer field
|
||||
|
||||
proc makeTest[T](size: Natural): Test[T] = # custom allocation...
|
||||
Test[T](size: size, arr: cast[ptr UncheckedArray[T]](alloc0(sizeof(T) * size)))
|
||||
|
||||
|
||||
**Note**: The `=trace` hooks is currently more experimental and less refined
|
||||
proc `=destroy`[T](dest: var Test[T]) =
|
||||
if dest.arr != nil:
|
||||
for i in 0 ..< dest.size: dest.arr[i].`=destroy`
|
||||
dest.arr.dealloc
|
||||
|
||||
proc `=trace`[T](dest: var Test[T]; env: pointer) =
|
||||
if dest.arr != nil: # trace the `T`'s which may be cyclic
|
||||
for i in 0 ..< dest.size: dest.arr[i].`=trace` env
|
||||
|
||||
# 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
|
||||
than the other hooks.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user