github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/src/runtime/HACKING.md (about)

     1  This is a very incomplete and probably out-of-date guide to
     2  programming in the Go runtime and how it differs from writing normal
     3  Go.
     4  
     5  Unmanaged memory
     6  ================
     7  
     8  In general, the runtime tries to use regular heap allocation. However,
     9  in some cases the runtime must allocate objects outside of the garbage
    10  collected heap, in *unmanaged memory*. This is necessary if the
    11  objects are part of the memory manager itself or if they must be
    12  allocated in situations where the caller may not have a P.
    13  
    14  There are three mechanisms for allocating unmanaged memory:
    15  
    16  * sysAlloc obtains memory directly from the OS. This comes in whole
    17    multiples of the system page size, but it can be freed with sysFree.
    18  
    19  * persistentalloc combines multiple smaller allocations into a single
    20    sysAlloc to avoid fragmentation. However, there is no way to free
    21    persistentalloced objects (hence the name).
    22  
    23  * fixalloc is a SLAB-style allocator that allocates objects of a fixed
    24    size. fixalloced objects can be freed, but this memory can only be
    25    reused by the same fixalloc pool, so it can only be reused for
    26    objects of the same type.
    27  
    28  In general, types that are allocated using any of these should be
    29  marked `//go:notinheap` (see below).
    30  
    31  Objects that are allocated in unmanaged memory **must not** contain
    32  heap pointers unless the following rules are also obeyed:
    33  
    34  1. Any pointers from unmanaged memory to the heap must be added as
    35     explicit garbage collection roots in `runtime.markroot`.
    36  
    37  2. If the memory is reused, the heap pointers must be zero-initialized
    38     before they become visible as GC roots. Otherwise, the GC may
    39     observe stale heap pointers. See "Zero-initialization versus
    40     zeroing".
    41  
    42  Zero-initialization versus zeroing
    43  ==================================
    44  
    45  There are two types of zeroing in the runtime, depending on whether
    46  the memory is already initialized to a type-safe state.
    47  
    48  If memory is not in a type-safe state, meaning it potentially contains
    49  "garbage" because it was just allocated and it is being initialized
    50  for first use, then it must be *zero-initialized* using
    51  `memclrNoHeapPointers` or non-pointer writes. This does not perform
    52  write barriers.
    53  
    54  If memory is already in a type-safe state and is simply being set to
    55  the zero value, this must be done using regular writes, `typedmemclr`,
    56  or `memclrHasPointers`. This performs write barriers.
    57  
    58  Runtime-only compiler directives
    59  ================================
    60  
    61  In addition to the "//go:" directives documented in "go doc compile",
    62  the compiler supports additional directives only in the runtime.
    63  
    64  go:systemstack
    65  --------------
    66  
    67  `go:systemstack` indicates that a function must run on the system
    68  stack. This is checked dynamically by a special function prologue.
    69  
    70  go:nowritebarrier
    71  -----------------
    72  
    73  `go:nowritebarrier` directs the compiler to emit an error if the
    74  following function contains any write barriers. (It *does not*
    75  suppress the generation of write barriers; it is simply an assertion.)
    76  
    77  Usually you want `go:nowritebarrierrec`. `go:nowritebarrier` is
    78  primarily useful in situations where it's "nice" not to have write
    79  barriers, but not required for correctness.
    80  
    81  go:nowritebarrierrec and go:yeswritebarrierrec
    82  ----------------------------------------------
    83  
    84  `go:nowritebarrierrec` directs the compiler to emit an error if the
    85  following function or any function it calls recursively, up to a
    86  `go:yeswritebarrierrec`, contains a write barrier.
    87  
    88  Logically, the compiler floods the call graph starting from each
    89  `go:nowritebarrierrec` function and produces an error if it encounters
    90  a function containing a write barrier. This flood stops at
    91  `go:yeswritebarrierrec` functions.
    92  
    93  `go:nowritebarrierrec` is used in the implementation of the write
    94  barrier to prevent infinite loops.
    95  
    96  Both directives are used in the scheduler. The write barrier requires
    97  an active P (`getg().m.p != nil`) and scheduler code often runs
    98  without an active P. In this case, `go:nowritebarrierrec` is used on
    99  functions that release the P or may run without a P and
   100  `go:yeswritebarrierrec` is used when code re-acquires an active P.
   101  Since these are function-level annotations, code that releases or
   102  acquires a P may need to be split across two functions.
   103  
   104  go:notinheap
   105  ------------
   106  
   107  `go:notinheap` applies to type declarations. It indicates that a type
   108  must never be heap allocated. Specifically, pointers to this type must
   109  always fail the `runtime.inheap` check. The type may be used for
   110  global variables, for stack variables, or for objects in unmanaged
   111  memory (e.g., allocated with `sysAlloc`, `persistentalloc`, or
   112  `fixalloc`). Specifically:
   113  
   114  1. `new(T)`, `make([]T)`, `append([]T, ...)` and implicit heap
   115     allocation of T are disallowed. (Though implicit allocations are
   116     disallowed in the runtime anyway.)
   117  
   118  2. A pointer to a regular type (other than `unsafe.Pointer`) cannot be
   119     converted to a pointer to a `go:notinheap` type, even if they have
   120     the same underlying type.
   121  
   122  3. Any type that contains a `go:notinheap` type is itself
   123     `go:notinheap`. Structs and arrays are `go:notinheap` if their
   124     elements are. Maps and channels of `go:notinheap` types are
   125     disallowed. To keep things explicit, any type declaration where the
   126     type is implicitly `go:notinheap` must be explicitly marked
   127     `go:notinheap` as well.
   128  
   129  4. Write barriers on pointers to `go:notinheap` types can be omitted.
   130  
   131  The last point is the real benefit of `go:notinheap`. The runtime uses
   132  it for low-level internal structures to avoid memory barriers in the
   133  scheduler and the memory allocator where they are illegal or simply
   134  inefficient. This mechanism is reasonably safe and does not compromise
   135  the readability of the runtime.