1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-25 23:10:47 -08:00
emacs/mps/manual/html/guide/lang.html
Gareth Rees 2ed2ff1893 Updated manual html
Copied from Perforce
 Change: 181750
 ServerID: perforce.ravenbrook.com
2013-05-13 21:04:49 +01:00

1201 lines
No EOL
118 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>3. Garbage collecting a language with the Memory Pool System &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Guide" href="index.html" />
<link rel="next" title="4. Debugging with the Memory Pool System" href="debug.html" />
<link rel="prev" title="2. Building the Memory Pool System" href="build.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="debug.html" title="4. Debugging with the Memory Pool System"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="build.html" title="2. Building the Memory Pool System"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Guide</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="garbage-collecting-a-language-with-the-memory-pool-system">
<span id="guide-lang"></span><span id="index-0"></span><h1>3. Garbage collecting a language with the Memory Pool System<a class="headerlink" href="#garbage-collecting-a-language-with-the-memory-pool-system" title="Permalink to this headline"></a></h1>
<p>Have you written the lexer, parser, code generator and the runtime
system for your programming language, and come to the realization that
you are going to need a memory manager too? If so, you&#8217;ve come to the
right place.</p>
<p>In this guide, I&#8217;ll explain how to use the MPS to add incremental,
moving, generational garbage collection to the runtime system for a
programming language.</p>
<p>I&#8217;m assuming that you are familiar with the overall architecture of
the MPS (see the chapter <a class="reference internal" href="overview.html#guide-overview"><em>Overview of the Memory Pool System</em></a>) and that you&#8217;ve
downloaded and built the MPS (see the chapter <a class="reference internal" href="build.html#guide-build"><em>Building the Memory Pool System</em></a>).</p>
<div class="section" id="the-scheme-interpreter">
<span id="index-1"></span><h2>3.1. The Scheme interpreter<a class="headerlink" href="#the-scheme-interpreter" title="Permalink to this headline"></a></h2>
<p>As a running example throughout this guide, I&#8217;ll be using a small
interpreter for a subset of the <a class="reference internal" href="../mmref/lang.html#term-scheme"><em class="xref std std-term">Scheme</em></a> programming language.
I&#8217;ll be quoting the relevant sections of code as needed, but you may
find it helpful to experiment with this interpreter yourself, in either
of its versions:</p>
<p><a class="reference download internal" href="../_downloads/scheme-malloc.c"><tt class="xref download docutils literal"><span class="pre">scheme-malloc.c</span></tt></a></p>
<blockquote>
<div>The toy Scheme interpreter before integration with the MPS, using
<a class="reference internal" href="../glossary/m.html#term-malloc"><em class="xref std std-term">malloc</em></a> and <a class="reference internal" href="../glossary/f.html#term-free-2"><em class="xref std std-term">free<sup>(2)</sup></em></a> for memory management.</div></blockquote>
<p><a class="reference download internal" href="../_downloads/scheme.c"><tt class="xref download docutils literal"><span class="pre">scheme.c</span></tt></a></p>
<blockquote>
<div>The toy Scheme interpreter after integration with the MPS.</div></blockquote>
<p>This simple interpreter allocates two kinds of objects on the
<a class="reference internal" href="../glossary/h.html#term-heap"><em class="xref std std-term">heap</em></a>:</p>
<ol class="arabic simple">
<li>All Scheme objects (there are no <a class="reference internal" href="../glossary/u.html#term-unboxed"><em class="xref std std-term">unboxed</em></a> objects).</li>
<li>The global symbol table: a hash table consisting of a vector of
pointers to strings.</li>
</ol>
<p>A Scheme object (whose type is not necessarily known) is represented by
an <tt class="docutils literal"><span class="pre">obj_t</span></tt>, which is a pointer to a union of every type in the
language:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">union</span> <span class="n">obj_u</span> <span class="o">*</span><span class="n">obj_t</span><span class="p">;</span>
<span class="k">typedef</span> <span class="k">union</span> <span class="n">obj_u</span> <span class="p">{</span>
<span class="n">type_s</span> <span class="n">type</span><span class="p">;</span>
<span class="n">pair_s</span> <span class="n">pair</span><span class="p">;</span>
<span class="n">symbol_s</span> <span class="n">symbol</span><span class="p">;</span>
<span class="n">integer_s</span> <span class="n">integer</span><span class="p">;</span>
<span class="n">special_s</span> <span class="n">special</span><span class="p">;</span>
<span class="n">operator_s</span> <span class="n">operator</span><span class="p">;</span>
<span class="n">string_s</span> <span class="n">string</span><span class="p">;</span>
<span class="n">port_s</span> <span class="n">port</span><span class="p">;</span>
<span class="n">character_s</span> <span class="n">character</span><span class="p">;</span>
<span class="n">vector_s</span> <span class="n">vector</span><span class="p">;</span>
<span class="n">table_s</span> <span class="n">table</span><span class="p">;</span>
<span class="n">buckets_s</span> <span class="n">buckets</span><span class="p">;</span>
<span class="p">}</span> <span class="n">obj_s</span><span class="p">;</span>
</pre></div>
</div>
<p>Each of these types is a structure whose first word is a number
specifying the type of the object (<tt class="docutils literal"><span class="pre">TYPE_PAIR</span></tt> for pairs,
<tt class="docutils literal"><span class="pre">TYPE_SYMBOL</span></tt> for symbols, and so on). For example, pairs are
represented by a pointer to the structure <tt class="docutils literal"><span class="pre">pair_s</span></tt> defined as
follows:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">pair_s</span> <span class="p">{</span>
<span class="n">type_t</span> <span class="n">type</span><span class="p">;</span> <span class="cm">/* TYPE_PAIR */</span>
<span class="n">obj_t</span> <span class="n">car</span><span class="p">,</span> <span class="n">cdr</span><span class="p">;</span> <span class="cm">/* first and second projections */</span>
<span class="p">}</span> <span class="n">pair_s</span><span class="p">;</span>
</pre></div>
</div>
<p>Because the first word of every object is its type, functions can
operate on objects generically, testing <tt class="docutils literal"><span class="pre">TYPE(obj)</span></tt> as necessary
(which is a macro for <tt class="docutils literal"><span class="pre">obj-&gt;type.type</span></tt>). For example, the
<tt class="docutils literal"><span class="pre">print()</span></tt> function is implemented like this:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">void</span> <span class="nf">print</span><span class="p">(</span><span class="n">obj_t</span> <span class="n">obj</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">depth</span><span class="p">,</span> <span class="kt">FILE</span> <span class="o">*</span><span class="n">stream</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">TYPE_INTEGER</span>:
<span class="n">fprintf</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="s">&quot;%ld&quot;</span><span class="p">,</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">integer</span><span class="p">.</span><span class="n">integer</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="n">TYPE_SYMBOL</span>:
<span class="n">fputs</span><span class="p">(</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">symbol</span><span class="p">.</span><span class="n">string</span><span class="p">,</span> <span class="n">stream</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="cm">/* ... and so on for the other types ... */</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Each constructor allocates memory for the new object by calling
<tt class="docutils literal"><span class="pre">malloc</span></tt>. For example, <tt class="docutils literal"><span class="pre">make_pair</span></tt> is the constructor for pairs:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">obj_t</span> <span class="nf">make_pair</span><span class="p">(</span><span class="n">obj_t</span> <span class="n">car</span><span class="p">,</span> <span class="n">obj_t</span> <span class="n">cdr</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">obj_t</span> <span class="n">obj</span> <span class="o">=</span> <span class="p">(</span><span class="n">obj_t</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">pair_s</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="n">obj</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;out of memory&quot;</span><span class="p">);</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">pair</span><span class="p">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">TYPE_PAIR</span><span class="p">;</span>
<span class="n">CAR</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">car</span><span class="p">;</span>
<span class="n">CDR</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">cdr</span><span class="p">;</span>
<span class="k">return</span> <span class="n">obj</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Objects are never freed, because it is necessary to prove that they
are <a class="reference internal" href="../glossary/d.html#term-dead"><em class="xref std std-term">dead</em></a> before their memory can be <a class="reference internal" href="../glossary/r.html#term-reclaim"><em class="xref std std-term">reclaimed</em></a>. To
prove that they are dead, we need a <a class="reference internal" href="../glossary/t.html#term-trace"><em class="xref std std-term">tracing</em></a>
<a class="reference internal" href="../glossary/g.html#term-garbage-collector"><em class="xref std std-term">garbage collector</em></a>, which the MPS will provide.</p>
</div>
<div class="section" id="choosing-an-arena-class">
<span id="index-2"></span><h2>3.2. Choosing an arena class<a class="headerlink" href="#choosing-an-arena-class" title="Permalink to this headline"></a></h2>
<p>You&#8217;ll recall from the <a class="reference internal" href="overview.html#guide-overview"><em>Overview of the Memory Pool System</em></a> that the functionality of
the MPS is divided between the <a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arenas</em></a>, which request memory
from (and return it to) the operating system, and <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pools</em></a>, which
allocate blocks of memory for your program.</p>
<p>There are two main classes of arena: the <a class="reference internal" href="../glossary/c.html#term-client-arena"><em class="xref std std-term">client arena</em></a>,
<a class="reference internal" href="../topic/arena.html#mps_arena_class_cl" title="mps_arena_class_cl"><tt class="xref c c-func docutils literal"><span class="pre">mps_arena_class_cl()</span></tt></a>, which gets its memory from your program,
and the <a class="reference internal" href="../glossary/v.html#term-virtual-memory-arena"><em class="xref std std-term">virtual memory arena</em></a>, <a class="reference internal" href="../topic/arena.html#mps_arena_class_vm" title="mps_arena_class_vm"><tt class="xref c c-func docutils literal"><span class="pre">mps_arena_class_vm()</span></tt></a>,
which gets its memory from the operating system&#8217;s <a class="reference internal" href="../glossary/v.html#term-virtual-memory"><em class="xref std std-term">virtual
memory</em></a> interface.</p>
<p>The client arena is intended for use on embedded systems where there
is no virtual memory, and has a couple of disadvantages (you have to
decide how much memory you are going to use; and the MPS can&#8217;t return
memory to the operating system for use by other processes) so for
general-purpose programs you&#8217;ll want to use the virtual memory arena.</p>
<p>You&#8217;ll need a couple of headers: <tt class="docutils literal"><span class="pre">mps.h</span></tt> for the MPS interface, and
<tt class="docutils literal"><span class="pre">mpsavm.h</span></tt> for the virtual memory arena class:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#include &quot;mps.h&quot;</span>
<span class="cp">#include &quot;mpsavm.h&quot;</span>
</pre></div>
</div>
<p>There&#8217;s only one arena, and many MPS functions take an arena as an
argument, so it makes sense for the arena to be a global variable
rather than having to pass it around everywhere:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">mps_arena_t</span> <span class="n">arena</span><span class="p">;</span>
</pre></div>
</div>
<p>Create an arena by calling <a class="reference internal" href="../topic/arena.html#mps_arena_create_k" title="mps_arena_create_k"><tt class="xref c c-func docutils literal"><span class="pre">mps_arena_create_k()</span></tt></a>. This function
takes a <a class="reference internal" href="../glossary/k.html#term-keyword-argument"><em class="xref std std-term">keyword argument</em></a> when creating a virtual memory arena:
the size of virtual <a class="reference internal" href="../glossary/a.html#term-address-space"><em class="xref std std-term">address space</em></a> (<em>not</em> <a class="reference internal" href="../glossary/r.html#term-ram"><em class="xref std std-term">RAM</em></a>), in
bytes, that the arena will reserve initially. The MPS will ask for
more address space if it runs out, but the more times it has to extend
its address space, the less efficient garbage collection will become.
The MPS works best if you reserve an address space that is several
times larger than your peak memory usage.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">Functions in the MPS interface take <a class="reference internal" href="../glossary/k.html#term-keyword-argument"><em class="xref std std-term">keyword arguments</em></a> for
arguments that are optional, or are only required in some
circumstances. These argument are passed in the form of an array
of structures of type <a class="reference internal" href="../topic/keyword.html#mps_arg_s" title="mps_arg_s"><tt class="xref c c-type docutils literal"><span class="pre">mps_arg_s</span></tt></a>. See
<a class="reference internal" href="../topic/keyword.html#topic-keyword"><em>Keyword arguments</em></a> for the full details.</p>
</div>
<p>Let&#8217;s reserve 32 megabytes:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_res_t</span> <span class="n">res</span><span class="p">;</span>
<span class="n">MPS_ARGS_BEGIN</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="p">{</span>
<span class="n">MPS_ARGS_ADD</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">MPS_KEY_ARENA_SIZE</span><span class="p">,</span> <span class="mi">32</span> <span class="o">*</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">1024</span><span class="p">);</span>
<span class="n">MPS_ARGS_DONE</span><span class="p">(</span><span class="n">args</span><span class="p">);</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_arena_create_k</span><span class="p">(</span><span class="o">&amp;</span><span class="n">arena</span><span class="p">,</span> <span class="n">mps_arena_class_vm</span><span class="p">(),</span> <span class="n">args</span><span class="p">);</span>
<span class="p">}</span> <span class="n">MPS_ARGS_END</span><span class="p">(</span><span class="n">args</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t create arena&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p><a class="reference internal" href="../topic/arena.html#mps_arena_create_k" title="mps_arena_create_k"><tt class="xref c c-func docutils literal"><span class="pre">mps_arena_create_k()</span></tt></a> is typical of functions in the MPS
interface in that it stores its result in a location pointed to by an
<a class="reference internal" href="../glossary/o.html#term-out-parameter"><em class="xref std std-term">out parameter</em></a> (here, <tt class="docutils literal"><span class="pre">&amp;arena</span></tt>) and returns a <a class="reference internal" href="../glossary/r.html#term-result-code"><em class="xref std std-term">result
code</em></a>, which is <a class="reference internal" href="../topic/error.html#MPS_RES_OK" title="MPS_RES_OK"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_OK</span></tt></a> if the function succeeded, or
some other value if it failed.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p>The MPS is designed to co-operate with other memory managers, so
when integrating your language with the MPS you need not feel
obliged to move all your memory management to the MPS: you can
continue to use <tt class="docutils literal"><span class="pre">malloc</span></tt> and <tt class="docutils literal"><span class="pre">free</span></tt> to manage some of your
memory, for example, while using the MPS for the rest.</p>
<p class="last">The toy Scheme interpreter illustrates this by continuing to use
<tt class="docutils literal"><span class="pre">malloc</span></tt> and <tt class="docutils literal"><span class="pre">free</span></tt> to manage its global symbol table.</p>
</div>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topics</p>
<p class="last"><a class="reference internal" href="../topic/arena.html#topic-arena"><em>Arenas</em></a>, <a class="reference internal" href="../topic/error.html#topic-error"><em>Error handing</em></a>.</p>
</div>
</div>
<div class="section" id="choosing-a-pool-class">
<span id="index-3"></span><h2>3.3. Choosing a pool class<a class="headerlink" href="#choosing-a-pool-class" title="Permalink to this headline"></a></h2>
<p>Pool classes come with a policy for how their memory will be managed:
some pool classes use <a class="reference internal" href="../glossary/a.html#term-automatic-memory-management"><em class="xref std std-term">automatic memory management</em></a> and others
use <a class="reference internal" href="../glossary/m.html#term-manual-memory-management"><em class="xref std std-term">manual</em></a>; some use <a class="reference internal" href="../glossary/m.html#term-moving-garbage-collector"><em class="xref std std-term">moving
collection</em></a> and others <a class="reference internal" href="../glossary/n.html#term-non-moving-garbage-collector"><em class="xref std std-term">non-moving</em></a>.</p>
<p>The section <a class="reference internal" href="../pool/intro.html#pool-choose"><em>Choosing a pool class</em></a> in the <a class="reference internal" href="../pool/index.html#pool"><em>Pool reference</em></a> contains a procedure
for choosing a pool class. In the case of the toy Scheme interpreter,
the answers to the questions are (1) yes, the MPS needs to
automatically reclaim unreachable blocks; (2) yes, it&#8217;s acceptable for
the MPS to move blocks in memory and protect them with <a class="reference internal" href="../glossary/b.html#term-barrier-1"><em class="xref std std-term">barriers<sup>(1)</sup></em></a>; and (3) the Scheme objects will contain <a class="reference internal" href="../glossary/e.html#term-exact-reference"><em class="xref std std-term">exact references</em></a>
to other Scheme objects in the same pool.</p>
<p>The recommended class is <a class="reference internal" href="../pool/amc.html#pool-amc"><em>AMC (Automatic Mostly-Copying)</em></a>. This pool class uses
automatic memory management, moving garbage collection,
<a class="reference internal" href="../glossary/a.html#term-allocation-point"><em class="xref std std-term">allocation points</em></a> and <a class="reference internal" href="../glossary/f.html#term-formatted-object"><em class="xref std std-term">formatted objects</em></a>, so it will
provide an introduction to these features of the MPS.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">The MPS is designed for pools of different classes to co-exist in
the same arena, so that objects requiring different memory
management policies can be segregated into pools of suitable
classes.</p>
</div>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/pool.html#topic-pool"><em>Pools</em></a>.</p>
</div>
</div>
<div class="section" id="describing-your-objects">
<span id="index-4"></span><h2>3.4. Describing your objects<a class="headerlink" href="#describing-your-objects" title="Permalink to this headline"></a></h2>
<p>In order for the MPS to be able to automatically manage your objects,
you need to tell it how to perform various operations on an object
(<a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scan</em></a> it for <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">references</em></a>; replace it with a
<a class="reference internal" href="../glossary/f.html#term-forwarding-object"><em class="xref std std-term">forwarding</em></a> or <a class="reference internal" href="../glossary/p.html#term-padding-object"><em class="xref std std-term">padding object</em></a>, and
so on). You do this by creating an <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a>. Here&#8217;s the
code for creating the object format for the toy Scheme interpreter:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">struct</span> <span class="n">mps_fmt_A_s</span> <span class="n">obj_fmt_s</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">ALIGNMENT</span><span class="p">,</span>
<span class="n">obj_scan</span><span class="p">,</span>
<span class="n">obj_skip</span><span class="p">,</span>
<span class="nb">NULL</span><span class="p">,</span>
<span class="n">obj_fwd</span><span class="p">,</span>
<span class="n">obj_isfwd</span><span class="p">,</span>
<span class="n">obj_pad</span><span class="p">,</span>
<span class="p">};</span>
<span class="n">mps_fmt_t</span> <span class="n">obj_fmt</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_fmt_create_A</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj_fmt</span><span class="p">,</span> <span class="n">arena</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj_fmt_s</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t create obj format&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>The structure <a class="reference internal" href="../topic/format.html#mps_fmt_A_s" title="mps_fmt_A_s"><tt class="xref c c-type docutils literal"><span class="pre">mps_fmt_A_s</span></tt></a> is the simplest of several object
format variants that are appropriate for moving pools like AMC.</p>
<p>The first element of the structure is the <a class="reference internal" href="../glossary/a.html#term-alignment"><em class="xref std std-term">alignment</em></a> of objects
belonging to this format. Determining the alignment is hard to do
portably, because it depends on the target architecture and on the way
the compiler lays out its structures in memory. Here are some things
you might try:</p>
<ol class="arabic">
<li><p class="first">Some modern compilers support the <tt class="docutils literal"><span class="pre">alignof</span></tt> operator:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#define ALIGNMENT alignof(obj_s)</span>
</pre></div>
</div>
</li>
<li><p class="first">On older compilers you may be able to use this trick:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#define ALIGNMENT offsetof(struct {char c; obj_s obj;}, obj)</span>
</pre></div>
</div>
<p>but this is not reliable because some compilers pack structures
more tightly than their alignment requirements in some
circumstances (for example, GCC if the <tt class="docutils literal"><span class="pre">-fstruct-pack</span></tt> option is
specified).</p>
</li>
<li><p class="first">The MPS interface provides the type <a class="reference internal" href="../topic/interface.html#mps_word_t" title="mps_word_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_word_t</span></tt></a>, which is
an unsigned integral type that is the same size as the platform&#8217;s
<a class="reference internal" href="../glossary/o.html#term-object-pointer"><em class="xref std std-term">object pointer</em></a> types.</p>
<p>So if you know that all your objects can be word-aligned, you can
use:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#define ALIGNMENT sizeof(mps_word_t)</span>
</pre></div>
</div>
</li>
</ol>
<p>The other elements of the structure are the <a class="reference internal" href="../glossary/f.html#term-format-method"><em class="xref std std-term">format methods</em></a>,
which are described in the following sections. (The <tt class="docutils literal"><span class="pre">NULL</span></tt> in the
structure is a placeholder for the <a class="reference internal" href="../glossary/c.html#term-copy-method"><em class="xref std std-term">copy method</em></a>, which is now
obsolete.)</p>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/format.html#topic-format"><em>Object formats</em></a>.</p>
</div>
<div class="section" id="the-scan-method">
<span id="guide-lang-scan"></span><span id="index-5"></span><h3>3.4.1. The scan method<a class="headerlink" href="#the-scan-method" title="Permalink to this headline"></a></h3>
<p>The <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a> is a function of type
<a class="reference internal" href="../topic/format.html#mps_fmt_scan_t" title="mps_fmt_scan_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_fmt_scan_t</span></tt></a>. It is called by the MPS to <a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scan</em></a> a
block of memory. Its task is to identify all references within the
objects in the block of memory, and &#8220;fix&#8221; them, by calling the macros
<a class="reference internal" href="../topic/scanning.html#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> and <a class="reference internal" href="../topic/scanning.html#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> on each reference (possibly
via the convenience macro <a class="reference internal" href="../topic/scanning.html#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a>).</p>
<p>&#8220;Fixing&#8221; is a generic operation whose effect depends on the context in
which the scan method was called. The scan method is called to
discover references and so determine which objects are <a class="reference internal" href="../glossary/l.html#term-live"><em class="xref std std-term">alive</em></a> and which are <a class="reference internal" href="../glossary/d.html#term-dead"><em class="xref std std-term">dead</em></a>, and also to update references
after objects have been moved.</p>
<p>Here&#8217;s the scan method for the toy Scheme interpreter:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">mps_res_t</span> <span class="nf">obj_scan</span><span class="p">(</span><span class="n">mps_ss_t</span> <span class="n">ss</span><span class="p">,</span> <span class="n">mps_addr_t</span> <span class="n">base</span><span class="p">,</span> <span class="n">mps_addr_t</span> <span class="n">limit</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">MPS_SCAN_BEGIN</span><span class="p">(</span><span class="n">ss</span><span class="p">)</span> <span class="p">{</span>
<span class="k">while</span> <span class="p">(</span><span class="n">base</span> <span class="o">&lt;</span> <span class="n">limit</span><span class="p">)</span> <span class="p">{</span>
<span class="n">obj_t</span> <span class="n">obj</span> <span class="o">=</span> <span class="n">base</span><span class="p">;</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">TYPE_PAIR</span>:
<span class="n">FIX</span><span class="p">(</span><span class="n">CAR</span><span class="p">(</span><span class="n">obj</span><span class="p">));</span>
<span class="n">FIX</span><span class="p">(</span><span class="n">CDR</span><span class="p">(</span><span class="n">obj</span><span class="p">));</span>
<span class="n">base</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">base</span> <span class="o">+</span> <span class="n">ALIGN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">pair_s</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="n">TYPE_INTEGER</span>:
<span class="n">base</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">base</span> <span class="o">+</span> <span class="n">ALIGN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">integer_s</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
<span class="cm">/* ... and so on for the other types ... */</span>
<span class="nl">default:</span>
<span class="n">assert</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Unexpected object on the heap</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">abort</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span> <span class="n">MPS_SCAN_END</span><span class="p">(</span><span class="n">ss</span><span class="p">);</span>
<span class="k">return</span> <span class="n">MPS_RES_OK</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The scan method receives a <a class="reference internal" href="../glossary/s.html#term-scan-state"><em class="xref std std-term">scan state</em></a> (<tt class="docutils literal"><span class="pre">ss</span></tt>) argument, and
the block of memory to scan, from <tt class="docutils literal"><span class="pre">base</span></tt> (inclusive) to <tt class="docutils literal"><span class="pre">limit</span></tt>
(exclusive). This block of memory is known to be packed with objects
belonging to the object format, and so the scan method loops over the
objects in the block, dispatching on the type of each object, and then
updating <tt class="docutils literal"><span class="pre">base</span></tt> to point to the next object in the block.</p>
<p>For each reference in an object <tt class="docutils literal"><span class="pre">obj_scan</span></tt> fixes it by calling
<a class="reference internal" href="../topic/scanning.html#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a> via the macro <tt class="docutils literal"><span class="pre">FIX</span></tt>, which is defined as
follows:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#define FIX(ref) \</span>
<span class="cp"> do { \</span>
<span class="cp"> mps_addr_t _addr = (ref); </span><span class="cm">/* copy to local to avoid type pun */</span><span class="cp"> \</span>
<span class="cp"> mps_res_t res = MPS_FIX12(ss, &amp;_addr); \</span>
<span class="cp"> if (res != MPS_RES_OK) return res; \</span>
<span class="cp"> (ref) = _addr; \</span>
<span class="cp"> } while (0)</span>
</pre></div>
</div>
<p>Each call to <a class="reference internal" href="../topic/scanning.html#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a> must appear between calls to the
macros <a class="reference internal" href="../topic/scanning.html#MPS_SCAN_BEGIN" title="MPS_SCAN_BEGIN"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_BEGIN()</span></tt></a> and <a class="reference internal" href="../topic/scanning.html#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>. It&#8217;s
usually most convenient to call <a class="reference internal" href="../topic/scanning.html#MPS_SCAN_BEGIN" title="MPS_SCAN_BEGIN"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_BEGIN()</span></tt></a> at the start
of the function and <a class="reference internal" href="../topic/scanning.html#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a> at the end, as here.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Notes</p>
<ol class="last arabic simple">
<li>When the MPS calls your scan method, it may be part-way through
moving your objects. It is therefore essential that the scan
method only examine objects in the range of addresses it is
given. Objects in other ranges of addresses are not guaranteed
to be in a consistent state.</li>
<li>Scanning is an operation on the <a class="reference internal" href="../glossary/c.html#term-critical-path"><em class="xref std std-term">critical path</em></a> of the
MPS, which means that it is important that it runs as quickly
as possible.</li>
<li>If your reference is <a class="reference internal" href="../glossary/t.html#term-tagged-reference"><em class="xref std std-term">tagged</em></a>, you
must remove the tag before fixing it. (This is not quite true,
but see <a class="reference internal" href="../topic/scanning.html#topic-scanning-tag"><em>Tagged references</em></a> for the full story.)</li>
<li>The &#8220;fix&#8221; operation may update the reference. So if your
reference is tagged, you must make sure that the tag is
restored after the reference is updated.</li>
<li>The &#8220;fix&#8221; operation may fail by returning a <a class="reference internal" href="../glossary/r.html#term-result-code"><em class="xref std std-term">result code</em></a>
other than <a class="reference internal" href="../topic/error.html#MPS_RES_OK" title="MPS_RES_OK"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_OK</span></tt></a>. A scan function must
propagate such a result code to the caller, and should do so as
soon as practicable.</li>
</ol>
</div>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topics</p>
<p class="last"><a class="reference internal" href="../topic/format.html#topic-format"><em>Object formats</em></a>, <a class="reference internal" href="../topic/scanning.html#topic-scanning"><em>Scanning</em></a>.</p>
</div>
</div>
<div class="section" id="the-skip-method">
<span id="guide-lang-skip"></span><span id="index-6"></span><h3>3.4.2. The skip method<a class="headerlink" href="#the-skip-method" title="Permalink to this headline"></a></h3>
<p>The <a class="reference internal" href="../glossary/s.html#term-skip-method"><em class="xref std std-term">skip method</em></a> is a function of type
<a class="reference internal" href="../topic/format.html#mps_fmt_skip_t" title="mps_fmt_skip_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_fmt_skip_t</span></tt></a>. It is called by the MPS to skip over an
object belonging to the format, and also to determine its size.</p>
<p>Here&#8217;s the skip method for the toy Scheme interpreter:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">mps_addr_t</span> <span class="nf">obj_skip</span><span class="p">(</span><span class="n">mps_addr_t</span> <span class="n">base</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">obj_t</span> <span class="n">obj</span> <span class="o">=</span> <span class="n">base</span><span class="p">;</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">TYPE_PAIR</span>:
<span class="n">base</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">base</span> <span class="o">+</span> <span class="n">ALIGN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">pair_s</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="n">TYPE_INTEGER</span>:
<span class="n">base</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">base</span> <span class="o">+</span> <span class="n">ALIGN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">integer_s</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
<span class="cm">/* ... and so on for the other types ... */</span>
<span class="nl">default:</span>
<span class="n">assert</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Unexpected object on the heap</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">abort</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">base</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The argument <tt class="docutils literal"><span class="pre">base</span></tt> is the address to the base of the object. The
skip method must return the address of the base of the &#8220;next object&#8221;:
in formats of variant A like this one, this is the address just past
the end of the object, rounded up to the object format&#8217;s alignment.</p>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/format.html#topic-format"><em>Object formats</em></a>.</p>
</div>
</div>
<div class="section" id="the-forward-method">
<span id="guide-lang-fwd"></span><span id="index-7"></span><h3>3.4.3. The forward method<a class="headerlink" href="#the-forward-method" title="Permalink to this headline"></a></h3>
<p>The <a class="reference internal" href="../glossary/f.html#term-forward-method"><em class="xref std std-term">forward method</em></a> is a function of type
<a class="reference internal" href="../topic/format.html#mps_fmt_fwd_t" title="mps_fmt_fwd_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_fmt_fwd_t</span></tt></a>. It is called by the MPS after it has moved an
object, and its task is to replace the old object with a
<a class="reference internal" href="../glossary/f.html#term-forwarding-object"><em class="xref std std-term">forwarding object</em></a> pointing to the new location of the object.</p>
<div class="figure align-center">
<img alt="Diagram: Copying garbage collection." src="../_images/copying1.svg" /><p class="caption">Copying garbage collection.</p>
</div>
<p>The forwarding object must satisfy these properties:</p>
<ol class="arabic simple">
<li>It must be scannable and skippable, and so it will need to have a
type field to distinguish it from other Scheme objects.</li>
<li>It must contain a pointer to the new location of the object (a
<a class="reference internal" href="../glossary/f.html#term-forwarding-pointer"><em class="xref std std-term">forwarding pointer</em></a>).</li>
<li>The <a class="reference internal" href="#guide-lang-scan"><em>scan method</em></a> and the <a class="reference internal" href="#guide-lang-skip"><em>skip method</em></a> will both need to know the length of the
forwarding object. This can be arbitrarily long (in the case of
string objects, for example) so it must contain a length field.</li>
</ol>
<p>This poses a problem, because the above analysis suggests that
forwarding objects need to contain at least three words, but Scheme
objects might be as small as two words (for example, integers).</p>
<p>This conundrum can be solved by having two types of forwarding object.
The first type is suitable for forwarding objects of three words or
longer:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">fwd_s</span> <span class="p">{</span>
<span class="n">type_t</span> <span class="n">type</span><span class="p">;</span> <span class="cm">/* TYPE_FWD */</span>
<span class="n">obj_t</span> <span class="n">fwd</span><span class="p">;</span> <span class="cm">/* forwarded object */</span>
<span class="kt">size_t</span> <span class="n">size</span><span class="p">;</span> <span class="cm">/* total size of this object */</span>
<span class="p">}</span> <span class="n">fwd_s</span><span class="p">;</span>
</pre></div>
</div>
<p>while the second type is suitable for forwarding objects of two words:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">fwd2_s</span> <span class="p">{</span>
<span class="n">type_t</span> <span class="n">type</span><span class="p">;</span> <span class="cm">/* TYPE_FWD2 */</span>
<span class="n">obj_t</span> <span class="n">fwd</span><span class="p">;</span> <span class="cm">/* forwarded object */</span>
<span class="p">}</span> <span class="n">fwd2_s</span><span class="p">;</span>
</pre></div>
</div>
<p>Here&#8217;s the forward method for the toy Scheme interpreter:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">void</span> <span class="nf">obj_fwd</span><span class="p">(</span><span class="n">mps_addr_t</span> <span class="n">old</span><span class="p">,</span> <span class="n">mps_addr_t</span> <span class="n">new</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">obj_t</span> <span class="n">obj</span> <span class="o">=</span> <span class="n">old</span><span class="p">;</span>
<span class="n">mps_addr_t</span> <span class="n">limit</span> <span class="o">=</span> <span class="n">obj_skip</span><span class="p">(</span><span class="n">old</span><span class="p">);</span>
<span class="kt">size_t</span> <span class="n">size</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">limit</span> <span class="o">-</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">old</span><span class="p">;</span>
<span class="n">assert</span><span class="p">(</span><span class="n">size</span> <span class="o">&gt;=</span> <span class="n">ALIGN_UP</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">fwd2_s</span><span class="p">)));</span>
<span class="k">if</span> <span class="p">(</span><span class="n">size</span> <span class="o">==</span> <span class="n">ALIGN_UP</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">fwd2_s</span><span class="p">)))</span> <span class="p">{</span>
<span class="n">TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">TYPE_FWD2</span><span class="p">;</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">fwd2</span><span class="p">.</span><span class="n">fwd</span> <span class="o">=</span> <span class="n">new</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">TYPE_FWD</span><span class="p">;</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">fwd</span><span class="p">.</span><span class="n">fwd</span> <span class="o">=</span> <span class="n">new</span><span class="p">;</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">fwd</span><span class="p">.</span><span class="n">size</span> <span class="o">=</span> <span class="n">size</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The argument <tt class="docutils literal"><span class="pre">old</span></tt> is the old address of the object, and <tt class="docutils literal"><span class="pre">new</span></tt> is
the location to which it has been moved.</p>
<p>The forwarding objects must be scannable and skippable, so the
following code must be added to <tt class="docutils literal"><span class="pre">obj_scan</span></tt> and <tt class="docutils literal"><span class="pre">obj_skip</span></tt>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">case</span> <span class="n">TYPE_FWD</span>:
<span class="n">base</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">base</span> <span class="o">+</span> <span class="n">ALIGN_UP</span><span class="p">(</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">fwd</span><span class="p">.</span><span class="n">size</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="n">TYPE_FWD2</span>:
<span class="n">base</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">base</span> <span class="o">+</span> <span class="n">ALIGN_UP</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">fwd2_s</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
</pre></div>
</div>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p>Objects that consist of a single word present a problem for the
design of the forwarding object. In the toy Scheme interpreter, this
happens on some 64-bit platforms, where a pointer is 8&nbsp;bytes long,
and a <tt class="docutils literal"><span class="pre">character_s</span></tt> object (which consists of a 4-byte <tt class="docutils literal"><span class="pre">int</span></tt>
and a 1-byte <tt class="docutils literal"><span class="pre">char</span></tt>) is also 8 bytes long.</p>
<p>There are a couple of solutions to this problem:</p>
<ol class="last arabic simple">
<li>Allocate the small objects with enough padding so that they can
be forwarded. (This is how the problem is solved in the toy
Scheme interpreter.)</li>
<li>Use a <a class="reference internal" href="../glossary/t.html#term-tag"><em class="xref std std-term">tag</em></a> to distinguish between the client object and
a forwarding object that replaces it. It might help to allocate
the small objects in their own pool so that the number of types
that the scan method has to distinguish is minimized. Since
these objects do not contain references, they could be
allocated from the <a class="reference internal" href="../pool/amcz.html#pool-amcz"><em>AMCZ (Automatic Mostly-Copying Zero-rank)</em></a> pool, and so the cost of
scanning them could be avoided.</li>
</ol>
</div>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/format.html#topic-format"><em>Object formats</em></a>.</p>
</div>
</div>
<div class="section" id="the-is-forwarded-method">
<span id="guide-lang-isfwd"></span><span id="index-8"></span><h3>3.4.4. The is-forwarded method<a class="headerlink" href="#the-is-forwarded-method" title="Permalink to this headline"></a></h3>
<p>The <a class="reference internal" href="../glossary/i.html#term-is-forwarded-method"><em class="xref std std-term">is-forwarded method</em></a> is a function of type
<a class="reference internal" href="../topic/format.html#mps_fmt_isfwd_t" title="mps_fmt_isfwd_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_fmt_isfwd_t</span></tt></a>. It is called by the MPS to determine if an
object is a <a class="reference internal" href="../glossary/f.html#term-forwarding-object"><em class="xref std std-term">forwarding object</em></a>, and if it is, to determine the
location where that object was moved.</p>
<p>Here&#8217;s the is-forwarded method for the toy Scheme interpreter:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">mps_addr_t</span> <span class="nf">obj_isfwd</span><span class="p">(</span><span class="n">mps_addr_t</span> <span class="n">addr</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">obj_t</span> <span class="n">obj</span> <span class="o">=</span> <span class="n">addr</span><span class="p">;</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">TYPE_FWD2</span>:
<span class="k">return</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">fwd2</span><span class="p">.</span><span class="n">fwd</span><span class="p">;</span>
<span class="k">case</span> <span class="n">TYPE_FWD</span>:
<span class="k">return</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">fwd</span><span class="p">.</span><span class="n">fwd</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>It receives the address of an object, and returns the address to which
that object was moved, or <tt class="docutils literal"><span class="pre">NULL</span></tt> if the object was not moved.</p>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/format.html#topic-format"><em>Object formats</em></a>.</p>
</div>
</div>
<div class="section" id="the-padding-method">
<span id="guide-lang-pad"></span><span id="index-9"></span><h3>3.4.5. The padding method<a class="headerlink" href="#the-padding-method" title="Permalink to this headline"></a></h3>
<p>The <a class="reference internal" href="../glossary/p.html#term-padding-method"><em class="xref std std-term">padding method</em></a> is a function of type
<a class="reference internal" href="../topic/format.html#mps_fmt_pad_t" title="mps_fmt_pad_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_fmt_pad_t</span></tt></a>. It is called by the MPS to fill a block of
memory with a <a class="reference internal" href="../glossary/p.html#term-padding-object"><em class="xref std std-term">padding object</em></a>: this is an object that fills
gaps in a block of <a class="reference internal" href="../glossary/f.html#term-formatted-object"><em class="xref std std-term">formatted objects</em></a>, for
example to enable the MPS to pack objects into fixed-size units (such
as operating system <a class="reference internal" href="../glossary/p.html#term-page"><em class="xref std std-term">pages</em></a>).</p>
<p>A padding object must be scannable and skippable, and not confusable
with a <a class="reference internal" href="../glossary/f.html#term-forwarding-object"><em class="xref std std-term">forwarding object</em></a>. This means they need a type and a
size. However, padding objects might need to be as small as the
alignment of the object format, which was specified to be a single
word. As with forwarding objects, this can be solved by having two
types of padding object. The first type is suitable for padding
objects of two words or longer:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">pad_s</span> <span class="p">{</span>
<span class="n">type_t</span> <span class="n">type</span><span class="p">;</span> <span class="cm">/* TYPE_PAD */</span>
<span class="kt">size_t</span> <span class="n">size</span><span class="p">;</span> <span class="cm">/* total size of this object */</span>
<span class="p">}</span> <span class="n">pad_s</span><span class="p">;</span>
</pre></div>
</div>
<p>while the second type is suitable for padding objects consisting of a
single word:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">pad1_s</span> <span class="p">{</span>
<span class="n">type_t</span> <span class="n">type</span><span class="p">;</span> <span class="cm">/* TYPE_PAD1 */</span>
<span class="p">}</span> <span class="n">pad1_s</span><span class="p">;</span>
</pre></div>
</div>
<p>Here&#8217;s the padding method:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">void</span> <span class="nf">obj_pad</span><span class="p">(</span><span class="n">mps_addr_t</span> <span class="n">addr</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">obj_t</span> <span class="n">obj</span> <span class="o">=</span> <span class="n">addr</span><span class="p">;</span>
<span class="n">assert</span><span class="p">(</span><span class="n">size</span> <span class="o">&gt;=</span> <span class="n">ALIGN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">pad1_s</span><span class="p">)));</span>
<span class="k">if</span> <span class="p">(</span><span class="n">size</span> <span class="o">==</span> <span class="n">ALIGN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">pad1_s</span><span class="p">)))</span> <span class="p">{</span>
<span class="n">TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">TYPE_PAD1</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">TYPE_PAD</span><span class="p">;</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">pad</span><span class="p">.</span><span class="n">size</span> <span class="o">=</span> <span class="n">size</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The argument <tt class="docutils literal"><span class="pre">addr</span></tt> is the address at which the padding object must be created, and <tt class="docutils literal"><span class="pre">size</span></tt> is its size in bytes: this will always be a multiple of the alignment of the object format.</p>
<p>The padding objects must be scannable and skippable, so the following
code must be added to <tt class="docutils literal"><span class="pre">obj_scan</span></tt> and <tt class="docutils literal"><span class="pre">obj_skip</span></tt>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">case</span> <span class="n">TYPE_PAD</span>:
<span class="n">base</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">base</span> <span class="o">+</span> <span class="n">ALIGN</span><span class="p">(</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">pad</span><span class="p">.</span><span class="n">size</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="n">TYPE_PAD1</span>:
<span class="n">base</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">base</span> <span class="o">+</span> <span class="n">ALIGN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">pad1_s</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
</pre></div>
</div>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/format.html#topic-format"><em>Object formats</em></a>.</p>
</div>
</div>
</div>
<div class="section" id="generation-chains">
<span id="index-10"></span><h2>3.5. Generation chains<a class="headerlink" href="#generation-chains" title="Permalink to this headline"></a></h2>
<p>The AMC pool requires not only an object format but a
<a class="reference internal" href="../glossary/g.html#term-generation-chain"><em class="xref std std-term">generation chain</em></a>. This specifies the generation structure of
the <a class="reference internal" href="../glossary/g.html#term-generational-garbage-collection"><em class="xref std std-term">generational garbage collection</em></a>.</p>
<p>You create a generation chain by constructing an array of structures
of type <a class="reference internal" href="../topic/collection.html#mps_gen_param_s" title="mps_gen_param_s"><tt class="xref c c-type docutils literal"><span class="pre">mps_gen_param_s</span></tt></a>, one for each generation, and
passing them to <a class="reference internal" href="../topic/collection.html#mps_chain_create" title="mps_chain_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_chain_create()</span></tt></a>. Each of these structures
contains two values, the <em>capacity</em> of the generation in
<a class="reference internal" href="../glossary/k.html#term-kilobyte"><em class="xref std std-term">kilobytes</em></a>, and the <em>mortality</em>, the proportion of
objects in the generation that you expect to survive a collection of
that generation.</p>
<p>These numbers are <em>hints</em> to the MPS that it may use to make decisions
about when and what to collect: nothing will go wrong (other than
suboptimal performance) if you make poor choices. Making good choices
for the capacity and mortality of each generation is not easy, and is postponed to the chapter <a class="reference internal" href="perf.html#guide-perf"><em>Tuning the Memory Pool System for performance</em></a>.</p>
<p>Here&#8217;s the code for creating the generation chain for the toy Scheme
interpreter:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_gen_param_s</span> <span class="n">obj_gen_params</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
<span class="p">{</span> <span class="mi">150</span><span class="p">,</span> <span class="mf">0.85</span> <span class="p">},</span>
<span class="p">{</span> <span class="mi">170</span><span class="p">,</span> <span class="mf">0.45</span> <span class="p">},</span>
<span class="p">};</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_chain_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj_chain</span><span class="p">,</span>
<span class="n">arena</span><span class="p">,</span>
<span class="n">LENGTH</span><span class="p">(</span><span class="n">obj_gen_params</span><span class="p">),</span>
<span class="n">obj_gen_params</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t create obj chain&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>Note that these numbers have have been deliberately chosen to be
small, so that the MPS is forced to collect often, so that you can see
it working. Don&#8217;t just copy these numbers unless you also want to see
frequent garbage collections!</p>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/collection.html#topic-collection"><em>Garbage collection</em></a>.</p>
</div>
</div>
<div class="section" id="creating-the-pool">
<span id="index-11"></span><h2>3.6. Creating the pool<a class="headerlink" href="#creating-the-pool" title="Permalink to this headline"></a></h2>
<p>Now you know enough to create an <a class="reference internal" href="../pool/amc.html#pool-amc"><em>AMC (Automatic Mostly-Copying)</em></a> pool! Let&#8217;s review
the pool creation code. First, the header for the AMC pool class:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#include &quot;mpscamc.h&quot;</span>
</pre></div>
</div>
<p>Second, the <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">struct</span> <span class="n">mps_fmt_A_s</span> <span class="n">obj_fmt_s</span> <span class="o">=</span> <span class="p">{</span>
<span class="k">sizeof</span><span class="p">(</span><span class="n">mps_word_t</span><span class="p">),</span>
<span class="n">obj_scan</span><span class="p">,</span>
<span class="n">obj_skip</span><span class="p">,</span>
<span class="nb">NULL</span><span class="p">,</span>
<span class="n">obj_fwd</span><span class="p">,</span>
<span class="n">obj_isfwd</span><span class="p">,</span>
<span class="n">obj_pad</span><span class="p">,</span>
<span class="p">};</span>
<span class="n">mps_fmt_t</span> <span class="n">obj_fmt</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_fmt_create_A</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj_fmt</span><span class="p">,</span> <span class="n">arena</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj_fmt_s</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t create obj format&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>Third, the <a class="reference internal" href="../glossary/g.html#term-generation-chain"><em class="xref std std-term">generation chain</em></a>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_gen_param_s</span> <span class="n">obj_gen_params</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
<span class="p">{</span> <span class="mi">150</span><span class="p">,</span> <span class="mf">0.85</span> <span class="p">},</span>
<span class="p">{</span> <span class="mi">170</span><span class="p">,</span> <span class="mf">0.45</span> <span class="p">},</span>
<span class="p">};</span>
<span class="n">mps_chain_t</span> <span class="n">obj_chain</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_chain_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj_chain</span><span class="p">,</span>
<span class="n">arena</span><span class="p">,</span>
<span class="n">LENGTH</span><span class="p">(</span><span class="n">obj_gen_params</span><span class="p">),</span>
<span class="n">obj_gen_params</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t create obj chain&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>And finally the <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_pool_t</span> <span class="n">obj_pool</span><span class="p">;</span>
<span class="n">MPS_ARGS_BEGIN</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="p">{</span>
<span class="n">MPS_ARGS_ADD</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">MPS_KEY_CHAIN</span><span class="p">,</span> <span class="n">obj_chain</span><span class="p">);</span>
<span class="n">MPS_ARGS_ADD</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">MPS_KEY_FORMAT</span><span class="p">,</span> <span class="n">obj_fmt</span><span class="p">);</span>
<span class="n">MPS_ARGS_DONE</span><span class="p">(</span><span class="n">args</span><span class="p">);</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_pool_create_k</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj_pool</span><span class="p">,</span> <span class="n">arena</span><span class="p">,</span> <span class="n">mps_class_amc</span><span class="p">(),</span> <span class="n">args</span><span class="p">);</span>
<span class="p">}</span> <span class="n">MPS_ARGS_END</span><span class="p">(</span><span class="n">args</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t create obj pool&quot;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="roots">
<span id="guide-lang-root"></span><span id="index-12"></span><h2>3.7. Roots<a class="headerlink" href="#roots" title="Permalink to this headline"></a></h2>
<p>The <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a> tells the MPS how to find <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">references</em></a> from one object to another. This allows the MPS to
extrapolate the reachability property: if object <em>A</em> is
<a class="reference internal" href="../glossary/r.html#term-reachable"><em class="xref std std-term">reachable</em></a>, and the <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a> fixes a reference from
<em>A</em> to another object <em>B</em>, then <em>B</em> is reachable too.</p>
<p>But how does this process get started? How does the MPS know which
objects are reachable <em>a priori</em>? Such objects are known as
<a class="reference internal" href="../glossary/r.html#term-root"><em class="xref std std-term">roots</em></a>, and you must register them with the MPS,
creating root descriptions of type <a class="reference internal" href="../topic/root.html#mps_root_t" title="mps_root_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_root_t</span></tt></a>.</p>
<p>The most important root consists of the contents of the
<a class="reference internal" href="../glossary/r.html#term-register"><em class="xref std std-term">registers</em></a> and the <a class="reference internal" href="../glossary/c.html#term-control-stack"><em class="xref std std-term">control stack</em></a> of each <a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">thread</em></a>
in your program: this is covered in <a class="reference internal" href="#guide-lang-threads"><em>Threads</em></a>, below.</p>
<p>Other roots may be found in static variables in your program, or in
memory allocated by other memory managers. For these roots you must
describe to the MPS how to <a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scan</em></a> them for references.</p>
<p>The toy Scheme interpreter has a number of static variables that point
to heap-allocated objects. First, the special objects, including:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">obj_t</span> <span class="n">obj_empty</span><span class="p">;</span> <span class="cm">/* (), the empty list */</span>
</pre></div>
</div>
<p>Second, the predefined symbols, including:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">obj_t</span> <span class="n">obj_quote</span><span class="p">;</span> <span class="cm">/* &quot;quote&quot; symbol */</span>
</pre></div>
</div>
<p>And third, the global symbol table:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">obj_t</span> <span class="o">*</span><span class="n">symtab</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">size_t</span> <span class="n">symtab_size</span><span class="p">;</span>
</pre></div>
</div>
<p>You tell the MPS how to scan these by writing root scanning functions
of type <a class="reference internal" href="../topic/root.html#mps_reg_scan_t" title="mps_reg_scan_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_reg_scan_t</span></tt></a>. These functions are similar to the
<a class="reference internal" href="#guide-lang-scan"><em>scan method</em></a> in an <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a>,
described above.</p>
<p>In the case of the toy Scheme interpreter, the root scanning function
for the special objects and the predefined symbols could be written
like this:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">mps_res_t</span> <span class="nf">globals_scan</span><span class="p">(</span><span class="n">mps_ss_t</span> <span class="n">ss</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">s</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">MPS_SCAN_BEGIN</span><span class="p">(</span><span class="n">ss</span><span class="p">)</span> <span class="p">{</span>
<span class="n">FIX</span><span class="p">(</span><span class="n">obj_empty</span><span class="p">);</span>
<span class="cm">/* ... and so on for the special objects ... */</span>
<span class="n">FIX</span><span class="p">(</span><span class="n">obj_quote</span><span class="p">);</span>
<span class="cm">/* ... and so on for the predefined symbols ... */</span>
<span class="p">}</span> <span class="n">MPS_SCAN_END</span><span class="p">(</span><span class="n">ss</span><span class="p">);</span>
<span class="k">return</span> <span class="n">MPS_RES_OK</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>but in fact the interpreter already has tables of these global
objects, so it&#8217;s simpler and more extensible for the root scanning
function to iterate over them:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">mps_res_t</span> <span class="nf">globals_scan</span><span class="p">(</span><span class="n">mps_ss_t</span> <span class="n">ss</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">s</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">MPS_SCAN_BEGIN</span><span class="p">(</span><span class="n">ss</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">size_t</span> <span class="n">i</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">LENGTH</span><span class="p">(</span><span class="n">sptab</span><span class="p">);</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="n">FIX</span><span class="p">(</span><span class="o">*</span><span class="n">sptab</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">varp</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">LENGTH</span><span class="p">(</span><span class="n">isymtab</span><span class="p">);</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="n">FIX</span><span class="p">(</span><span class="o">*</span><span class="n">isymtab</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">varp</span><span class="p">);</span>
<span class="p">}</span> <span class="n">MPS_SCAN_END</span><span class="p">(</span><span class="n">ss</span><span class="p">);</span>
<span class="k">return</span> <span class="n">MPS_RES_OK</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Each root scanning function must be registered with the MPS by calling
<a class="reference internal" href="../topic/root.html#mps_root_create" title="mps_root_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_root_create()</span></tt></a>, like this:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_root_t</span> <span class="n">globals_root</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_root_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">globals_root</span><span class="p">,</span> <span class="n">arena</span><span class="p">,</span> <span class="n">mps_rank_exact</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span>
<span class="n">globals_scan</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t register globals root&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>The third argument (here <a class="reference internal" href="../topic/root.html#mps_rank_exact" title="mps_rank_exact"><tt class="xref c c-func docutils literal"><span class="pre">mps_rank_exact()</span></tt></a>) is the <a class="reference internal" href="../glossary/r.html#term-rank"><em class="xref std std-term">rank</em></a>
of references in the root. &#8220;<a class="reference internal" href="../glossary/e.html#term-exact-reference"><em class="xref std std-term">Exact</em></a>&#8221; means
that:</p>
<ol class="arabic simple">
<li>each reference in the root is a genuine pointer to another object
managed by the MPS, or else a null pointer (unlike <a class="reference internal" href="../glossary/a.html#term-ambiguous-reference"><em class="xref std std-term">ambiguous
references</em></a>); and</li>
<li>each reference keeps the target of the reference alive (unlike
<a class="reference internal" href="../glossary/w.html#term-weak-reference-1"><em class="xref std std-term">weak references<sup>(1)</sup></em></a>).</li>
</ol>
<p>The fourth argument is the <a class="reference internal" href="../glossary/r.html#term-root-mode"><em class="xref std std-term">root mode</em></a>, which tells the MPS
whether it is allowed to place a <a class="reference internal" href="../glossary/b.html#term-barrier-1"><em class="xref std std-term">barrier<sup>(1)</sup></em></a> on the root. The
root mode <tt class="docutils literal"><span class="pre">0</span></tt> means that it is not allowed.</p>
<p>The sixth and seventh arguments (here <tt class="docutils literal"><span class="pre">NULL</span></tt> and <tt class="docutils literal"><span class="pre">0</span></tt>) are passed
to the root scanning function where they are received as the
parameters <tt class="docutils literal"><span class="pre">p</span></tt> and <tt class="docutils literal"><span class="pre">s</span></tt> respectively. In this case there was no
need to use them.</p>
<p>What about the global symbol table? This is trickier, because it gets
rehashed from time to time, and during the rehashing process there are
two copies of the symbol table in existence. Because the MPS is
<a class="reference internal" href="../glossary/a.html#term-asynchronous-garbage-collector"><em class="xref std std-term">asynchronous</em></a>, it might be
scanning, moving, or collecting, at any point in time, and if it is
doing so during the rehashing of the symbol table it had better scan
both the old and new copies of the table. This is most conveniently
done by registering a new root to refer to the new copy, and then
after the rehash has completed, de-registering the old root by calling
<a class="reference internal" href="../topic/root.html#mps_root_destroy" title="mps_root_destroy"><tt class="xref c c-func docutils literal"><span class="pre">mps_root_destroy()</span></tt></a>.</p>
<p>It would be possible to write a root scanning function of type
<a class="reference internal" href="../topic/root.html#mps_reg_scan_t" title="mps_reg_scan_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_reg_scan_t</span></tt></a>, as described above, to fix the references in
the global symbol table, but the case of a table of references is
sufficiently common that the MPS provides a convenient (and optimized)
function, <a class="reference internal" href="../topic/root.html#mps_root_create_table" title="mps_root_create_table"><tt class="xref c c-func docutils literal"><span class="pre">mps_root_create_table()</span></tt></a>, for registering it:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">mps_root_t</span> <span class="n">symtab_root</span><span class="p">;</span>
<span class="cm">/* ... */</span>
<span class="n">mps_addr_t</span> <span class="n">ref</span> <span class="o">=</span> <span class="n">symtab</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_root_create_table</span><span class="p">(</span><span class="o">&amp;</span><span class="n">symtab_root</span><span class="p">,</span> <span class="n">arena</span><span class="p">,</span> <span class="n">mps_rank_exact</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span>
<span class="n">ref</span><span class="p">,</span> <span class="n">symtab_size</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t register new symtab root&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p id="guide-lang-roots-rehash">The root must be re-registered whenever the global symbol table
changes size:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">void</span> <span class="nf">rehash</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
<span class="n">obj_t</span> <span class="o">*</span><span class="n">old_symtab</span> <span class="o">=</span> <span class="n">symtab</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="n">old_symtab_size</span> <span class="o">=</span> <span class="n">symtab_size</span><span class="p">;</span>
<span class="n">mps_root_t</span> <span class="n">old_symtab_root</span> <span class="o">=</span> <span class="n">symtab_root</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="n">i</span><span class="p">;</span>
<span class="n">mps_addr_t</span> <span class="n">ref</span><span class="p">;</span>
<span class="n">mps_res_t</span> <span class="n">res</span><span class="p">;</span>
<span class="n">symtab_size</span> <span class="o">*=</span> <span class="mi">2</span><span class="p">;</span>
<span class="n">symtab</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">obj_t</span><span class="p">)</span> <span class="o">*</span> <span class="n">symtab_size</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">symtab</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;out of memory&quot;</span><span class="p">);</span>
<span class="cm">/* Initialize the new table to NULL so that &quot;find&quot; will work. */</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">symtab_size</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="n">symtab</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">ref</span> <span class="o">=</span> <span class="n">symtab</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_root_create_table</span><span class="p">(</span><span class="o">&amp;</span><span class="n">symtab_root</span><span class="p">,</span> <span class="n">arena</span><span class="p">,</span> <span class="n">mps_rank_exact</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span>
<span class="n">ref</span><span class="p">,</span> <span class="n">symtab_size</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t register new symtab root&quot;</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">old_symtab_size</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">old_symtab</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
<span class="n">obj_t</span> <span class="o">*</span><span class="n">where</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">old_symtab</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">symbol</span><span class="p">.</span><span class="n">string</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">where</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">);</span> <span class="cm">/* new table shouldn&#39;t be full */</span>
<span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">where</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">);</span> <span class="cm">/* shouldn&#39;t be in new table */</span>
<span class="o">*</span><span class="n">where</span> <span class="o">=</span> <span class="n">old_symtab</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">mps_root_destroy</span><span class="p">(</span><span class="n">old_symtab_root</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">old_symtab</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition-note admonition">
<p class="first admonition-title">Notes</p>
<ol class="last arabic simple">
<li>The old root description (referring to the old copy of the
symbol table) is not destroyed until after the new root
description has been registered. This is because the MPS is
<a class="reference internal" href="../glossary/a.html#term-asynchronous-garbage-collector"><em class="xref std std-term">asynchronous</em></a>: it might
be scanning, moving, or collecting, at any point in time. If
the old root description were destroyed before the new root
description was registered, there would be a period during
which:<ol class="loweralpha">
<li>the symbol table was not reachable (at least as far as the
MPS was concerned) and so all the objects referenced by it
(and all the objects reachable from <em>those</em> objects) might
be dead; and</li>
<li>if the MPS moved an object, it would not know that the
object was referenced by the symbol table, and so would not
update the reference there to point to the new location of
the object. This would result in out-of-date references in
the old symbol table, and these would be copied into the new
symbol table.</li>
</ol>
</li>
<li>The root might be scanned as soon as it is registered, so it is
important to fill it with scannable references (<tt class="docutils literal"><span class="pre">NULL</span></tt> in
this case) before registering it.</li>
<li>The order of operations at the end is important: the old root
must be de-registered before its memory is freed.</li>
</ol>
</div>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/root.html#topic-root"><em>Roots</em></a>.</p>
</div>
</div>
<div class="section" id="threads">
<span id="guide-lang-threads"></span><span id="index-13"></span><h2>3.8. Threads<a class="headerlink" href="#threads" title="Permalink to this headline"></a></h2>
<p>In a multi-threaded environment where <a class="reference internal" href="../glossary/i.html#term-incremental-garbage-collection"><em class="xref std std-term">incremental garbage
collection</em></a> is used, you must register each of your <a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">threads</em></a>
with the MPS so that the MPS can examine their state.</p>
<p>Even in a single-threaded environment (like the toy Scheme
interpreter) it may also be necessary to register the (only) thread if
either of these conditions apply:</p>
<ol class="arabic simple">
<li>you are using <a class="reference internal" href="../glossary/m.html#term-moving-garbage-collector"><em class="xref std std-term">moving garbage collection</em></a> (as with the <a class="reference internal" href="../pool/amc.html#pool-amc"><em>AMC (Automatic Mostly-Copying)</em></a> pool);</li>
<li>the thread&#8217;s <a class="reference internal" href="../glossary/r.html#term-register"><em class="xref std std-term">registers</em></a> and <a class="reference internal" href="../glossary/c.html#term-control-stack"><em class="xref std std-term">control stack</em></a>
constitute a <a class="reference internal" href="../glossary/r.html#term-root"><em class="xref std std-term">root</em></a> (that is, objects may be kept alive via
references in local variables: this is almost always the case for
programs written in <a class="reference internal" href="../mmref/lang.html#term-c"><em class="xref std std-term">C</em></a>).</li>
</ol>
<p>You register a thread with an <a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arena</em></a> by calling
<a class="reference internal" href="../topic/thread.html#mps_thread_reg" title="mps_thread_reg"><tt class="xref c c-func docutils literal"><span class="pre">mps_thread_reg()</span></tt></a>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_thr_t</span> <span class="kr">thread</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_thread_reg</span><span class="p">(</span><span class="o">&amp;</span><span class="kr">thread</span><span class="p">,</span> <span class="n">arena</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t register thread&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>You register the thread&#8217;s registers and control stack as a root by
calling <a class="reference internal" href="../topic/root.html#mps_root_create_reg" title="mps_root_create_reg"><tt class="xref c c-func docutils literal"><span class="pre">mps_root_create_reg()</span></tt></a> and passing
<a class="reference internal" href="../topic/root.html#mps_stack_scan_ambig" title="mps_stack_scan_ambig"><tt class="xref c c-func docutils literal"><span class="pre">mps_stack_scan_ambig()</span></tt></a>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="kt">void</span> <span class="o">*</span><span class="n">marker</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">marker</span><span class="p">;</span>
<span class="n">mps_root_t</span> <span class="n">reg_root</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_root_create_reg</span><span class="p">(</span><span class="o">&amp;</span><span class="n">reg_root</span><span class="p">,</span>
<span class="n">arena</span><span class="p">,</span>
<span class="n">mps_rank_ambig</span><span class="p">(),</span>
<span class="mi">0</span><span class="p">,</span>
<span class="kr">thread</span><span class="p">,</span>
<span class="n">mps_stack_scan_ambig</span><span class="p">,</span>
<span class="n">marker</span><span class="p">,</span>
<span class="mi">0</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t create root&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>In order to scan the control stack, the MPS needs to know where the
bottom of the stack is, and that&#8217;s the role of the <tt class="docutils literal"><span class="pre">marker</span></tt>
variable: the compiler places it on the stack, so its address is a
position within the stack. As long as you don&#8217;t exit from this
function while the MPS is running, your program&#8217;s active local
variables will always be higher up on the stack than <tt class="docutils literal"><span class="pre">marker</span></tt>, and
so will be scanned for references by the MPS.</p>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/thread.html#topic-thread"><em>Threads</em></a>.</p>
</div>
</div>
<div class="section" id="allocation">
<span id="guide-lang-allocation"></span><span id="index-14"></span><h2>3.9. Allocation<a class="headerlink" href="#allocation" title="Permalink to this headline"></a></h2>
<p>It probably seemed a long journey to get here, but at last we&#8217;re ready
to start allocating.</p>
<p><a class="reference internal" href="../glossary/m.html#term-manual-memory-management"><em class="xref std std-term">Manual</em></a> pools typically support
<a class="reference internal" href="../glossary/m.html#term-malloc"><em class="xref std std-term">malloc</em></a>-like allocation using the function
<a class="reference internal" href="../topic/allocation.html#mps_alloc" title="mps_alloc"><tt class="xref c c-func docutils literal"><span class="pre">mps_alloc()</span></tt></a>. But <a class="reference internal" href="../glossary/a.html#term-automatic-memory-management"><em class="xref std std-term">automatic</em></a> pools cannot, because of the following problem:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">obj_t</span> <span class="nf">make_pair</span><span class="p">(</span><span class="n">obj_t</span> <span class="n">car</span><span class="p">,</span> <span class="n">obj_t</span> <span class="n">cdr</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">obj_t</span> <span class="n">obj</span><span class="p">;</span>
<span class="n">mps_addr_t</span> <span class="n">addr</span><span class="p">;</span>
<span class="n">mps_res_t</span> <span class="n">res</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_alloc</span><span class="p">(</span><span class="o">&amp;</span><span class="n">addr</span><span class="p">,</span> <span class="n">pool</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">pair_s</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;out of memory in make_pair&quot;</span><span class="p">);</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">addr</span><span class="p">;</span>
<span class="cm">/* What happens if the MPS scans obj just now? */</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">pair</span><span class="p">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">TYPE_PAIR</span><span class="p">;</span>
<span class="n">CAR</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">car</span><span class="p">;</span>
<span class="n">CDR</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">cdr</span><span class="p">;</span>
<span class="k">return</span> <span class="n">obj</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Because the MPS is <a class="reference internal" href="../glossary/a.html#term-asynchronous-garbage-collector"><em class="xref std std-term">asynchronous</em></a>, it might scan any reachable object at any time, including
immediately after the object has been allocated. In this case, if the
MPS attempts to scan <tt class="docutils literal"><span class="pre">obj</span></tt> at the indicated point, the object&#8217;s
<tt class="docutils literal"><span class="pre">type</span></tt> field will be uninitialized, and so the <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a>
may abort.</p>
<p>The MPS solves this problem via the fast, nearly lock-free
<a class="reference internal" href="../topic/allocation.html#topic-allocation-point-protocol"><em>Allocation point protocol</em></a>. This needs an additional
structure, an <a class="reference internal" href="../glossary/a.html#term-allocation-point"><em class="xref std std-term">allocation point</em></a>, to be attached to the pool by
calling <a class="reference internal" href="../topic/allocation.html#mps_ap_create_k" title="mps_ap_create_k"><tt class="xref c c-func docutils literal"><span class="pre">mps_ap_create_k()</span></tt></a>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">mps_ap_t</span> <span class="n">obj_ap</span><span class="p">;</span>
<span class="cm">/* ... */</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_ap_create_k</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj_ap</span><span class="p">,</span> <span class="n">obj_pool</span><span class="p">,</span> <span class="n">mps_args_none</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;Couldn&#39;t create obj allocation point&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>And then the constructor can be implemented like this:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">obj_t</span> <span class="nf">make_pair</span><span class="p">(</span><span class="n">obj_t</span> <span class="n">car</span><span class="p">,</span> <span class="n">obj_t</span> <span class="n">cdr</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">obj_t</span> <span class="n">obj</span><span class="p">;</span>
<span class="n">mps_addr_t</span> <span class="n">addr</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">size</span> <span class="o">=</span> <span class="n">ALIGN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">pair_s</span><span class="p">));</span>
<span class="k">do</span> <span class="p">{</span>
<span class="n">mps_res_t</span> <span class="n">res</span> <span class="o">=</span> <span class="n">mps_reserve</span><span class="p">(</span><span class="o">&amp;</span><span class="n">addr</span><span class="p">,</span> <span class="n">obj_ap</span><span class="p">,</span> <span class="n">size</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;out of memory in make_pair&quot;</span><span class="p">);</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">addr</span><span class="p">;</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">pair</span><span class="p">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">TYPE_PAIR</span><span class="p">;</span>
<span class="n">CAR</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">car</span><span class="p">;</span>
<span class="n">CDR</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">cdr</span><span class="p">;</span>
<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">mps_commit</span><span class="p">(</span><span class="n">obj_ap</span><span class="p">,</span> <span class="n">addr</span><span class="p">,</span> <span class="n">size</span><span class="p">));</span>
<span class="k">return</span> <span class="n">obj</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The function <a class="reference internal" href="../topic/allocation.html#mps_reserve" title="mps_reserve"><tt class="xref c c-func docutils literal"><span class="pre">mps_reserve()</span></tt></a> allocates a block of memory that
the MPS knows is uninitialized: the MPS promises not to scan this
block or move it until after it is <a class="reference internal" href="../glossary/c.html#term-committed-2"><em class="xref std std-term">committed<sup>(2)</sup></em></a> by calling
<a class="reference internal" href="../topic/allocation.html#mps_commit" title="mps_commit"><tt class="xref c c-func docutils literal"><span class="pre">mps_commit()</span></tt></a>. So the new object can be initialized safely.</p>
<p>However, there&#8217;s a second problem:</p>
<div class="highlight-c"><div class="highlight"><pre> <span class="n">CAR</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">car</span><span class="p">;</span>
<span class="n">CDR</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="o">=</span> <span class="n">cdr</span><span class="p">;</span>
<span class="cm">/* What if the MPS moves car or cdr just now? */</span>
<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">mps_commit</span><span class="p">(</span><span class="n">obj_ap</span><span class="p">,</span> <span class="n">addr</span><span class="p">,</span> <span class="n">size</span><span class="p">));</span>
</pre></div>
</div>
<p>Because <tt class="docutils literal"><span class="pre">obj</span></tt> is not yet committed, the MPS won&#8217;t scan it, and that
means that it won&#8217;t discover that it contains references to <tt class="docutils literal"><span class="pre">car</span></tt>
and <tt class="docutils literal"><span class="pre">cdr</span></tt>, and so won&#8217;t update these references to point to their
new locations.</p>
<p>In such a circumstance (that is, when objects have moved since you
called <a class="reference internal" href="../topic/allocation.html#mps_reserve" title="mps_reserve"><tt class="xref c c-func docutils literal"><span class="pre">mps_reserve()</span></tt></a>), <a class="reference internal" href="../topic/allocation.html#mps_commit" title="mps_commit"><tt class="xref c c-func docutils literal"><span class="pre">mps_commit()</span></tt></a> returns false, and
we have to initialize the object again (most conveniently done via a
<tt class="docutils literal"><span class="pre">while</span></tt> loop, as here).</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Notes</p>
<ol class="last arabic simple">
<li>When using the <a class="reference internal" href="../topic/allocation.html#topic-allocation-point-protocol"><em>Allocation point protocol</em></a> it is up
to you to ensure that the requested size is aligned, because
<a class="reference internal" href="../topic/allocation.html#mps_reserve" title="mps_reserve"><tt class="xref c c-func docutils literal"><span class="pre">mps_reserve()</span></tt></a> is on the MPS&#8217;s <a class="reference internal" href="../glossary/c.html#term-critical-path"><em class="xref std std-term">critical path</em></a>,
and so it is highly optimized: in nearly all cases it is just
an increment to a pointer and a test.</li>
<li>It is very rare for <a class="reference internal" href="../topic/allocation.html#mps_commit" title="mps_commit"><tt class="xref c c-func docutils literal"><span class="pre">mps_commit()</span></tt></a> to return false, but
in the course of millions of allocations even very rare events
occur, so it is important not to do anything you don&#8217;t want to
repeat between calling <a class="reference internal" href="../topic/allocation.html#mps_reserve" title="mps_reserve"><tt class="xref c c-func docutils literal"><span class="pre">mps_reserve()</span></tt></a> and
<a class="reference internal" href="../topic/allocation.html#mps_commit" title="mps_commit"><tt class="xref c c-func docutils literal"><span class="pre">mps_commit()</span></tt></a>. Also, the shorter the interval, the less
likely <a class="reference internal" href="../topic/allocation.html#mps_commit" title="mps_commit"><tt class="xref c c-func docutils literal"><span class="pre">mps_commit()</span></tt></a> is to return false.</li>
</ol>
</div>
<div class="admonition-topic admonition">
<p class="first admonition-title">Topic</p>
<p class="last"><a class="reference internal" href="../topic/allocation.html#topic-allocation"><em>Allocation</em></a>.</p>
</div>
</div>
<div class="section" id="maintaining-consistency">
<span id="index-15"></span><h2>3.10. Maintaining consistency<a class="headerlink" href="#maintaining-consistency" title="Permalink to this headline"></a></h2>
<p>The MPS is <a class="reference internal" href="../glossary/a.html#term-asynchronous-garbage-collector"><em class="xref std std-term">asynchronous</em></a>:
this means that it might be scanning, moving, or collecting, at any
point in time (potentially, between any pair of instructions in your
program). So you must make sure that your data structures always obey
these rules:</p>
<ol class="arabic">
<li><p class="first">A <a class="reference internal" href="../glossary/r.html#term-root"><em class="xref std std-term">root</em></a> must be scannable by its root scanning function as
soon as it has been registered.</p>
<p>See the discussion of the <a class="reference internal" href="#guide-lang-roots-rehash"><em>global symbol table</em></a> in the toy Scheme interpreter.</p>
</li>
<li><p class="first">A <a class="reference internal" href="../glossary/f.html#term-formatted-object"><em class="xref std std-term">formatted object</em></a> must be scannable by the <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan
method</em></a> as soon as it has been <a class="reference internal" href="../glossary/c.html#term-committed-2"><em class="xref std std-term">committed<sup>(2)</sup></em></a> by calling
<a class="reference internal" href="../topic/allocation.html#mps_commit" title="mps_commit"><tt class="xref c c-func docutils literal"><span class="pre">mps_commit()</span></tt></a>.</p>
<p>See the discussion of the <a class="reference internal" href="#guide-lang-allocation"><em>pair constructor</em></a> in the toy Scheme interpreter.</p>
</li>
<li><p class="first">All objects in automatically managed pools that are
<a class="reference internal" href="../glossary/r.html#term-reachable"><em class="xref std std-term">reachable</em></a> by your code must always be provably reachable
from a root via a chain of <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">references</em></a> that are
<a class="reference internal" href="../glossary/f.html#term-fix"><em class="xref std std-term">fixed</em></a> by a scanning function.</p>
<p>See the discussion of the <a class="reference internal" href="#guide-lang-roots-rehash"><em>global symbol table</em></a> in the toy Scheme interpreter.</p>
</li>
<li><p class="first">Formatted objects must remain scannable throughout their
<a class="reference internal" href="../glossary/l.html#term-lifetime"><em class="xref std std-term">lifetime</em></a>.</p>
</li>
</ol>
<p>Examples of code that breaks these rules, together with tactics for
tracking down the causes, appear in the chapter <a class="reference internal" href="debug.html#guide-debug"><em>Debugging with the Memory Pool System</em></a>.</p>
</div>
<div class="section" id="tidying-up">
<span id="index-16"></span><h2>3.11. Tidying up<a class="headerlink" href="#tidying-up" title="Permalink to this headline"></a></h2>
<p>When your program is done with the MPS, it&#8217;s good practice to tear
down all the MPS data structures. This causes the MPS to check the
consistency of its data structures and report any problems it
detects. It also causes the MPS to flush its <a class="reference internal" href="../glossary/t.html#term-telemetry-stream"><em class="xref std std-term">telemetry stream</em></a>.</p>
<p>MPS data structures must be destroyed or deregistered in the reverse
order to that in which they were registered or created. So you must
destroy all <a class="reference internal" href="../glossary/a.html#term-allocation-point"><em class="xref std std-term">allocation points</em></a> created in a
<a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a> before destroying the pool; destroy all <a class="reference internal" href="../glossary/r.html#term-root"><em class="xref std std-term">roots</em></a> and pools, and deregister all <a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">threads</em></a>, that
were created in an <a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arena</em></a> before destroying the arena, and so
on.</p>
<p>Here&#8217;s the tear-down code from the toy Scheme interpreter:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_ap_destroy</span><span class="p">(</span><span class="n">obj_ap</span><span class="p">);</span>
<span class="n">mps_pool_destroy</span><span class="p">(</span><span class="n">obj_pool</span><span class="p">);</span>
<span class="n">mps_chain_destroy</span><span class="p">(</span><span class="n">obj_chain</span><span class="p">);</span>
<span class="n">mps_fmt_destroy</span><span class="p">(</span><span class="n">obj_fmt</span><span class="p">);</span>
<span class="n">mps_root_destroy</span><span class="p">(</span><span class="n">reg_root</span><span class="p">);</span>
<span class="n">mps_thread_dereg</span><span class="p">(</span><span class="kr">thread</span><span class="p">);</span>
<span class="n">mps_arena_destroy</span><span class="p">(</span><span class="n">arena</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="what-next">
<h2>3.12. What next?<a class="headerlink" href="#what-next" title="Permalink to this headline"></a></h2>
<p>This article has covered the basic knowledge needed to add
incremental, moving, generational garbage collection to the runtime
system for a programming language.</p>
<p>If everything is working for your language, then the next step is
the chapter <a class="reference internal" href="perf.html#guide-perf"><em>Tuning the Memory Pool System for performance</em></a>.</p>
<p>But in the more likely event that things don&#8217;t work out quite as
smoothly for your language as they did in the toy Scheme interpreter,
then you&#8217;ll be more interested in the chapter <a class="reference internal" href="debug.html#guide-debug"><em>Debugging with the Memory Pool System</em></a>.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">3. Garbage collecting a language with the Memory Pool System</a><ul>
<li><a class="reference internal" href="#the-scheme-interpreter">3.1. The Scheme interpreter</a></li>
<li><a class="reference internal" href="#choosing-an-arena-class">3.2. Choosing an arena class</a></li>
<li><a class="reference internal" href="#choosing-a-pool-class">3.3. Choosing a pool class</a></li>
<li><a class="reference internal" href="#describing-your-objects">3.4. Describing your objects</a><ul>
<li><a class="reference internal" href="#the-scan-method">3.4.1. The scan method</a></li>
<li><a class="reference internal" href="#the-skip-method">3.4.2. The skip method</a></li>
<li><a class="reference internal" href="#the-forward-method">3.4.3. The forward method</a></li>
<li><a class="reference internal" href="#the-is-forwarded-method">3.4.4. The is-forwarded method</a></li>
<li><a class="reference internal" href="#the-padding-method">3.4.5. The padding method</a></li>
</ul>
</li>
<li><a class="reference internal" href="#generation-chains">3.5. Generation chains</a></li>
<li><a class="reference internal" href="#creating-the-pool">3.6. Creating the pool</a></li>
<li><a class="reference internal" href="#roots">3.7. Roots</a></li>
<li><a class="reference internal" href="#threads">3.8. Threads</a></li>
<li><a class="reference internal" href="#allocation">3.9. Allocation</a></li>
<li><a class="reference internal" href="#maintaining-consistency">3.10. Maintaining consistency</a></li>
<li><a class="reference internal" href="#tidying-up">3.11. Tidying up</a></li>
<li><a class="reference internal" href="#what-next">3.12. What next?</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="build.html"
title="previous chapter">2. Building the Memory Pool System</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="debug.html"
title="next chapter">4. Debugging with the Memory Pool System</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="debug.html" title="4. Debugging with the Memory Pool System"
>next</a> |</li>
<li class="right" >
<a href="build.html" title="2. Building the Memory Pool System"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Guide</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>