about summary refs log tree commit diff stats
path: root/044space.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-07-13 22:43:16 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-07-13 22:50:49 -0700
commit77d5b5d658830bd24724f945e0d6ddf6a06adc0e (patch)
tree94c50c0ddfa6d55dc1189d62243ceeacaf783326 /044space.cc
parent84e4ed1ab58d5b34cf92919aedbb15736a7349d9 (diff)
downloadmu-77d5b5d658830bd24724f945e0d6ddf6a06adc0e.tar.gz
1780 - now we always reclaim local scopes
But still no difference in either memory footprint or in running time.
This will teach me -- for the umpteenth time -- to optimize before
measuring.
Diffstat (limited to '044space.cc')
-rw-r--r--044space.cc61
1 files changed, 53 insertions, 8 deletions
diff --git a/044space.cc b/044space.cc
index aecfd398..4469e47f 100644
--- a/044space.cc
+++ b/044space.cc
@@ -124,14 +124,7 @@ if (s == "number-of-locals") return true;
 //   `default-space:address:array:location <- new location:type, number-of-locals:literal`
 // where N is Name[recipe][""]
 if (curr.name == "new-default-space") {
-  curr.operation = Recipe_ordinal["new"];
-  if (!curr.ingredients.empty())
-    raise << "new-default-space can't take any ingredients\n";
-  curr.ingredients.push_back(reagent("location:type"));
-  curr.ingredients.push_back(reagent("number-of-locals:literal"));
-  if (!curr.products.empty())
-    raise << "new-default-space can't take any results\n";
-  curr.products.push_back(reagent("default-space:address:array:location"));
+  rewrite_default_space_instruction(curr);
 }
 :(after "vector<double> read_memory(reagent x)")
   if (x.name == "number-of-locals") {
@@ -148,6 +141,58 @@ if (curr.name == "new-default-space") {
     return;
   }
 
+//:: a little hook to automatically reclaim the default-space when returning
+//:: from a recipe
+
+:(scenario local_scope)
+recipe main [
+  1:address <- foo
+  2:address <- foo
+  3:boolean <- equal 1:address, 2:address
+]
+recipe foo [
+  local-scope
+  x:number <- copy 34:literal
+  reply default-space:address:array:location
+]
+# both calls to foo should have received the same default-space
++mem: storing 1 in location 3
+
+:(after "Falling Through End Of Recipe")
+try_reclaim_locals();
+:(after "Starting Reply")
+try_reclaim_locals();
+
+//: now 'local-scope' is identical to 'new-default-space' except that we'll
+//: reclaim the default-space when the routine exits
+:(before "End Rewrite Instruction(curr)")
+if (curr.name == "local-scope") {
+  rewrite_default_space_instruction(curr);
+}
+
+:(code)
+void try_reclaim_locals() {
+  // only reclaim routines starting with 'local-scope'
+  const recipe_ordinal r = Recipe_ordinal[current_recipe_name()];
+  const instruction& inst = Recipe[r].steps.at(0);
+  if (inst.name != "local-scope")
+    return;
+//?   cerr << inst.to_string() << '\n'; //? 1
+  abandon(Current_routine->calls.front().default_space,
+          /*array length*/1+/*number-of-locals*/Name[r][""]);
+}
+
+void rewrite_default_space_instruction(instruction& curr) {
+  curr.operation = Recipe_ordinal["new"];
+  if (!curr.ingredients.empty())
+    raise << "new-default-space can't take any ingredients\n";
+  curr.ingredients.push_back(reagent("location:type"));
+  curr.ingredients.push_back(reagent("number-of-locals:literal"));
+  if (!curr.products.empty())
+    raise << "new-default-space can't take any results\n";
+  curr.products.push_back(reagent("default-space:address:array:location"));
+}
+
 //:: helpers
 
 :(code)