mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-30 09:00:31 -08:00
Check in HTML version of the manual (writable on client) so that it will display automatically on the Ravenbrook server and so that we can easily include it in product releases. Copied from Perforce Change: 180338 ServerID: perforce.ravenbrook.com
557 lines
No EOL
56 KiB
HTML
557 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>7. Scanning — 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="8. Threads" href="thread.html" />
|
|
<link rel="prev" title="6. 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="8. Threads"
|
|
accesskey="N">next</a> |</li>
|
|
<li class="right" >
|
|
<a href="format.html" title="6. Object formats"
|
|
accesskey="P">previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" accesskey="U">Reference</a> »</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>7. 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">“fixing”</em></a> them. It’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>7.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>7.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
|
|
“encrypted”), 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> + 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">-></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">-></span><span class="n">ref</span> <span class="o">&</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">&</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">-></span><span class="n">ref</span> <span class="o">&</span> <span class="mh">0x7</span><span class="p">;</span>
|
|
<span class="n">obj</span><span class="o">-></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->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>7.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 “of interest” 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 “of interest”, and what kind of code the compiler has
|
|
generated. There is no substitute for measurement.</p>
|
|
<p>See <a class="reference internal" href="critical.html#topic-critical"><em>The critical path</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 “of interest” 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>7.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’t know if it’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>7.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>7.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’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 “of interest”.</p>
|
|
<div class="admonition warning">
|
|
<p class="first admonition-title">Warning</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’s no substitute for measurement.</p>
|
|
</div>
|
|
<p>Here’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, &_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’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"><</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">-></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">-></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">-></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"><</span> <span class="n">obj</span><span class="o">-></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">-></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">-></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">-></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">"Unexpected object on the heap</span><span class="se">\n</span><span class="s">"</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>7.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> 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> 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’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’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"><</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">&</span><span class="n">obj</span><span class="o">-></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">&</span><span class="n">obj</span><span class="o">-></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">&</span><span class="n">obj</span><span class="o">-></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>7.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> ss</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em> 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 “interesting” 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 “encrypted”, 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> ss</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em> *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> ss</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em> *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 “encrypted”), 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> ss</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em> *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 “stage 1 fix” 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="#">7. Scanning</a><ul>
|
|
<li><a class="reference internal" href="#scanning-protocol">7.1. Scanning protocol</a></li>
|
|
<li><a class="reference internal" href="#tagged-references">7.2. Tagged references</a></li>
|
|
<li><a class="reference internal" href="#critical-path">7.3. Critical path</a></li>
|
|
<li><a class="reference internal" href="#ambiguous-references">7.4. Ambiguous references</a></li>
|
|
<li><a class="reference internal" href="#unfixed-references">7.5. Unfixed references</a></li>
|
|
<li><a class="reference internal" href="#example-scheme-objects">7.6. Example: Scheme objects</a></li>
|
|
<li><a class="reference internal" href="#scanning-interface">7.7. Scanning interface</a></li>
|
|
<li><a class="reference internal" href="#fixing-interface">7.8. Fixing interface</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>Previous topic</h4>
|
|
<p class="topless"><a href="format.html"
|
|
title="previous chapter">6. Object formats</a></p>
|
|
<h4>Next topic</h4>
|
|
<p class="topless"><a href="thread.html"
|
|
title="next chapter">8. Threads</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="8. Threads"
|
|
>next</a> |</li>
|
|
<li class="right" >
|
|
<a href="format.html" title="6. Object formats"
|
|
>previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" >Reference</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <a href="../copyright.html">Copyright</a> 2012, Ravenbrook Limited.
|
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
|
</div>
|
|
</body>
|
|
</html> |