about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-01-27 17:12:12 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-01-27 17:12:12 -0800
commit50689bff2ed59814a67e74e90a33717552d69df0 (patch)
treeb241a7981c0e1bb5780e0e63832e45b7057c447a
parent95425355a01edf284a86d0873e63d88071221ed8 (diff)
downloadmu-50689bff2ed59814a67e74e90a33717552d69df0.tar.gz
2609 - reuse test-recipe variables in sandbox/ tests
I'd feared that the refcount errors in the previous commit meant there
was a bug in my ref-counting, so I temporarily used new variables rather
than reusing existing ones. But it turns out the one remaining place
memory corruption can happen is when recipes don't use default-scope and
so end up sharing memory. Don't I have a warning for this?
-rw-r--r--020run.cc1
-rw-r--r--038new.cc69
-rw-r--r--sandbox/005-sandbox.mu5
-rw-r--r--sandbox/008-sandbox-test.mu4
4 files changed, 75 insertions, 4 deletions
diff --git a/020run.cc b/020run.cc
index 19c508e8..be3c69c1 100644
--- a/020run.cc
+++ b/020run.cc
@@ -60,6 +60,7 @@ void run_current_routine()
   while (!Current_routine->completed())  // later layers will modify condition
   {
     // Running One Instruction
+//?     trace(9999, "aaaa") << "location 1 contains " << get_or_insert(Memory, 1) << end();
 //?     Instructions_running[current_recipe_name()]++;
     if (current_instruction().is_label) { ++current_step_index(); continue; }
     trace(Initial_callstack_depth + Trace_stream->callstack_depth, "run") << current_instruction().to_string() << end();
diff --git a/038new.cc b/038new.cc
index abc11b8d..1156bb12 100644
--- a/038new.cc
+++ b/038new.cc
@@ -421,6 +421,7 @@ if (x.type->value == get(Type_ordinal, "address")
     put(Memory, old_address, old_refcount-1);
   }
   // perform the write
+//?   trace(9999, "mem") << "038new.cc:424: location " << x.value << " contains " << old_address << " with refcount " << get_or_insert(Memory, old_address) << end();
   trace(9999, "mem") << "storing " << no_scientific(data.at(0)) << " in location " << base << end();
   put(Memory, base, new_address);
   // increment refcount of new address
@@ -432,6 +433,9 @@ if (x.type->value == get(Type_ordinal, "address")
   }
   // abandon old address if necessary
   // do this after all refcount updates are done just in case old and new are identical
+//?   if (get_or_insert(Memory, old_address) < 0) {
+//?     DUMP("");
+//?   }
   assert(get_or_insert(Memory, old_address) >= 0);
   if (old_address && get_or_insert(Memory, old_address) == 0) {
     // lookup_memory without drop_one_lookup {
@@ -441,11 +445,76 @@ if (x.type->value == get(Type_ordinal, "address")
     drop_from_type(x, "address");
     drop_from_type(x, "shared");
     // }
+//?     cerr << "ABANDON\n";
     abandon(old_address, size_of(x)+/*refcount*/1);
   }
   return;
 }
 
+:(scenario refcounts_2)
+recipe main [
+  1:address:shared:number <- new number:type
+  # over-writing one allocation with another
+  1:address:shared:number <- new number:type
+  1:address:shared:number <- copy 0
+]
++run: 1:address:shared:number <- new number:type
++mem: incrementing refcount of 1000: 0 -> 1
++run: 1:address:shared:number <- new number:type
++mem: automatically abandoning 1000
+
+:(scenario refcounts_3)
+recipe main [
+  1:address:shared:number <- new number:type
+  # passing in addresses to recipes increments refcount
+  foo 1:address:shared:number
+  1:address:shared:number <- copy 0
+]
+recipe foo [
+  2:address:shared:number <- next-ingredient
+  # return does NOT yet decrement refcount; memory must be explicitly managed
+  2:address:shared:number <- copy 0
+]
++run: 1:address:shared:number <- new number:type
++mem: incrementing refcount of 1000: 0 -> 1
++run: 2:address:shared:number <- next-ingredient
++mem: incrementing refcount of 1000: 1 -> 2
++run: 2:address:shared:number <- copy 0
++mem: decrementing refcount of 1000: 2 -> 1
++run: 1:address:shared:number <- copy 0
++mem: decrementing refcount of 1000: 1 -> 0
++mem: automatically abandoning 1000
+
+:(scenario refcounts_4)
+recipe main [
+  1:address:shared:number <- new number:type
+  # idempotent copies leave refcount unchanged
+  1:address:shared:number <- copy 1:address:shared:number
+]
++run: 1:address:shared:number <- new number:type
++mem: incrementing refcount of 1000: 0 -> 1
++run: 1:address:shared:number <- copy 1:address:shared:number
++mem: decrementing refcount of 1000: 1 -> 0
++mem: incrementing refcount of 1000: 0 -> 1
+
+:(scenario refcounts_5)
+recipe main [
+  1:address:shared:number <- new number:type
+  # passing in addresses to recipes increments refcount
+  foo 1:address:shared:number
+  # return does NOT yet decrement refcount; memory must be explicitly managed
+  1:address:shared:number <- new number:type
+]
+recipe foo [
+  2:address:shared:number <- next-ingredient
+]
++run: 1:address:shared:number <- new number:type
++mem: incrementing refcount of 1000: 0 -> 1
++run: 2:address:shared:number <- next-ingredient
++mem: incrementing refcount of 1000: 1 -> 2
++run: 1:address:shared:number <- new number:type
++mem: decrementing refcount of 1000: 2 -> 1
+
 //:: Extend 'new' to handle a unicode string literal argument.
 
 :(scenario new_string)
diff --git a/sandbox/005-sandbox.mu b/sandbox/005-sandbox.mu
index 87f688ed..35d53beb 100644
--- a/sandbox/005-sandbox.mu
+++ b/sandbox/005-sandbox.mu
@@ -434,6 +434,7 @@ scenario run-updates-results [
   # define a recipe (no indent for the 'add' line below so column numbers are more obvious)
   1:address:shared:array:character <- new [ 
 recipe foo [
+local-scope
 z:number <- add 2, 2
 reply z
 ]]
@@ -456,7 +457,7 @@ reply z
     .                                                  .
   ]
   # make a change (incrementing one of the args to 'add'), then rerun
-  4:address:shared:array:character <- new [ 
+  1:address:shared:array:character <- new [ 
 recipe foo [
 z:number <- add 2, 3
 reply z
@@ -465,7 +466,7 @@ reply z
     press F4
   ]
   run [
-    event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data, 4:address:shared:array:character/recipes
+    event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data, 1:address:shared:array:character/recipes
   ]
   # check that screen updates the result on the right
   screen-should-contain [
diff --git a/sandbox/008-sandbox-test.mu b/sandbox/008-sandbox-test.mu
index a7344ba4..d08bb890 100644
--- a/sandbox/008-sandbox-test.mu
+++ b/sandbox/008-sandbox-test.mu
@@ -58,7 +58,7 @@ recipe foo [
     .                                                  .
   ]
   # now change the result
-  5:address:shared:array:character <- new [ 
+  1:address:shared:array:character <- new [ 
 recipe foo [
   reply 3
 ]]
@@ -67,7 +67,7 @@ recipe foo [
     press F4
   ]
   run [
-    event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data, 5:address:shared:array:character/new-test-recipes
+    event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data, 1:address:shared:array:character/new-test-recipes
   ]
   # result turns red
   screen-should-contain-in-color 1/red, [