mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-06 03:40:56 -08:00
409 lines
No EOL
36 KiB
HTML
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) — 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> »</li>
|
|
<li><a href="index.html" accesskey="U">Pool reference</a> »</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’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">&</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">"can't create allocation point"</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’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 “Linked” 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’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’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 "length * 2 + 1" */</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">-></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"><</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">-></span><span class="n">length</span> <span class="o">>></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">-></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">&</span><span class="n">p</span><span class="p">);</span>
|
|
<span class="n">a</span><span class="o">-></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"><</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">-></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">&</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">&&</span> <span class="n">a</span><span class="o">-></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">-></span><span class="n">dependent</span><span class="o">-></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">-></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">-></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">-></span><span class="n">length</span> <span class="o">*</span> <span class="k">sizeof</span> <span class="n">a</span><span class="o">-></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’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’s perspective: it’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’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>“Aligned pointer” means a word whose numeric value (that is, its
|
|
value when treated as an unsigned integer) is a multiple of the
|
|
architecture’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’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 "mpscawl.h"</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> 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> »</li>
|
|
<li><a href="index.html" >Pool reference</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <a href="../copyright.html">Copyright</a> 2012, Ravenbrook Limited.
|
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
|
</div>
|
|
</body>
|
|
</html> |