mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-26 15:21:51 -08:00
569 lines
No EOL
56 KiB
HTML
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 — 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> »</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>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">“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>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
|
|
“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>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 “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="../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 “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>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’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>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’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-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’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>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> 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>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> 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="#">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&view=status%3dopen&display=Job:Priority:Title&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> »</li>
|
|
<li><a href="index.html" >Reference</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <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> |