1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-26 15:21:51 -08:00
emacs/mps/manual/html/topic/scanning.html
Gareth Rees d7a91d1c37 Updated manual html
Copied from Perforce
 Change: 182127
 ServerID: perforce.ravenbrook.com
2013-05-23 19:46:53 +01:00

569 lines
No EOL
56 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>8. Scanning &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="Reference" href="index.html" />
<link rel="next" title="9. Threads" href="thread.html" />
<link rel="prev" title="7. Object formats" href="format.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="thread.html" title="9. Threads"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="format.html" title="7. Object formats"
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">Reference</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="scanning">
<span id="topic-scanning"></span><span id="index-0"></span><h1>8. Scanning<a class="headerlink" href="#scanning" title="Permalink to this headline"></a></h1>
<p><a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">Scanning</em></a> is the process of identifying the
<a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">references</em></a> in a block of memory and
<a class="reference internal" href="../glossary/f.html#term-fix"><em class="xref std std-term">&#8220;fixing&#8221;</em></a> them. It&#8217;s the process at the heart of the
Memory Pool System, and the most critical of the memory management
functions that have to be implemented by the <a class="reference internal" href="../glossary/c.html#term-client-program"><em class="xref std std-term">client program</em></a>.</p>
<p>Scanning is performed for two tasks: during <a class="reference internal" href="../glossary/t.html#term-trace"><em class="xref std std-term">tracing</em></a>,
blocks are scanned in order to follow references, and so determine
which blocks are <a class="reference internal" href="../glossary/r.html#term-reachable"><em class="xref std std-term">reachable</em></a> and which are not. After objects
have been moved in memory, blocks are scanned in order to identify
references that need to be updated to point to the new locations of
these objects. Both tasks use the same scanning protocol, described
here.</p>
<div class="section" id="scanning-protocol">
<span id="topic-scanning-protocol"></span><span id="index-1"></span><h2>8.1. Scanning protocol<a class="headerlink" href="#scanning-protocol" title="Permalink to this headline"></a></h2>
<p>There are several types of scanning functions (the <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">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>, of type <a class="reference internal" href="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>, and
root scanning functions of various types) but all take a <a class="reference internal" href="../glossary/s.html#term-scan-state"><em class="xref std std-term">scan
state</em></a> argument of type <a class="reference internal" href="#mps_ss_t" title="mps_ss_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_ss_t</span></tt></a>, and a description of a
region to be scanned. They must carry out the following steps:</p>
<ol class="arabic simple">
<li>Call the macro <a class="reference internal" href="#MPS_SCAN_BEGIN" title="MPS_SCAN_BEGIN"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_BEGIN()</span></tt></a> on the scan state.</li>
<li>For each reference in the region:<ol class="arabic">
<li>Call <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a>, passing the scan state and the
reference.</li>
<li>If <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> returns false, the reference is not of
interest to the MPS. Proceed to the next reference in the
region.</li>
<li>If <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> returns true, the reference is of interest
to the MPS. Call <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>, passing the scan state and
a pointer to a location containing the reference.</li>
<li>If <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> returns 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="error.html#MPS_RES_OK" title="MPS_RES_OK"><tt class="xref c c-func docutils literal"><span class="pre">MPS_RES_OK()</span></tt></a>, return this result code from the scanning
function as soon as practicable.</li>
<li>If <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> returns <a class="reference internal" href="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>, it may have
updated the reference. If necessary, make sure that the updated
reference is stored back to the region being scanned.</li>
</ol>
</li>
<li>Call the macro <a class="reference internal" href="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a> on the scan state.</li>
<li>Return <a class="reference internal" href="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>.</li>
</ol>
<p>This description of the protocol simplifies a number of important
details, which are covered in the following sections.</p>
</div>
<div class="section" id="tagged-references">
<span id="topic-scanning-tag"></span><span id="index-2"></span><h2>8.2. Tagged references<a class="headerlink" href="#tagged-references" title="Permalink to this headline"></a></h2>
<p>If your references are <a class="reference internal" href="../glossary/t.html#term-tagged-reference"><em class="xref std std-term">tagged</em></a> (or otherwise
&#8220;encrypted&#8221;), then you must remove the tag (or decrypt them) before
passing them to <a class="reference internal" href="#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="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>.</p>
<p>The reference passed to <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> must be the address of the
base of the block referred to (unless the referent belongs to an
<a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a> of variant auto-header, in which case it must be
a reference to the address just after the header).</p>
<p>However, <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> allows some leeway: if you pass it a
reference to the interior of an allocated block, then
<a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> correctly determines whether a reference to the
block is of interest to the MPS.</p>
<p>This means that if your tag is in the low bits of the reference, you
may not have to remove it before calling <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a>. For
example, if you use three tag bits, then your reference is at most
<em>base</em>&nbsp;+&nbsp;7, and if your objects are at least 8 bytes long, then the
reference is within the object and need not be stripped. So your code
might look like this:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">if</span> <span class="p">(</span><span class="n">MPS_FIX1</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">ref</span><span class="p">))</span> <span class="p">{</span>
<span class="cm">/* strip the tag */</span>
<span class="n">mps_addr_t</span> <span class="n">p</span> <span class="o">=</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">ref</span> <span class="o">&amp;</span> <span class="o">~</span><span class="mh">0x7</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_FIX2</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">p</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="k">return</span> <span class="n">res</span><span class="p">;</span>
<span class="cm">/* restore the tag and update reference */</span>
<span class="n">mps_word_t</span> <span class="n">tag</span> <span class="o">=</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">ref</span> <span class="o">&amp;</span> <span class="mh">0x7</span><span class="p">;</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">ref</span> <span class="o">=</span> <span class="p">(</span><span class="n">obj_t</span><span class="p">)((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">p</span> <span class="o">+</span> <span class="n">tag</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>This saves the cost of stripping the tag in the case that <tt class="docutils literal"><span class="pre">obj-&gt;ref</span></tt>
is not of interest to the MPS.</p>
<p>Similarly, if you use interior pointers, you do not need to convert
them to base pointers before calling <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> (or, indeed,
before calling <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>, if the target of the referent
belongs to an <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a> of variant auto-header).</p>
</div>
<div class="section" id="critical-path">
<span id="index-3"></span><h2>8.3. Critical path<a class="headerlink" href="#critical-path" title="Permalink to this headline"></a></h2>
<p>Scanning is an operation on the critical path of the MPS and so it is
vital that it runs fast. The scanning protocol is designed to ensure
that as much of the scanning code can be run inline in the client
program as possible. In particular, the macro <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> does
not need to call into the MPS.</p>
<p>The purpose of <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> is to provide a fast check as to
whether a reference is &#8220;of interest&#8221; to the MPS. It is legitimate to
call this on any word: it does not even have to be an address. So if
you have a mixture of references and non-references, it might turn out
to be faster to call <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> on each word before you even
determine whether or not the word is a reference.</p>
<p>Whether this is in fact an optimization depends on the proportion of
references to non-references, on how often genuine references turn out
to be &#8220;of interest&#8221;, and what kind of code the compiler has
generated. There is no substitute for measurement.</p>
<p>See <a class="reference internal" href="../design/critical-path.html#design-critical-path"><em>The critical path through the MPS</em></a>.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">In one application with a high proportion of <a class="reference internal" href="../glossary/u.html#term-unboxed"><em class="xref std std-term">unboxed</em></a>
values, it turned out to be fastest to check the tag and reject
non-references before calling <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a>.</p>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">If you passed a word that might not be a reference to
<a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a>, and it returned true, this might be a false
positive. You must be certain that the alleged reference is
genuine as well as &#8220;of interest&#8221; before passing it to
<a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>.</p>
</div>
<p>Another technique that can speed up scanning is to segregate objects
into pools whose object formats contain different scan methods. In
particular, if you can segregate objects that do not contain any
references into <a class="reference internal" href="../glossary/l.html#term-leaf-object"><em class="xref std std-term">leaf object</em></a> pools like <a class="reference internal" href="../pool/amcz.html#pool-amcz"><em>AMCZ (Automatic Mostly-Copying Zero-rank)</em></a>, these
objects do not need to be scanned at all.</p>
</div>
<div class="section" id="ambiguous-references">
<span id="index-4"></span><h2>8.4. Ambiguous references<a class="headerlink" href="#ambiguous-references" title="Permalink to this headline"></a></h2>
<p>If the references in the object being scanned are <a class="reference internal" href="../glossary/a.html#term-ambiguous-reference"><em class="xref std std-term">ambiguous</em></a> then <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> does not update the
reference (because it can&#8217;t know if it&#8217;s a genuine reference). The MPS
handles an ambiguous reference by <a class="reference internal" href="../glossary/p.html#term-pinning"><em class="xref std std-term">pinning</em></a> the block pointed to
so that it cannot move.</p>
<p>You could use this fact to optimize the scan by avoiding the need to
reassemble and store the updated reference after calling
<a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a></p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">The MPS currently has no pools that support ambiguous references,
so this cannot arise for the <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">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>, but <a class="reference internal" href="../glossary/r.html#term-root"><em class="xref std std-term">root</em></a> scanning functions may
encounter this case.</p>
</div>
</div>
<div class="section" id="unfixed-references">
<span id="index-5"></span><h2>8.5. Unfixed references<a class="headerlink" href="#unfixed-references" title="Permalink to this headline"></a></h2>
<p>The MPS does not require you to <a class="reference internal" href="../glossary/f.html#term-fix"><em class="xref std std-term">fix</em></a> all your <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">references</em></a>. But if a reference is not fixed:</p>
<ol class="arabic simple">
<li>it does not keep its target alive (this might be acceptable if you
know that the target is being kept alive for another reason, for
example if it is in a <a class="reference internal" href="../glossary/m.html#term-manual-memory-management"><em class="xref std std-term">manually managed</em></a> pool, or if there is always another reference to the
target that <em>is</em> fixed);</li>
<li>it does not get updated if the target moves (this might be
acceptable if you know that the target cannot move, for example if
it is in a <a class="reference internal" href="../glossary/n.html#term-non-moving-memory-manager"><em class="xref std std-term">non-moving</em></a> pool, or
if it is <a class="reference internal" href="../glossary/p.html#term-pinning"><em class="xref std std-term">pinned</em></a> by an <a class="reference internal" href="../glossary/a.html#term-ambiguous-reference"><em class="xref std std-term">ambiguous
reference</em></a>).</li>
</ol>
<p>These optimizations can be tricky to make correct, and can make the
system fragile (for example, it may break if you start using a
different <a class="reference internal" href="../glossary/p.html#term-pool-class"><em class="xref std std-term">pool class</em></a>), so it usually safest to fix all
references.</p>
</div>
<div class="section" id="example-scheme-objects">
<span id="index-6"></span><h2>8.6. Example: Scheme objects<a class="headerlink" href="#example-scheme-objects" title="Permalink to this headline"></a></h2>
<p>Scanning tends to be a repetitive procedure and so you&#8217;ll find it is
usually helpful to define macros to reduce the size of the source
code. The MPS provides a convenience macro <a class="reference internal" href="#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a> for the
common case of calling <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a> and then immediately calling
<a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> if the reference is &#8220;of interest&#8221;.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">Some compilers generate better code if you use
<a class="reference internal" href="#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a>, and some if you use <a class="reference internal" href="#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="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>. There&#8217;s no substitute for measurement.</p>
</div>
<p>Here&#8217;s the macro <tt class="docutils literal"><span class="pre">FIX</span></tt> defined by the toy Scheme interpreter:</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>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">The comment refers to a temptation to write non-portable code that
presents itself here. <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> takes a pointer to a
location containing the reference (an argument of type
<tt class="docutils literal"><span class="pre">mps_addr_t</span> <span class="pre">*</span></tt>). It is tempting to take the address of the
reference and cast it to this type. The behaviour of such a cast
is not defined by the C standard. See <a class="reference internal" href="interface.html#topic-interface-pun"><em>Type punning</em></a>.</p>
</div>
<p>Here&#8217;s the Scheme scanner:</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">obj</span><span class="o">-&gt;</span><span class="n">type</span><span class="p">.</span><span class="n">type</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">obj</span><span class="o">-&gt;</span><span class="n">pair</span><span class="p">.</span><span class="n">car</span><span class="p">);</span>
<span class="n">FIX</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">cdr</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_VECTOR</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">obj</span><span class="o">-&gt;</span><span class="n">vector</span><span class="p">.</span><span class="n">length</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="n">obj</span><span class="o">-&gt;</span><span class="n">vector</span><span class="p">.</span><span class="n">vector</span><span class="p">[</span><span class="n">i</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="n">offsetof</span><span class="p">(</span><span class="n">vector_s</span><span class="p">,</span> <span class="n">vector</span><span class="p">)</span> <span class="o">+</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">vector</span><span class="p">.</span><span class="n">length</span> <span class="o">*</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">vector</span><span class="p">.</span><span class="n">vector</span><span class="p">[</span><span class="mi">0</span><span class="p">]));</span>
<span class="k">break</span><span class="p">;</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="k">return</span> <span class="n">MPS_RES_FAIL</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>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">This scanner is a simple example intended to make the process
clear to the reader. The scanning code and the object layout are
not at all optimized.</p>
</div>
</div>
<div class="section" id="scanning-interface">
<span id="index-7"></span><h2>8.7. Scanning interface<a class="headerlink" href="#scanning-interface" title="Permalink to this headline"></a></h2>
<dl class="type">
<dt id="mps_ss_t">
<tt class="descname">mps_ss_t</tt><a class="headerlink" href="#mps_ss_t" title="Permalink to this definition"></a></dt>
<dd><p>The type of <a class="reference internal" href="../glossary/s.html#term-scan-state"><em class="xref std std-term">scan states</em></a>.</p>
<p>A scan state represents the state of the current <a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scan</em></a>. The
MPS passes a scan state to the <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a> of an
<a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a> when it needs to <a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scan</em></a> for
<a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">references</em></a> within a region of memory. The scan
method must pass the scan state to <a class="reference internal" href="#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="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a> to delimit a sequence of fix operations,
and to the functions <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a>, <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> and
<a class="reference internal" href="#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a> when fixing a <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">reference</em></a>.</p>
</dd></dl>
<dl class="function">
<dt id="MPS_SCAN_BEGIN">
<tt class="descname">MPS_SCAN_BEGIN</tt><big>(</big><a class="reference internal" href="#mps_ss_t" title="mps_ss_t">mps_ss_t</a><em>&nbsp;ss</em><big>)</big><a class="headerlink" href="#MPS_SCAN_BEGIN" title="Permalink to this definition"></a></dt>
<dd><p>Within a <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a>, set up local information required
by <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a>, <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> and
<a class="reference internal" href="#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a>. The local information persists until
<a class="reference internal" href="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>.</p>
<p><tt class="docutils literal"><span class="pre">ss</span></tt> is the <a class="reference internal" href="../glossary/s.html#term-scan-state"><em class="xref std std-term">scan state</em></a> that was passed to the scan method.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">Between <a class="reference internal" href="#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="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>,
the scan state is in a special state, and must not be passed
to a function. If you really need to do so, for example
because you have an embedded structure shared between two scan
methods, you must wrap the call with <a class="reference internal" href="#MPS_FIX_CALL" title="MPS_FIX_CALL"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX_CALL()</span></tt></a> to
ensure that the scan state is passed correctly.</p>
</div>
</dd></dl>
<dl class="function">
<dt id="MPS_SCAN_END">
<tt class="descname">MPS_SCAN_END</tt><big>(</big><a class="reference internal" href="#mps_ss_t" title="mps_ss_t">mps_ss_t</a><em>&nbsp;ss</em><big>)</big><a class="headerlink" href="#MPS_SCAN_END" title="Permalink to this definition"></a></dt>
<dd><p>Within a <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a>, terminate a block started by
<a class="reference internal" href="#MPS_SCAN_BEGIN" title="MPS_SCAN_BEGIN"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_BEGIN()</span></tt></a>.</p>
<p><tt class="docutils literal"><span class="pre">ss</span></tt> is the <a class="reference internal" href="../glossary/s.html#term-scan-state"><em class="xref std std-term">scan state</em></a> that was passed to the scan
method.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last"><a class="reference internal" href="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a> ensures that the scan is completed, so
successful termination of a scan must invoke it. However, in
case of an error it is allowed to return from the scan
method without invoking <a class="reference internal" href="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>.</p>
</div>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">Between <a class="reference internal" href="#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="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>, the
scan state is in a special state, and must not be passed to a
function. If you really need to do so, for example because you
have an embedded structure shared between two scan methods, you
must wrap the call with <a class="reference internal" href="#MPS_FIX_CALL" title="MPS_FIX_CALL"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX_CALL()</span></tt></a> to ensure that the
scan state is passed correctly.</p>
</div>
</dd></dl>
<dl class="function">
<dt id="MPS_FIX_CALL">
<tt class="descname">MPS_FIX_CALL</tt><big>(</big>ss, call<big>)</big><a class="headerlink" href="#MPS_FIX_CALL" title="Permalink to this definition"></a></dt>
<dd><p>Call a function from within a <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a>, between
<a class="reference internal" href="#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="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>, passing
the <a class="reference internal" href="../glossary/s.html#term-scan-state"><em class="xref std std-term">scan state</em></a> correctly.</p>
<p><tt class="docutils literal"><span class="pre">ss</span></tt> is the scan state that was passed to the scan method.</p>
<p><tt class="docutils literal"><span class="pre">call</span></tt> is an expression containing a function call where <tt class="docutils literal"><span class="pre">ss</span></tt>
is one of the arguments.</p>
<p>Returns the result of evaluating the expression <tt class="docutils literal"><span class="pre">call</span></tt>.</p>
<p>Between <a class="reference internal" href="#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="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>, the
scan state is in a special state, and must not be passed to a
function. If you really need to do so, for example because you
have a structure shared between two <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object formats</em></a>, you
must wrap the call with <a class="reference internal" href="#MPS_FIX_CALL" title="MPS_FIX_CALL"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX_CALL()</span></tt></a> to ensure that the
scan state is passed correctly.</p>
<p>In example below, the scan method <tt class="docutils literal"><span class="pre">obj_scan</span></tt> fixes the object&#8217;s
<tt class="docutils literal"><span class="pre">left</span></tt> and <tt class="docutils literal"><span class="pre">right</span></tt> references, but delegates the scanning of
references inside the object&#8217;s <tt class="docutils literal"><span class="pre">data</span></tt> member to the function
<tt class="docutils literal"><span class="pre">data_scan</span></tt>. In order to ensure that the scan state is passed
correctly to <tt class="docutils literal"><span class="pre">data_scan</span></tt>, the call must be wrapped in
<a class="reference internal" href="#MPS_FIX_CALL" title="MPS_FIX_CALL"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX_CALL()</span></tt></a>.</p>
<div class="highlight-c"><div class="highlight"><pre><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">obj_t</span> <span class="n">obj</span><span class="p">;</span>
<span class="n">mps_res_t</span> <span class="n">res</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">for</span> <span class="p">(</span><span class="n">obj</span> <span class="o">=</span> <span class="n">base</span><span class="p">;</span> <span class="n">obj</span> <span class="o">&lt;</span> <span class="n">limit</span><span class="p">;</span> <span class="n">obj</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">MPS_FIX12</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">)</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span>
<span class="k">return</span> <span class="n">res</span><span class="p">;</span>
<span class="n">MPS_FIX_CALL</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="n">res</span> <span class="o">=</span> <span class="n">data_scan</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">data</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="k">return</span> <span class="n">res</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">MPS_FIX12</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">)</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span>
<span class="k">return</span> <span class="n">res</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>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Use of <a class="reference internal" href="#MPS_FIX_CALL" title="MPS_FIX_CALL"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX_CALL()</span></tt></a> is best avoided, as it forces
values out of registers. The gains in simplicity of the code
need to be measured against the loss in performance.</p>
</div>
</dd></dl>
</div>
<div class="section" id="fixing-interface">
<span id="index-8"></span><h2>8.8. Fixing interface<a class="headerlink" href="#fixing-interface" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="MPS_FIX1">
<a class="reference internal" href="interface.html#mps_bool_t" title="mps_bool_t">mps_bool_t</a> <tt class="descname">MPS_FIX1</tt><big>(</big><a class="reference internal" href="#mps_ss_t" title="mps_ss_t">mps_ss_t</a><em>&nbsp;ss</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em>&nbsp;ref</em><big>)</big><a class="headerlink" href="#MPS_FIX1" title="Permalink to this definition"></a></dt>
<dd><p>Determine whether a <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">reference</em></a> needs to be passed to
<a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>.</p>
<p><tt class="docutils literal"><span class="pre">ss</span></tt> is the <a class="reference internal" href="../glossary/s.html#term-scan-state"><em class="xref std std-term">scan state</em></a> that was passed to the
<a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a>.</p>
<p><tt class="docutils literal"><span class="pre">ref</span></tt> is the reference.</p>
<p>Returns a truth value (<a class="reference internal" href="interface.html#mps_bool_t" title="mps_bool_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_bool_t</span></tt></a>) indicating whether
<tt class="docutils literal"><span class="pre">ref</span></tt> is &#8220;interesting&#8221; to the MPS. If it returns true, the scan
method must invoke <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> to <a class="reference internal" href="../glossary/f.html#term-fix"><em class="xref std std-term">fix</em></a> <tt class="docutils literal"><span class="pre">ref</span></tt>.</p>
<p>This macro must only be used within a <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a>, between
<a class="reference internal" href="#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="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">If your reference is <a class="reference internal" href="../glossary/t.html#term-tagged-reference"><em class="xref std std-term">tagged</em></a> or
otherwise &#8220;encrypted&#8221;, you must ensure that it points to a
location within the target block before calling
<a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a>. (Therefore, a small tag in the low bits
need not be stripped.)</p>
</div>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">In the case where the scan method does not need to do anything
between <a class="reference internal" href="#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="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>, you can use
the convenience macro <a class="reference internal" href="#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a>.</p>
</div>
</dd></dl>
<dl class="function">
<dt id="MPS_FIX12">
<a class="reference internal" href="error.html#mps_res_t" title="mps_res_t">mps_res_t</a> <tt class="descname">MPS_FIX12</tt><big>(</big><a class="reference internal" href="#mps_ss_t" title="mps_ss_t">mps_ss_t</a><em>&nbsp;ss</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em>&nbsp;*ref_io</em><big>)</big><a class="headerlink" href="#MPS_FIX12" title="Permalink to this definition"></a></dt>
<dd><p><a class="reference internal" href="../glossary/f.html#term-fix"><em class="xref std std-term">Fix</em></a> a <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">reference</em></a>.</p>
<p>This macro is a convenience for the case where <a class="reference internal" href="#MPS_FIX1" title="MPS_FIX1"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX1()</span></tt></a>
is immediately followed by <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>. The interface is
the same as <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>.</p>
</dd></dl>
<dl class="function">
<dt id="MPS_FIX2">
<a class="reference internal" href="error.html#mps_res_t" title="mps_res_t">mps_res_t</a> <tt class="descname">MPS_FIX2</tt><big>(</big><a class="reference internal" href="#mps_ss_t" title="mps_ss_t">mps_ss_t</a><em>&nbsp;ss</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em>&nbsp;*ref_io</em><big>)</big><a class="headerlink" href="#MPS_FIX2" title="Permalink to this definition"></a></dt>
<dd><p><a class="reference internal" href="../glossary/f.html#term-fix"><em class="xref std std-term">Fix</em></a> a <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">reference</em></a>.</p>
<p><tt class="docutils literal"><span class="pre">ss</span></tt> is the <a class="reference internal" href="../glossary/s.html#term-scan-state"><em class="xref std std-term">scan state</em></a> that was passed to the scan method.</p>
<p><tt class="docutils literal"><span class="pre">ref_io</span></tt> points to the reference.</p>
<p>Returns <a class="reference internal" href="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 successful: in this case the
reference may have been updated, and the scan method must continue
to scan the <a class="reference internal" href="../glossary/b.html#term-block"><em class="xref std std-term">block</em></a>. If it returns any other result, the
<a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a> must return that result as soon as possible,
without fixing any further references.</p>
<p>This macro must only be used within a <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a>, between
<a class="reference internal" href="#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="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p>If your reference is <a class="reference internal" href="../glossary/t.html#term-tagged-reference"><em class="xref std std-term">tagged</em></a> (or
otherwise &#8220;encrypted&#8221;), you must remove the tag (or otherwise
decrypt the reference) before calling <a class="reference internal" href="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>, and
restore the tag to the (possibly updated) reference
afterwards.</p>
<p class="last">The only exception is for references to objects belonging to a
format of variant auto-header (see
<a class="reference internal" href="format.html#mps_fmt_auto_header_s" title="mps_fmt_auto_header_s"><tt class="xref c c-type docutils literal"><span class="pre">mps_fmt_auto_header_s</span></tt></a>): the header size must not be
subtracted from these references.</p>
</div>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">In the case where the scan method does not need to do anything
between <a class="reference internal" href="#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="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>, you can use
the convenience macro <a class="reference internal" href="#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a>.</p>
</div>
</dd></dl>
<dl class="function">
<dt id="mps_fix">
<a class="reference internal" href="error.html#mps_res_t" title="mps_res_t">mps_res_t</a> <tt class="descname">mps_fix</tt><big>(</big><a class="reference internal" href="#mps_ss_t" title="mps_ss_t">mps_ss_t</a><em>&nbsp;ss</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em>&nbsp;*ref_io</em><big>)</big><a class="headerlink" href="#mps_fix" title="Permalink to this definition"></a></dt>
<dd><div class="admonition-deprecated admonition">
<p class="first admonition-title">Deprecated</p>
<p>starting with version 1.111.</p>
<p class="last">Use <a class="reference internal" href="#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="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a> instead.</p>
</div>
<p><a class="reference internal" href="../glossary/f.html#term-fix"><em class="xref std std-term">Fix</em></a> a <a class="reference internal" href="../glossary/r.html#term-reference"><em class="xref std std-term">reference</em></a>.</p>
<p>This is a function equivalent to:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">MPS_SCAN_BEGIN</span><span class="p">(</span><span class="n">ss</span><span class="p">);</span>
<span class="n">MPS_FIX12</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="n">ref_io</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>
</pre></div>
</div>
<p>Because <a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scanning</em></a> 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>, we recommend that you use
<a class="reference internal" href="#MPS_FIX12" title="MPS_FIX12"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX12()</span></tt></a> (or <a class="reference internal" href="#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="#MPS_FIX2" title="MPS_FIX2"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX2()</span></tt></a>)
to ensure that the &#8220;stage 1 fix&#8221; is inlined.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">If you call this between <a class="reference internal" href="#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="#MPS_SCAN_END" title="MPS_SCAN_END"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SCAN_END()</span></tt></a>, you must use <a class="reference internal" href="#MPS_FIX_CALL" title="MPS_FIX_CALL"><tt class="xref c c-func docutils literal"><span class="pre">MPS_FIX_CALL()</span></tt></a> to
ensure that the scan state is passed correctly.</p>
</div>
</dd></dl>
</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="#">8. Scanning</a><ul>
<li><a class="reference internal" href="#scanning-protocol">8.1. Scanning protocol</a></li>
<li><a class="reference internal" href="#tagged-references">8.2. Tagged references</a></li>
<li><a class="reference internal" href="#critical-path">8.3. Critical path</a></li>
<li><a class="reference internal" href="#ambiguous-references">8.4. Ambiguous references</a></li>
<li><a class="reference internal" href="#unfixed-references">8.5. Unfixed references</a></li>
<li><a class="reference internal" href="#example-scheme-objects">8.6. Example: Scheme objects</a></li>
<li><a class="reference internal" href="#scanning-interface">8.7. Scanning interface</a></li>
<li><a class="reference internal" href="#fixing-interface">8.8. Fixing interface</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="format.html"
title="previous chapter">7. Object formats</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="thread.html"
title="next chapter">9. Threads</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="thread.html" title="9. Threads"
>next</a> |</li>
<li class="right" >
<a href="format.html" title="7. Object formats"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Reference</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>