about summary refs log tree commit diff stats
path: root/053recipe_header.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2017-10-22 23:14:19 -0700
committerKartik K. Agaram <vc@akkartik.com>2017-10-22 23:48:03 -0700
commit514f0e34aa25317e069d9a154fe76826829a8d88 (patch)
tree08dc4112cbac8556e8aaab59ea56181b7178a6fa /053recipe_header.cc
parentf8a6721df2a5080fe3e17c83e46678c1a4f9d006 (diff)
downloadmu-514f0e34aa25317e069d9a154fe76826829a8d88.tar.gz
4089
Clean up how we reclaim local scopes.

It used to work like this (commit 3216):

  1. Update refcounts of products after every instruction, EXCEPT:

      a) when instruction is a non-primitive and the callee starts with
      'local-scope' (because it's already not decremented in 'return')

    OR:

      b) when instruction is primitive 'next-ingredient' or
      'next-ingredient-without-typechecking', and its result is saved to a
      variable in the default space (because it's already incremented at
      the time of the call)

  2. If a function starts with 'local-scope', force it to be reclaimed
  before each return. However, since locals may be returned, *very
  carefully* don't reclaim those. (See the logic in the old `escaping`
  and `should_update_refcount` functions.)

However, this approach had issues. We needed two separate commands for
'local-scope' (reclaim locals on exit) and 'new-default-space'
(programmer takes charge of reclaiming locals). The hard-coded
reclamation duplicated refcounting logic. In addition to adding
complexity, this implementation failed to work if a function overwrites
default-space after setting up a local-scope (the old default-space is
leaked). It also fails in the presence of continuations. Calling a
continuation more than once was guaranteed to corrupt memory (commit
3986).

After this commit, reclaiming local scopes now works like this:

  Update refcounts of products for every PRIMITIVE instruction.
  For non-primitive instructions, all the work happens in the `return`
  instruction:
    increment refcount of ingredients to `return`
      (unless -- one last bit of ugliness -- they aren't saved in the
      caller)
    decrement the refcount of the default-space
      use existing infrastructure for reclaiming as necessary
      if reclaiming default-space, first decrement refcount of each
      local
        again, use existing infrastructure for reclaiming as necessary

This commit (finally!) completes the bulk[1] of step 2 of the plan in
commit 3991. It was very hard until I gave up trying to tweak the
existing implementation and just test-drove layer 43 from scratch.

[1] There's still potential for memory corruption if we abuse
`default-space`. I should probably try to add warnings about that at
some point (todo in layer 45).
Diffstat (limited to '053recipe_header.cc')
-rw-r--r--053recipe_header.cc4
1 files changed, 0 insertions, 4 deletions
diff --git a/053recipe_header.cc b/053recipe_header.cc
index 9e01db42..513cfc4e 100644
--- a/053recipe_header.cc
+++ b/053recipe_header.cc
@@ -640,7 +640,3 @@ void check_recipe_header_constraints(const recipe_ordinal r) {
     raise << "recipe 'main' must return at most a single product, a number\n" << end();
   }
 }
-
-:(before "End Includes")
-using std::min;
-using std::max;