diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-08-17 19:04:35 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-08-17 19:04:35 -0700 |
commit | d990e8f07aee36f68bcd270889d20c2d22b9aa0b (patch) | |
tree | 07a624ea81f2974e1bb038462f4d0607237ea431 /html/036refcount.cc.html | |
parent | cb159b8c8a888f089676a63273b76b641e860d88 (diff) | |
download | mu-d990e8f07aee36f68bcd270889d20c2d22b9aa0b.tar.gz |
3219
Trying keeping html in the master branch: https://github.com/blog/2228-simpler-github-pages-publishing Let's see if https://akkartik.github.io/mu updates after I push this commit to just the master branch.
Diffstat (limited to 'html/036refcount.cc.html')
-rw-r--r-- | html/036refcount.cc.html | 185 |
1 files changed, 122 insertions, 63 deletions
diff --git a/html/036refcount.cc.html b/html/036refcount.cc.html index 05896aad..c1f923ae 100644 --- a/html/036refcount.cc.html +++ b/html/036refcount.cc.html @@ -22,6 +22,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color .Special { color: #c00000; } .Identifier { color: #fcb165; } .Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.Todo { color: #000000; background-color: #ffff00; padding-bottom: 1px; } --> </style> @@ -52,54 +53,65 @@ def main [ <span class="traceContains">+run: {2: ("address" "number")} <- copy {0: "literal"}</span> <span class="traceContains">+mem: decrementing refcount of 1000: 1 -> 0</span> +<span class="Delimiter">:(before "End Globals")</span> +<span class="Comment">//: escape hatch for a later layer</span> +<span class="Normal">bool</span> Update_refcounts_in_write_memory = <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Delimiter">:(before "End write_memory(x) Special-cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>should_update_refcounts_in_write_memory<span class="Delimiter">(</span>product_index<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>Update_refcounts_in_write_memory<span class="Delimiter">)</span> + update_any_refcounts<span class="Delimiter">(</span>x<span class="Delimiter">,</span> data<span class="Delimiter">);</span> + +<span class="Delimiter">:(code)</span> +<span class="Normal">void</span> update_any_refcounts<span class="Delimiter">(</span><span class="Normal">const</span> reagent& canonized_x<span class="Delimiter">,</span> <span class="Normal">const</span> vector<<span class="Normal">double</span>>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span> + increment_any_refcounts<span class="Delimiter">(</span>canonized_x<span class="Delimiter">,</span> data<span class="Delimiter">);</span> <span class="Comment">// increment first so we don't reclaim on x <- copy x</span> + decrement_any_refcounts<span class="Delimiter">(</span>canonized_x<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> increment_any_refcounts<span class="Delimiter">(</span><span class="Normal">const</span> reagent& canonized_x<span class="Delimiter">,</span> <span class="Normal">const</span> vector<<span class="Normal">double</span>>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>canonized_x<span class="Delimiter">))</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>data<span class="Delimiter">));</span> - assert<span class="Delimiter">(</span>x<span class="Delimiter">.</span>value<span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>!x<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">);</span> - update_refcounts<span class="Delimiter">(</span>x<span class="Delimiter">,</span> data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> + assert<span class="Delimiter">(</span>!canonized_x<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">);</span> + increment_refcount<span class="Delimiter">(</span>data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> <span class="Delimiter">}</span> - <span class="Comment">// End Update Refcounts in write_memory(x)</span> + <span class="Comment">// End Increment Refcounts(canonized_x)</span> <span class="Delimiter">}</span> -<span class="Delimiter">:(code)</span> -<span class="Comment">//: hook for a later layer</span> -<span class="Normal">bool</span> should_update_refcounts_in_write_memory<span class="Delimiter">(</span><span class="Normal">int</span> product_index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +<span class="Normal">void</span> increment_refcount<span class="Delimiter">(</span><span class="Normal">int</span> new_address<span class="Delimiter">)</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>new_address >= <span class="Constant">0</span><span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>new_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Normal">int</span> new_refcount = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> new_address<span class="Delimiter">);</span> + trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"incrementing refcount of "</span> << new_address << <span class="Constant">": "</span> << new_refcount << <span class="Constant">" -> "</span> << new_refcount+<span class="Constant">1</span> << end<span class="Delimiter">();</span> + put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> new_address<span class="Delimiter">,</span> new_refcount+<span class="Constant">1</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> update_refcounts<span class="Delimiter">(</span><span class="Normal">const</span> reagent& old<span class="Delimiter">,</span> <span class="Normal">int</span> new_address<span class="Delimiter">)</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>old<span class="Delimiter">));</span> - update_refcounts<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> old<span class="Delimiter">.</span>value<span class="Delimiter">),</span> new_address<span class="Delimiter">,</span> old<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> payload_size<span class="Delimiter">(</span>old<span class="Delimiter">));</span> +<span class="Normal">void</span> decrement_any_refcounts<span class="Delimiter">(</span><span class="Normal">const</span> reagent& canonized_x<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>canonized_x<span class="Delimiter">))</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>canonized_x<span class="Delimiter">.</span>value<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>!canonized_x<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">);</span> + decrement_refcount<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> canonized_x<span class="Delimiter">.</span>value<span class="Delimiter">),</span> canonized_x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> payload_size<span class="Delimiter">(</span>canonized_x<span class="Delimiter">));</span> + <span class="Delimiter">}</span> + <span class="Comment">// End Decrement Refcounts(canonized_x)</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> update_refcounts<span class="Delimiter">(</span><span class="Normal">int</span> old_address<span class="Delimiter">,</span> <span class="Normal">int</span> new_address<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* payload_type<span class="Delimiter">,</span> <span class="Normal">int</span> <span class="Comment">/*</span><span class="Comment">just in case it's an array</span><span class="Comment">*/</span>payload_size<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>old_address == new_address<span class="Delimiter">)</span> <span class="Delimiter">{</span> - trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"copying address to itself; refcount unchanged"</span> << end<span class="Delimiter">();</span> - <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Comment">// decrement refcount of old address</span> +<span class="Normal">void</span> decrement_refcount<span class="Delimiter">(</span><span class="Normal">int</span> old_address<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* payload_type<span class="Delimiter">,</span> <span class="Normal">int</span> payload_size<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>old_address >= <span class="Constant">0</span><span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>old_address<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">int</span> old_refcount = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> old_address<span class="Delimiter">);</span> - trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"decrementing refcount of "</span> << old_address << <span class="Constant">": "</span> << old_refcount << <span class="Constant">" -> "</span> << <span class="Delimiter">(</span>old_refcount-<span class="Constant">1</span><span class="Delimiter">)</span> << end<span class="Delimiter">();</span> + trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"decrementing refcount of "</span> << old_address << <span class="Constant">": "</span> << old_refcount << <span class="Constant">" -> "</span> << old_refcount-<span class="Constant">1</span> << end<span class="Delimiter">();</span> --old_refcount<span class="Delimiter">;</span> put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> old_address<span class="Delimiter">,</span> old_refcount<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>old_refcount < <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> tb_shutdown<span class="Delimiter">();</span> - DUMP<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> - cerr << <span class="Constant">"Negative refcount: "</span> << old_address << <span class="Constant">' '</span> << old_refcount << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + cerr << <span class="Constant">"Negative refcount!!! "</span> << old_address << <span class="Constant">' '</span> << old_refcount << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> + cerr << <span class="Constant">"Saving trace to last_trace.</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + ofstream fout<span class="Delimiter">(</span><span class="Constant">"last_trace"</span><span class="Delimiter">);</span> + fout << Trace_stream<span class="Delimiter">-></span>readable_contents<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> + fout<span class="Delimiter">.</span>close<span class="Delimiter">();</span> + <span class="Delimiter">}</span> exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Comment">// End Decrement Reference Count(old_address, payload_type, payload_size)</span> - <span class="Delimiter">}</span> - <span class="Comment">// increment refcount of new address</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>new_address<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">int</span> new_refcount = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> new_address<span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>new_refcount >= <span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// == 0 only when new_address == old_address</span> - trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"incrementing refcount of "</span> << new_address << <span class="Constant">": "</span> << new_refcount << <span class="Constant">" -> "</span> << <span class="Delimiter">(</span>new_refcount+<span class="Constant">1</span><span class="Delimiter">)</span> << end<span class="Delimiter">();</span> - put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> new_address<span class="Delimiter">,</span> new_refcount+<span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// End Decrement Refcount(old_address, payload_type, payload_size)</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -118,7 +130,8 @@ def main [ <span class="traceContains">+run: {1: ("address" "number")} <- new {number: "type"}</span> <span class="traceContains">+mem: incrementing refcount of 1000: 0 -> 1</span> <span class="traceContains">+run: {1: ("address" "number")} <- copy {1: ("address" "number")}</span> -<span class="traceContains">+mem: copying address to itself; refcount unchanged</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 1 -> 2</span> +<span class="traceContains">+mem: decrementing refcount of 1000: 2 -> 1</span> <span class="Delimiter">:(scenario refcounts_call)</span> def main [ @@ -133,7 +146,9 @@ def foo [ ] <span class="traceContains">+run: {1: ("address" "number")} <- new {number: "type"}</span> <span class="traceContains">+mem: incrementing refcount of 1000: 0 -> 1</span> -<span class="traceContains">+run: {2: ("address" "number")} <- next-ingredient</span> +<span class="traceContains">+run: foo {1: ("address" "number")}</span> +<span class="Comment"># leave ambiguous precisely when the next increment happens; a later layer</span> +<span class="Comment"># will mess with that</span> <span class="traceContains">+mem: incrementing refcount of 1000: 1 -> 2</span> <span class="traceContains">+run: {1: ("address" "number")} <- new {number: "type"}</span> <span class="traceContains">+mem: decrementing refcount of 1000: 2 -> 1</span> @@ -161,10 +176,8 @@ def main [ <span class="Delimiter">:(after "Write Memory in PUT in Run")</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">,</span> offset<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>!has_property<span class="Delimiter">(</span>element<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">));</span> -element<span class="Delimiter">.</span>value = address<span class="Delimiter">;</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>element<span class="Delimiter">))</span> - update_refcounts<span class="Delimiter">(</span>element<span class="Delimiter">,</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> -<span class="Comment">// End Update Refcounts in PUT</span> +element<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>address<span class="Delimiter">);</span> +update_any_refcounts<span class="Delimiter">(</span>element<span class="Delimiter">,</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">));</span> <span class="Delimiter">:(scenario refcounts_put_index)</span> def main [ @@ -181,9 +194,7 @@ def main [ <span class="traceContains">+mem: incrementing refcount of 1000: 1 -> 2</span> <span class="Delimiter">:(after "Write Memory in PUT_INDEX in Run")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>element<span class="Delimiter">))</span> - update_refcounts<span class="Delimiter">(</span>element<span class="Delimiter">,</span> value<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> -<span class="Comment">// End Update Refcounts in PUT_INDEX</span> +update_any_refcounts<span class="Delimiter">(</span>element<span class="Delimiter">,</span> value<span class="Delimiter">);</span> <span class="Delimiter">:(scenario refcounts_maybe_convert)</span> exclusive-container foo [ @@ -205,9 +216,11 @@ def main [ <span class="traceContains">+mem: incrementing refcount of 1000: 2 -> 3</span> <span class="Delimiter">:(after "Write Memory in Successful MAYBE_CONVERT")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>product<span class="Delimiter">))</span> - update_refcounts<span class="Delimiter">(</span>product<span class="Delimiter">,</span> get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address+<span class="Comment">/*</span><span class="Comment">skip tag</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">));</span> -<span class="Comment">// End Update Refcounts in Successful MAYBE_CONVERT</span> +<span class="Comment">// </span><span class="Todo">TODO</span><span class="Comment">: double-check data here as well</span> +vector<<span class="Normal">double</span>> data<span class="Delimiter">;</span> +<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> + data<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address+<span class="Comment">/*</span><span class="Comment">skip tag</span><span class="Comment">*/</span><span class="Constant">1</span>+i<span class="Delimiter">));</span> +update_any_refcounts<span class="Delimiter">(</span>product<span class="Delimiter">,</span> data<span class="Delimiter">);</span> <span class="SalientComment">//:: manage refcounts in instructions that copy multiple locations at a time</span> @@ -403,34 +416,33 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Comment">//: use metadata.address to update refcounts within containers, arrays and</span> <span class="Comment">//: exclusive containers</span> -<span class="Delimiter">:(before "End Update Refcounts in write_memory(x)")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_container<span class="Delimiter">(</span>x<span class="Delimiter">)</span> || is_mu_exclusive_container<span class="Delimiter">(</span>x<span class="Delimiter">))</span> - update_container_refcounts<span class="Delimiter">(</span>x<span class="Delimiter">,</span> data<span class="Delimiter">);</span> -<span class="Delimiter">:(before "End Update Refcounts in PUT")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_container<span class="Delimiter">(</span>element<span class="Delimiter">)</span> || is_mu_exclusive_container<span class="Delimiter">(</span>element<span class="Delimiter">))</span> - update_container_refcounts<span class="Delimiter">(</span>element<span class="Delimiter">,</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">));</span> -<span class="Delimiter">:(before "End Update Refcounts in PUT_INDEX")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_container<span class="Delimiter">(</span>element<span class="Delimiter">)</span> || is_mu_exclusive_container<span class="Delimiter">(</span>element<span class="Delimiter">))</span> - update_container_refcounts<span class="Delimiter">(</span>element<span class="Delimiter">,</span> value<span class="Delimiter">);</span> -<span class="Delimiter">:(before "End Update Refcounts in Successful MAYBE_CONVERT")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_container<span class="Delimiter">(</span>product<span class="Delimiter">)</span> || is_mu_exclusive_container<span class="Delimiter">(</span>product<span class="Delimiter">))</span> <span class="Delimiter">{</span> - vector<<span class="Normal">double</span>> data<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> - data<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address+<span class="Comment">/*</span><span class="Comment">skip tag</span><span class="Comment">*/</span><span class="Constant">1</span>+i<span class="Delimiter">));</span> - update_container_refcounts<span class="Delimiter">(</span>product<span class="Delimiter">,</span> data<span class="Delimiter">);</span> +<span class="Delimiter">:(before "End Increment Refcounts(canonized_x)")</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_container<span class="Delimiter">(</span>canonized_x<span class="Delimiter">)</span> || is_mu_exclusive_container<span class="Delimiter">(</span>canonized_x<span class="Delimiter">))</span> <span class="Delimiter">{</span> + <span class="Normal">const</span> container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> canonized_x<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + <span class="Normal">for</span> <span class="Delimiter">(</span>map<set<tag_condition_info><span class="Delimiter">,</span> set<address_element_info> >::const_iterator p = metadata<span class="Delimiter">.</span>address<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != metadata<span class="Delimiter">.</span>address<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!all_match<span class="Delimiter">(</span>data<span class="Delimiter">,</span> p<span class="Delimiter">-></span>first<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + <span class="Normal">for</span> <span class="Delimiter">(</span>set<address_element_info>::const_iterator info = p<span class="Delimiter">-></span>second<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> info != p<span class="Delimiter">-></span>second<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++info<span class="Delimiter">)</span> + increment_refcount<span class="Delimiter">(</span>data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>info<span class="Delimiter">-></span>offset<span class="Delimiter">));</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Delimiter">:(code)</span> -<span class="Normal">void</span> update_container_refcounts<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">,</span> <span class="Normal">const</span> vector<<span class="Normal">double</span>>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>is_mu_container<span class="Delimiter">(</span>x<span class="Delimiter">)</span> || is_mu_exclusive_container<span class="Delimiter">(</span>x<span class="Delimiter">));</span> - <span class="Normal">const</span> container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> x<span class="Delimiter">.</span>type<span class="Delimiter">);</span> +<span class="Delimiter">:(before "End Decrement Refcounts(canonized_x)")</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_container<span class="Delimiter">(</span>canonized_x<span class="Delimiter">)</span> || is_mu_exclusive_container<span class="Delimiter">(</span>canonized_x<span class="Delimiter">))</span> <span class="Delimiter">{</span> + trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"need to read old value to figure out what refcounts to decrement"</span> << end<span class="Delimiter">();</span> + <span class="Comment">// read from canonized_x but without canonizing again</span> + <span class="Comment">// todo: inline without running canonize all over again</span> + reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> tmp = canonized_x<span class="Delimiter">;</span> + tmp<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span><span class="Constant">"raw"</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">));</span> + vector<<span class="Normal">double</span>> data = read_memory<span class="Delimiter">(</span>tmp<span class="Delimiter">);</span> + <span class="Normal">const</span> container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> canonized_x<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Normal">for</span> <span class="Delimiter">(</span>map<set<tag_condition_info><span class="Delimiter">,</span> set<address_element_info> >::const_iterator p = metadata<span class="Delimiter">.</span>address<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != metadata<span class="Delimiter">.</span>address<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!all_match<span class="Delimiter">(</span>data<span class="Delimiter">,</span> p<span class="Delimiter">-></span>first<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span>set<address_element_info>::const_iterator info = p<span class="Delimiter">-></span>second<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> info != p<span class="Delimiter">-></span>second<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++info<span class="Delimiter">)</span> - update_refcounts<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> x<span class="Delimiter">.</span>value + info<span class="Delimiter">-></span>offset<span class="Delimiter">),</span> data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>info<span class="Delimiter">-></span>offset<span class="Delimiter">),</span> info<span class="Delimiter">-></span>payload_type<span class="Delimiter">,</span> size_of<span class="Delimiter">(</span>info<span class="Delimiter">-></span>payload_type<span class="Delimiter">)</span>+<span class="Comment">/*</span><span class="Comment">refcount</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span> + decrement_refcount<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> canonized_x<span class="Delimiter">.</span>value + info<span class="Delimiter">-></span>offset<span class="Delimiter">),</span> info<span class="Delimiter">-></span>payload_type<span class="Delimiter">,</span> size_of<span class="Delimiter">(</span>info<span class="Delimiter">-></span>payload_type<span class="Delimiter">)</span>+<span class="Comment">/*</span><span class="Comment">refcount</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(code)</span> <span class="Normal">bool</span> all_match<span class="Delimiter">(</span><span class="Normal">const</span> vector<<span class="Normal">double</span>>& data<span class="Delimiter">,</span> <span class="Normal">const</span> set<tag_condition_info>& conditions<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">for</span> <span class="Delimiter">(</span>set<tag_condition_info>::const_iterator p = conditions<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != conditions<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>p<span class="Delimiter">-></span>offset<span class="Delimiter">)</span> != p<span class="Delimiter">-></span>tag<span class="Delimiter">)</span> @@ -460,7 +472,7 @@ def main [ <span class="Comment"># put increments refcount inside container</span> <span class="traceContains">+mem: incrementing refcount of 1000: 2 -> 3</span> -<span class="Delimiter">:(scenario refcounts_put_index_container)</span> +<span class="Delimiter">:(scenario refcounts_put_index_array)</span> container bar [ <span class="Normal">x</span>:address:number ] @@ -617,6 +629,53 @@ def main [ <span class="traceContains">+run: {20: "foo"} <- copy {10: "foo"}</span> <span class="traceContains">+mem: incrementing refcount of 1000: 2 -> 3</span> +<span class="Delimiter">:(scenario refcounts_copy_array_within_container)</span> +container foo [ + <span class="Normal">x</span>:address:array:number +] +def main [ + <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span><span class="Normal">new</span> number:type<span class="Delimiter">,</span> <span class="Constant">3</span> + <span class="Constant">2</span>:foo<span class="Special"> <- </span>merge <span class="Constant">1</span>:address:array:number + <span class="Constant">3</span>:address:array:number<span class="Special"> <- </span><span class="Normal">new</span> number:type<span class="Delimiter">,</span> <span class="Constant">5</span> + <span class="Constant">2</span>:foo<span class="Special"> <- </span>merge <span class="Constant">3</span>:address:array:number +] +<span class="traceContains">+run: {1: ("address" "array" "number")} <- new {number: "type"}, {3: "literal"}</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 0 -> 1</span> +<span class="traceContains">+run: {2: "foo"} <- merge {1: ("address" "array" "number")}</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 1 -> 2</span> +<span class="traceContains">+run: {2: "foo"} <- merge {3: ("address" "array" "number")}</span> +<span class="traceContains">+mem: decrementing refcount of 1000: 2 -> 1</span> + +<span class="Delimiter">:(scenario refcounts_handle_exclusive_containers_with_different_tags)</span> +container foo1 [ + <span class="Normal">x</span>:address:number + <span class="Normal">y</span>:number +] +container foo2 [ + <span class="Normal">x</span>:number + <span class="Normal">y</span>:address:number +] +exclusive-container bar [ + <span class="Normal">a</span>:foo1 + <span class="Normal">b</span>:foo2 +] +def main [ + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">12000</span>/unsafe <span class="Comment"># pretend allocation</span> + *<span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">34</span> + <span class="Constant">2</span>:bar<span class="Special"> <- </span>merge <span class="Constant">0</span>/foo1<span class="Delimiter">,</span> <span class="Constant">1</span>:address:number<span class="Delimiter">,</span> <span class="Constant">97</span> + <span class="Constant">5</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">13000</span>/unsafe <span class="Comment"># pretend allocation</span> + *<span class="Constant">5</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">35</span> + <span class="Constant">6</span>:bar<span class="Special"> <- </span>merge <span class="Constant">1</span>/foo2<span class="Delimiter">,</span> <span class="Constant">98</span><span class="Delimiter">,</span> <span class="Constant">5</span>:address:number + <span class="Constant">2</span>:bar<span class="Special"> <- </span>copy <span class="Constant">6</span>:bar +] +<span class="traceContains">+run: {2: "bar"} <- merge {0: "literal", "foo1": ()}, {1: ("address" "number")}, {97: "literal"}</span> +<span class="traceContains">+mem: incrementing refcount of 12000: 1 -> 2</span> +<span class="traceContains">+run: {6: "bar"} <- merge {1: "literal", "foo2": ()}, {98: "literal"}, {5: ("address" "number")}</span> +<span class="traceContains">+mem: incrementing refcount of 13000: 1 -> 2</span> +<span class="traceContains">+run: {2: "bar"} <- copy {6: "bar"}</span> +<span class="traceContains">+mem: incrementing refcount of 13000: 2 -> 3</span> +<span class="traceContains">+mem: decrementing refcount of 12000: 2 -> 1</span> + <span class="Delimiter">:(code)</span> <span class="Normal">bool</span> is_mu_container<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> is_mu_container<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> |