1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-06 03:40:56 -08:00
emacs/mps/manual/html/pool/awl.html
Gareth Rees 2e2b6f7023 Update html.
Copied from Perforce
 Change: 180351
 ServerID: perforce.ravenbrook.com
2012-11-05 22:32:19 +00:00

409 lines
No EOL
36 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. AWL (Automatic Weak Linked) &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Pool reference" href="index.html" />
<link rel="next" title="8. LO (Leaf Object)" href="lo.html" />
<link rel="prev" title="6. AMS (Automatic Mark and Sweep)" href="ams.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="lo.html" title="8. LO (Leaf Object)"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="ams.html" title="6. AMS (Automatic Mark and Sweep)"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Pool reference</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="awl-automatic-weak-linked">
<span id="pool-awl"></span><span id="index-0"></span><h1>7. AWL (Automatic Weak Linked)<a class="headerlink" href="#awl-automatic-weak-linked" title="Permalink to this headline"></a></h1>
<p><strong>AWL</strong> is an <a class="reference internal" href="../glossary/a.html#term-automatic-memory-management"><em class="xref std std-term">automatically managed</em></a> <a class="reference internal" href="../glossary/n.html#term-non-moving-garbage-collector"><em class="xref std std-term">non-moving</em></a>
<a class="reference internal" href="../glossary/p.html#term-pool-class"><em class="xref std std-term">pool class</em></a> that may contain <a class="reference internal" href="../glossary/w.html#term-weak-reference-1"><em class="xref std std-term">weak references<sup>(1)</sup></em></a>.</p>
<p>The purpose of this pool class is to allow the client to implement
<a class="reference internal" href="../glossary/w.html#term-weak-key-hash-table"><em class="xref std std-term">weak-key</em></a>, <a class="reference internal" href="../glossary/w.html#term-weak-value-hash-table"><em class="xref std std-term">weak-value</em></a>, and <a class="reference internal" href="../glossary/d.html#term-doubly-weak-hash-table"><em class="xref std std-term">doubly weak hash tables</em></a>.</p>
<p>In a weak-key hash table, the keys are weakly referenced, so their
presence in the table will not prevent the key object from being
garbage collected. Once the key is no longer <a class="reference internal" href="../glossary/r.html#term-reachable"><em class="xref std std-term">reachable</em></a>, weak
references to it may get <a class="reference internal" href="../glossary/s.html#term-splat"><em class="xref std std-term">splatted</em></a> (that is, replaced
with null pointers). Once that has happened, the client program can&#8217;t
get at the value corresponding to the key any more, so the
implementation is free to splat the value slot as well.</p>
<p>AWL allows the implementation to splat the value slot at the same time
that the weak key slot is splatted. (Or the other way around for
weak-value tables.) See <a class="reference internal" href="#pool-awl-dependent"><em>Dependent objects</em></a>.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">AWL is the only pool in the open source MPS that allows its
formatted objects to contain weak references. It was designed to
support the weak hash tables in <a class="reference external" href="http://opendylan.org/">Open Dylan</a>, and may be awkward to use for other use
cases. If you need more general handling of weak references,
<a class="reference internal" href="../contact.html#contact"><em>contact us</em></a>.</p>
</div>
<div class="section" id="awl-properties">
<span id="index-1"></span><h2>7.1. AWL properties<a class="headerlink" href="#awl-properties" title="Permalink to this headline"></a></h2>
<ul>
<li><p class="first">Does not support allocation via <a class="reference internal" href="../topic/allocation.html#mps_alloc" title="mps_alloc"><tt class="xref c c-func docutils literal"><span class="pre">mps_alloc()</span></tt></a> or deallocation
via <a class="reference internal" href="../topic/allocation.html#mps_free" title="mps_free"><tt class="xref c c-func docutils literal"><span class="pre">mps_free()</span></tt></a>.</p>
</li>
<li><p class="first">Supports allocation via <a class="reference internal" href="../glossary/a.html#term-allocation-point"><em class="xref std std-term">allocation points</em></a>. If an allocation
point is created in an AWL pool, the call to <a class="reference internal" href="../topic/allocation.html#mps_ap_create" title="mps_ap_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_ap_create()</span></tt></a>
takes one additional parameter, a <a class="reference internal" href="../glossary/r.html#term-rank"><em class="xref std std-term">rank</em></a> of type
<a class="reference internal" href="../topic/root.html#mps_rank_t" title="mps_rank_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_rank_t</span></tt></a>. The rank must be either
<a class="reference internal" href="../topic/root.html#mps_rank_exact" title="mps_rank_exact"><tt class="xref c c-func docutils literal"><span class="pre">mps_rank_exact()</span></tt></a> (to allocate ordinary objects containing
<a class="reference internal" href="../glossary/e.html#term-exact-reference"><em class="xref std std-term">exact references</em></a>), or <a class="reference internal" href="../topic/root.html#mps_rank_weak" title="mps_rank_weak"><tt class="xref c c-func docutils literal"><span class="pre">mps_rank_weak()</span></tt></a> (to allocate
objects that contain weak references). For example:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_ap_t</span> <span class="n">ap</span><span class="p">;</span>
<span class="n">mps_res_t</span> <span class="n">res</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_ap_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ap</span><span class="p">,</span> <span class="n">pool</span><span class="p">,</span> <span class="n">mps_rank_weak</span><span class="p">());</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="n">error</span><span class="p">(</span><span class="s">&quot;can&#39;t create allocation point&quot;</span><span class="p">);</span>
</pre></div>
</div>
</li>
<li><p class="first">Supports <a class="reference internal" href="../glossary/a.html#term-allocation-frame"><em class="xref std std-term">allocation frames</em></a> but does not use them to improve
the efficiency of stack-like allocation.</p>
</li>
<li><p class="first">Does not support <a class="reference internal" href="../glossary/s.html#term-segregated-allocation-cache"><em class="xref std std-term">segregated allocation caches</em></a>.</p>
</li>
<li><p class="first">Garbage collections are scheduled automatically. See
<a class="reference internal" href="../topic/collection.html#topic-collection-schedule"><em>Scheduling of collections</em></a>.</p>
</li>
<li><p class="first">Blocks may contain <a class="reference internal" href="../glossary/e.html#term-exact-reference"><em class="xref std std-term">exact references</em></a> or <a class="reference internal" href="../glossary/w.html#term-weak-reference-1"><em class="xref std std-term">weak
references<sup>(1)</sup></em></a> to blocks in the same or other pools (but may not
contain <a class="reference internal" href="../glossary/a.html#term-ambiguous-reference"><em class="xref std std-term">ambiguous references</em></a>, and may not use <a class="reference internal" href="../glossary/r.html#term-remote-reference"><em class="xref std std-term">remote
references</em></a>).</p>
</li>
<li><p class="first">Allocations may be variable in size.</p>
</li>
<li><p class="first">The <a class="reference internal" href="../glossary/a.html#term-alignment"><em class="xref std std-term">alignment</em></a> of blocks is configurable.</p>
</li>
<li><p class="first">Blocks may have <a class="reference internal" href="../glossary/d.html#term-dependent-object"><em class="xref std std-term">dependent objects</em></a>.</p>
</li>
<li><p class="first">Blocks that are not <a class="reference internal" href="../glossary/r.html#term-reachable"><em class="xref std std-term">reachable</em></a> from a <a class="reference internal" href="../glossary/r.html#term-root"><em class="xref std std-term">root</em></a> are
automatically <a class="reference internal" href="../glossary/r.html#term-reclaim"><em class="xref std std-term">reclaimed</em></a>.</p>
</li>
<li><p class="first">Blocks are <a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scanned</em></a>.</p>
</li>
<li><p class="first">Blocks may only be referenced by <a class="reference internal" href="../glossary/b.html#term-base-pointer"><em class="xref std std-term">base pointers</em></a> (unless they
belong to an object format of variant auto-header).</p>
</li>
<li><p class="first">Blocks may be protected by <a class="reference internal" href="../glossary/b.html#term-barrier-1"><em class="xref std std-term">barriers<sup>(1)</sup></em></a>.</p>
</li>
<li><p class="first">Blocks do not <a class="reference internal" href="../glossary/m.html#term-moving-garbage-collector"><em class="xref std std-term">move</em></a>. A consequence
of this is that the pool&#8217;s <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a> need not provide a
<a class="reference internal" href="../glossary/f.html#term-forward-method"><em class="xref std std-term">forward method</em></a>, an <a class="reference internal" href="../glossary/i.html#term-is-forwarded-method"><em class="xref std std-term">is-forwarded method</em></a> or a
<a class="reference internal" href="../glossary/p.html#term-padding-method"><em class="xref std std-term">padding method</em></a>.</p>
</li>
<li><p class="first">Blocks may be registered for <a class="reference internal" href="../glossary/f.html#term-finalization"><em class="xref std std-term">finalization</em></a>.</p>
</li>
<li><p class="first">Blocks must belong to an <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a>.</p>
</li>
</ul>
</div>
<div class="section" id="dependent-objects">
<span id="pool-awl-dependent"></span><span id="index-2"></span><h2>7.2. Dependent objects<a class="headerlink" href="#dependent-objects" title="Permalink to this headline"></a></h2>
<p>In order to support prompt deletion of values in a <a class="reference internal" href="../glossary/w.html#term-weak-key-hash-table"><em class="xref std std-term">weak-key
hash table</em></a> when the key is <a class="reference internal" href="../glossary/s.html#term-splat"><em class="xref std std-term">splatted</em></a> (and prompt
deletion of keys in a <a class="reference internal" href="../glossary/w.html#term-weak-value-hash-table"><em class="xref std std-term">weak-value hash table</em></a>), an AWL pool
allows each object to have a <em class="dfn">dependent object</em>. (This is where
the &#8220;Linked&#8221; in the name of the pool class comes from.)</p>
<p>The dependent object is specified by the <tt class="docutils literal"><span class="pre">find_dependent</span></tt> argument
to <a class="reference internal" href="../topic/pool.html#mps_pool_create" title="mps_pool_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_pool_create()</span></tt></a> when creating an AWL pool. This is a
function of type <a class="reference internal" href="#mps_awl_find_dependent_t" title="mps_awl_find_dependent_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_awl_find_dependent_t</span></tt></a> that takes the
address of an object in the pool and returns the address of its
dependent object (or a null pointer if there is no corresponding
dependent object).</p>
<p>When <a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scanning</em></a> an object in an AWL pool, the MPS ensures
that the dependent object is not protected. This means that the
<a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan method</em></a> in the pool&#8217;s <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a> can read or
write the dependent object.</p>
<p>If an object contains a reference to its dependent object, you should
<a class="reference internal" href="../glossary/f.html#term-fix"><em class="xref std std-term">fix</em></a> that reference, and be aware that if it is a weak
reference then it may be splatted when the dependent object dies.</p>
<p>The way you would normally use this feature in a weak hash table would
be to put the table&#8217;s keys in one object, and its values in another.
(This would be necessary in any case, because the MPS does not support
a mixture of <a class="reference internal" href="../glossary/e.html#term-exact-reference"><em class="xref std std-term">exact references</em></a> and <a class="reference internal" href="../glossary/w.html#term-weak-reference-1"><em class="xref std std-term">weak references<sup>(1)</sup></em></a>
in the same object.) The dependent object for the keys objects is the
values object, and vice versa (if necessary). The scan method looks
out for the splatting of a reference, and when this is detected, it
splats the corresponding reference in the dependent object.</p>
<p>For example:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">obj_t</span> <span class="n">obj_deleted</span><span class="p">;</span> <span class="cm">/* deleted entry in hash table */</span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="n">weak_array_s</span> <span class="p">{</span>
<span class="k">struct</span> <span class="n">weak_array_s</span> <span class="o">*</span><span class="n">dependent</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">length</span><span class="p">;</span> <span class="cm">/* tagged as &quot;length * 2 + 1&quot; */</span>
<span class="n">obj_t</span> <span class="n">slot</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">}</span> <span class="n">weak_array_s</span><span class="p">,</span> <span class="o">*</span><span class="n">weak_array_t</span><span class="p">;</span>
<span class="k">typedef</span> <span class="n">weak_table_s</span> <span class="p">{</span>
<span class="n">type_s</span> <span class="n">type</span><span class="p">;</span> <span class="cm">/* TYPE_WEAK_TABLE */</span>
<span class="n">weak_array_t</span> <span class="n">keys</span><span class="p">,</span> <span class="n">values</span><span class="p">;</span>
<span class="p">}</span> <span class="n">weak_table_s</span><span class="p">,</span> <span class="o">*</span><span class="n">weak_table_t</span><span class="p">;</span>
<span class="n">mps_addr_t</span> <span class="nf">weak_array_find_dependent</span><span class="p">(</span><span class="n">mps_addr_t</span> <span class="n">addr</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">weak_array_t</span> <span class="n">a</span> <span class="o">=</span> <span class="n">addr</span><span class="p">;</span>
<span class="k">return</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">dependent</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">mps_res_t</span> <span class="nf">weak_array_scan</span><span class="p">(</span><span class="n">mps_ss_t</span> <span class="n">ss</span><span class="p">,</span> <span class="n">mps_addr_t</span> <span class="n">base</span><span class="p">,</span> <span class="n">mps_addr_t</span> <span class="n">limit</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">MPS_SCAN_BEGIN</span><span class="p">(</span><span class="n">ss</span><span class="p">)</span> <span class="p">{</span>
<span class="k">while</span> <span class="p">(</span><span class="n">base</span> <span class="o">&lt;</span> <span class="n">limit</span><span class="p">)</span> <span class="p">{</span>
<span class="n">mps_addr_t</span> <span class="n">p</span><span class="p">;</span>
<span class="n">weak_array_t</span> <span class="n">a</span> <span class="o">=</span> <span class="n">base</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">i</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">length</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">;</span> <span class="cm">/* untag */</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">dependent</span><span class="p">;</span>
<span class="n">MPS_FIX12</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">p</span><span class="p">);</span>
<span class="n">a</span><span class="o">-&gt;</span><span class="n">dependent</span> <span class="o">=</span> <span class="n">p</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">length</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">slot</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<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">p</span><span class="p">))</span> <span class="p">{</span>
<span class="n">mps_res_t</span> <span class="n">res</span> <span class="o">=</span> <span class="n">MPS_FIX2</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">p</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span> <span class="k">return</span> <span class="n">res</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">p</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">&amp;&amp;</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">dependent</span><span class="p">)</span> <span class="p">{</span>
<span class="cm">/* key/value was splatted: splat value/key too */</span>
<span class="n">a</span><span class="o">-&gt;</span><span class="n">dependent</span><span class="o">-&gt;</span><span class="n">slot</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj_deleted</span><span class="p">;</span>
<span class="n">a</span><span class="o">-&gt;</span><span class="n">slot</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj_deleted</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">a</span><span class="o">-&gt;</span><span class="n">slot</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">p</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">base</span> <span class="o">+=</span> <span class="n">offsetof</span><span class="p">(</span><span class="n">weak_array_s</span><span class="p">,</span> <span class="n">slot</span><span class="p">)</span> <span class="o">+</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">length</span> <span class="o">*</span> <span class="k">sizeof</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">slot</span><span class="p">[</span><span class="mi">0</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">The <tt class="docutils literal"><span class="pre">length</span></tt> field of the <tt class="docutils literal"><span class="pre">weak_array_s</span></tt> structure contains
the value <tt class="docutils literal"><span class="pre">length</span> <span class="pre">*</span> <span class="pre">2</span> <span class="pre">+</span> <span class="pre">1</span></tt> so that it cannot be mistaken for a
pointer. See <a class="reference internal" href="#pool-awl-caution"><em>Caution</em></a> below.</p>
</div>
</div>
<div class="section" id="protection-faults">
<span id="pool-awl-barrier"></span><span id="index-3"></span><h2>7.3. Protection faults<a class="headerlink" href="#protection-faults" title="Permalink to this headline"></a></h2>
<p>AWL has another special power: it enables better handing of
<a class="reference internal" href="../glossary/p.html#term-protection-fault"><em class="xref std std-term">protection faults</em></a> on <em class="dfn">weak objects</em> (objects containing
<a class="reference internal" href="../glossary/w.html#term-weak-reference-1"><em class="xref std std-term">weak references<sup>(1)</sup></em></a>).</p>
<p>To explain the benefit we first need to describe the problem. The MPS
uses a <a class="reference internal" href="../glossary/r.html#term-read-barrier"><em class="xref std std-term">read barrier</em></a> to perform <a class="reference internal" href="../glossary/i.html#term-incremental-garbage-collection"><em class="xref std std-term">incremental garbage
collection</em></a>. When the client program tries to read an object
containing <a class="reference internal" href="../glossary/w.html#term-weak-reference-1"><em class="xref std std-term">weak references<sup>(1)</sup></em></a>, the MPS may have
<a class="reference internal" href="../glossary/p.html#term-protection"><em class="xref std std-term">protected</em></a> it so that the MPS can process the
object before the client gets to see it.</p>
<p>The problem is that the client program may try to access a weak object
at a point in the <a class="reference internal" href="../glossary/c.html#term-collection-cycle"><em class="xref std std-term">collection cycle</em></a> when the MPS cannot yet
determine the status of the objects that the weak object refers to.
What the MPS does in this situation is assume that all the referenced
objects are going to live. This assumption is correct but
conservative; it may result in objects that are weakly referenced
staying alive for longer than they need to. In the worst case this can
result in a very large amount of memory being used by objects that are
no longer needed.</p>
<p>In order to combat this problem the MPS sometimes does the following:
Instead of processing the entire weak object and unprotecting it, so
that the client program can access the object, the MPS may emulate the
processor instruction. When this happens, the MPS doesn&#8217;t process the
entire weak object; it only processes the exact location that was
being accessed (typically a single word). It emulates the processor
instruction, and it keeps the object protected. This happens invisibly
from the client program&#8217;s perspective: it&#8217;s exactly as if the
instruction executed as normal.</p>
<p>Naturally this emulation business is delicate and involves staring at
the most badly written parts of low-level processor architecture
manuals for days.</p>
<p>Emulation of accesses to protected objects happens when all of the
following are true:</p>
<ol class="arabic simple">
<li>The object is a weak object allocated in an AWL pool.</li>
<li>The MPS is running on Linux/IA-32 or Windows/IA-32. Extending this
list to new (reasonable) operating systems should be tolerable (for
example, OS X/IA-32). Extending this to new processor architectures
requires more work.</li>
<li>The processor instruction that is accessing the object is of a
suitable simple form. The MPS doesn&#8217;t contain an emulator for all
possible instructions that might access memory, so currently it
only recognizes and emulates a simple <tt class="docutils literal"><span class="pre">MOV</span></tt> from memory to a
register or vice-versa.</li>
</ol>
<p><a class="reference internal" href="../contact.html#contact"><em>Contact us</em></a> if you need emulation of access to weak
references for new operating systems, processor architectures, or
memory access instructions.</p>
</div>
<div class="section" id="caution">
<span id="pool-awl-caution"></span><span id="index-4"></span><h2>7.4. Caution<a class="headerlink" href="#caution" title="Permalink to this headline"></a></h2>
<p>Because of the instruction emulation described in
<a class="reference internal" href="#pool-awl-barrier"><em>Protection faults</em></a> above, AWL places the following restriction on
the format of objects allocated in it:</p>
<ul>
<li><p class="first">Each slot in an object must either be a valid word-aligned
reference, or else the bottom bits of the word must be non-zero so
that it does not look like an aligned pointer.</p>
<p>&#8220;Aligned pointer&#8221; means a word whose numeric value (that is, its
value when treated as an unsigned integer) is a multiple of the
architecture&#8217;s <a class="reference internal" href="../glossary/n.html#term-natural-alignment"><em class="xref std std-term">natural alignment</em></a> (see
<a class="reference internal" href="../topic/platform.html#MPS_PF_ALIGN" title="MPS_PF_ALIGN"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_PF_ALIGN</span></tt></a>). If you&#8217;re using a 32-bit architecture,
that means that an aligned pointer is a multiple of 4 and its bottom
two bits are both zero.</p>
<p>The bottom line is that references from an object in an AWL pool
must be untagged and aligned, and integers must be tagged with a
non-zero tag.</p>
</li>
</ul>
<p>Normally one would cope with this restriction by allocating the table
metadata in a pool belonging to another pool class, and only
allocating the arrays of keys and values in an AWL pool. See <a class="reference internal" href="#pool-awl-dependent"><em>the
example</em></a> above.</p>
</div>
<div class="section" id="awl-interface">
<span id="index-5"></span><h2>7.5. AWL interface<a class="headerlink" href="#awl-interface" title="Permalink to this headline"></a></h2>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#include &quot;mpscawl.h&quot;</span>
</pre></div>
</div>
<dl class="function">
<dt id="mps_class_awl">
<a class="reference internal" href="../topic/pool.html#mps_class_t" title="mps_class_t">mps_class_t</a> <tt class="descname">mps_class_awl</tt><big>(</big>void<big>)</big><a class="headerlink" href="#mps_class_awl" title="Permalink to this definition"></a></dt>
<dd><p>Return the <a class="reference internal" href="../glossary/p.html#term-pool-class"><em class="xref std std-term">pool class</em></a> for an AWL (Automatic Weak Linked)
<a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>.</p>
<p>When creating an AWL pool, <a class="reference internal" href="../topic/pool.html#mps_pool_create" title="mps_pool_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_pool_create()</span></tt></a> takes two
extra arguments:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_res_t</span> <span class="n">mps_pool_create</span><span class="p">(</span><span class="n">mps_pool_t</span> <span class="o">*</span><span class="n">pool_o</span><span class="p">,</span> <span class="n">mps_arena_t</span> <span class="n">arena</span><span class="p">,</span>
<span class="n">mps_class_t</span> <span class="n">mps_class_awl</span><span class="p">(),</span>
<span class="n">mps_fmt_t</span> <span class="n">fmt</span><span class="p">,</span>
<span class="n">mps_awl_find_dependent_t</span> <span class="n">find_dependent</span><span class="p">)</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">fmt</span></tt> specifies the <a class="reference internal" href="../glossary/o.html#term-object-format"><em class="xref std std-term">object format</em></a> for the objects
allocated in the pool. The format must provide a <a class="reference internal" href="../glossary/s.html#term-scan-method"><em class="xref std std-term">scan
method</em></a> and a <a class="reference internal" href="../glossary/s.html#term-skip-method"><em class="xref std std-term">skip method</em></a>.</p>
<p><tt class="docutils literal"><span class="pre">find_dependent</span></tt> is a function of type
<a class="reference internal" href="#mps_awl_find_dependent_t" title="mps_awl_find_dependent_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_awl_find_dependent_t</span></tt></a> that specifies how to find the
<a class="reference internal" href="../glossary/d.html#term-dependent-object"><em class="xref std std-term">dependent object</em></a> for an object in the pool.</p>
<p>When creating an allocation point on an AWL pool,
<a class="reference internal" href="../topic/allocation.html#mps_ap_create" title="mps_ap_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_ap_create()</span></tt></a> takes one extra argument:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_res_t</span> <span class="n">mps_ap_create</span><span class="p">(</span><span class="n">mps_ap_t</span> <span class="o">*</span><span class="n">ap_o</span><span class="p">,</span> <span class="n">mps_pool_t</span> <span class="n">pool</span><span class="p">,</span>
<span class="n">mps_rank_t</span> <span class="n">rank</span><span class="p">)</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">rank</span></tt> specifies the <a class="reference internal" href="../glossary/r.html#term-rank"><em class="xref std std-term">rank</em></a> of references in objects
allocated on this allocation point. It must be
<a class="reference internal" href="../topic/root.html#mps_rank_exact" title="mps_rank_exact"><tt class="xref c c-func docutils literal"><span class="pre">mps_rank_exact()</span></tt></a> (if the objects allocated on this
allocation point will contain <a class="reference internal" href="../glossary/e.html#term-exact-reference"><em class="xref std std-term">exact references</em></a>), or
<a class="reference internal" href="../topic/root.html#mps_rank_weak" title="mps_rank_weak"><tt class="xref c c-func docutils literal"><span class="pre">mps_rank_weak()</span></tt></a> (if the objects will contain <a class="reference internal" href="../glossary/w.html#term-weak-reference-1"><em class="xref std std-term">weak
references<sup>(1)</sup></em></a>).</p>
</dd></dl>
<dl class="type">
<dt id="mps_awl_find_dependent_t">
<a class="reference internal" href="../topic/interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a> <tt class="descname">(*mps_awl_find_dependent_t)</tt><big>(</big><a class="reference internal" href="../topic/interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em>&nbsp;addr</em><big>)</big><a class="headerlink" href="#mps_awl_find_dependent_t" title="Permalink to this definition"></a></dt>
<dd><p>The type of functions that find the <a class="reference internal" href="../glossary/d.html#term-dependent-object"><em class="xref std std-term">dependent object</em></a> for
an object in an AWL pool.</p>
<p><tt class="docutils literal"><span class="pre">addr</span></tt> is the address of an object in an AWL pool.</p>
<p>Returns the address of the corresponding dependent object, or a
null pointer if there is none.</p>
<p>The dependent object need not be in memory managed by the MPS, but
if it is, then it must be in a <a class="reference internal" href="../glossary/n.html#term-non-moving-garbage-collector"><em class="xref std std-term">non-moving</em></a> pool in the same arena as <tt class="docutils literal"><span class="pre">addr</span></tt>.</p>
</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. AWL (Automatic Weak Linked)</a><ul>
<li><a class="reference internal" href="#awl-properties">7.1. AWL properties</a></li>
<li><a class="reference internal" href="#dependent-objects">7.2. Dependent objects</a></li>
<li><a class="reference internal" href="#protection-faults">7.3. Protection faults</a></li>
<li><a class="reference internal" href="#caution">7.4. Caution</a></li>
<li><a class="reference internal" href="#awl-interface">7.5. AWL interface</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="ams.html"
title="previous chapter">6. AMS (Automatic Mark and Sweep)</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="lo.html"
title="next chapter">8. LO (Leaf Object)</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="lo.html" title="8. LO (Leaf Object)"
>next</a> |</li>
<li class="right" >
<a href="ams.html" title="6. AMS (Automatic Mark and Sweep)"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Pool reference</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <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>