Skip to content

Latest commit

 

History

History
704 lines (486 loc) · 25.5 KB

root.rst

File metadata and controls

704 lines (486 loc) · 25.5 KB

single: root; introduction

Roots

Roots tell the garbage collector where to start tracing <trace>. The garbage collector determines which blocks are reachable from the roots, and (in automatically managed <automatic memory management> pools) reclaims the unreachable blocks. This is quite efficient and can be a very good approximation to liveness <live>.

It is therefore important that all references that the client program can directly access are registered as roots, otherwise the garbage collector might recycle an object that would be used in the future. Some collectors, for example Boehm's, assume that all references stored in static data are roots; the Memory Pool System is more flexible, but requires the client program to declare which references are roots.

single: root; registering

Registering roots

You can register a root at any time by calling one of the mps_root_create functions. Roots may not be registered twice, and no two roots may overlap (that is, each reference is fixed by at most one root). Roots may be:

  1. in registers;
  2. on the program's control stack;
  3. in the program's static data;
  4. in heap not managed by the MPS (provided that you destroy the root before freeing it; see the Scheme interpreter's global symbol table <guide-lang-roots-rehash> for an example);
  5. in manually managed <manual memory management> pools (provided that you remove the root before freeing it).

Roots must not be in memory that is subject to garbage collection (and so roots must not be in automatically managed <automatic memory management> pools).

When you register a root you describe to the MPS how to scan it for references, providing your own scanning function in the cases of :cmps_root_create and :cmps_root_create_fmt. Such a root scanning function must follow the topic-scanning-protocol.

All the references in a root are of the same rank (just as in a formatted object). So they are all exact <exact reference>, ambiguous <ambiguous reference> or weak <weak reference (1)>.

Note

If the rank of the root is exact <exact reference>, or weak <weak reference (1)>, the references in the root must always be valid while the root is registered: that is, they must be references to actual objects or null pointers. This could be immediately after the root is registered, so the root must be valid before it is registered.

Note

As with scanning <topic-scanning> in general, it's safe to fix references that point to memory not managed by the MPS. These will be ignored.

Roots can be deregistered at any time by calling :cmps_root_destroy. All roots registered in an arena must be deregistered before the arena is destroyed.

There are four ways to register a root, depending on how you need to scan it for references:

  1. :cmps_root_create if you need a custom root scanning function (of type :cmps_root_scan_t);
  2. :cmps_root_create_fmt if the root consists of a block of objects belonging to an object format, which can be scanned by the format's scan method (of type :cmps_fmt_scan_t);
  3. :cmps_root_create_area if the root consists of an area of memory;
  4. :cmps_root_create_thread if the root consists of the registers and control stack of a thread. See topic-root-thread below.

Several of these categories of roots have variants for dealing with tagged references. See topic-scanning-tag.

pair: root; cautions

Cautions

Creating a root and then registering is similar to reserving a block and then committing it (in the topic-allocation-point-protocol), and similar cautions <topic-allocation-cautions> apply. Before registering a root:

  1. The root must be valid (that is, the appropriate root scanning function can scan it).
  2. All exact references in the root (references that are fixed by the root scanning function) must contain valid references or null pointers.
  3. You must not store a reference in the root to a block in an automatically managed pool (such a reference is hidden from the MPS until you register the root, and may become invalid).

So the typical sequence of operations when creating a root is:

  1. Initialize references in the root with null pointers or other safe values.
  2. Register the root.
  3. Fill in the references in the root.

pair: root; thread

Thread roots

Every thread's registers and control stack potentially contain references to allocated objects, so should be registered as a root by calling :cmps_root_create_thread.

The MPS's stack scanner needs to know how to find the cold end of the part of the stack to scan. The cold end of the relevant part of the stack can be found by taking the address of a local variable in the function that calls the main work function of your thread. You should take care to ensure that the work function is not inlined so that the address is definitely in the stack frame below any potential roots.

single: Scheme; thread root

For example, here's the code from the toy Scheme interpreter that registers a thread root and then calls the program:

mps_thr_t thread;
mps_root_t stack_root;
int exit_code;
void *cold = &cold;

res = mps_thread_reg(&thread, arena);
if (res != MPS_RES_OK) error("Couldn't register thread");

res = mps_root_create_thread(&stack_root, arena, thread, cold);
if (res != MPS_RES_OK) error("Couldn't create root");

exit_code = start(argc, argv);

mps_root_destroy(stack_root);
mps_thread_dereg(thread);

pair: root; rank

Ranks

pair: root; mode

Root modes

The root mode provides a way for the client to declare various facts about a root that allow the MPS to make optimizations. Roots that are declared to be constant need not be re-scanned, and roots that are declared to be protectable may have barriers placed on them, allowing the MPS to detect whether they have changed.

Note

The MPS does not currently perform either of these optimizations, so root modes have no effect. These features may be added in a future release.

single: root; interface

Root interface

pair: root; introspection

Root introspection