diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-01-27 17:12:12 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-01-27 17:12:12 -0800 |
commit | 50689bff2ed59814a67e74e90a33717552d69df0 (patch) | |
tree | b241a7981c0e1bb5780e0e63832e45b7057c447a | |
parent | 95425355a01edf284a86d0873e63d88071221ed8 (diff) | |
download | mu-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.cc | 1 | ||||
-rw-r--r-- | 038new.cc | 69 | ||||
-rw-r--r-- | sandbox/005-sandbox.mu | 5 | ||||
-rw-r--r-- | sandbox/008-sandbox-test.mu | 4 |
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, [ |