diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-05-03 17:38:33 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-05-03 17:38:33 -0700 |
commit | 6e793202e3dd9a89b88ab291cebbcb788337c592 (patch) | |
tree | 964576ac4bca556076c5fe09c4f0323f6e78f774 /036refcount.cc | |
parent | 191e9bb224cad7c3ea62d986a89a9aa6301c1966 (diff) | |
download | mu-6e793202e3dd9a89b88ab291cebbcb788337c592.tar.gz |
2898 - start filling in missing refcounts
This commit covers instructions 'put', 'put-index' and 'maybe-convert'. Next up are the harder ones: 'copy' and 'merge'. In these cases there's a non-scalar being copied, and we need to figure out which locations within it need to update their refcount.
Diffstat (limited to '036refcount.cc')
-rw-r--r-- | 036refcount.cc | 97 |
1 files changed, 91 insertions, 6 deletions
diff --git a/036refcount.cc b/036refcount.cc index a3ea72f9..939490ac 100644 --- a/036refcount.cc +++ b/036refcount.cc @@ -18,11 +18,17 @@ def main [ +mem: decrementing refcount of 1000: 1 -> 0 :(before "End write_memory(reagent x) Special-cases") -if (x.type->value == get(Type_ordinal, "address")) { +if (is_mu_address(x)) { // compute old address of x, as well as new address we want to write in - int old_address = get_or_insert(Memory, x.value); assert(scalar(data)); - int new_address = data.at(0); + write_memory_updating_refcounts(x, data.at(0)); + return; +} +:(code) +// variant of write_memory for addresses +void write_memory_updating_refcounts(const reagent& canonized_loc, int new_address) { + assert(is_mu_address(canonized_loc)); + int old_address = get_or_insert(Memory, canonized_loc.value); // decrement refcount of old address if (old_address) { int old_refcount = get_or_insert(Memory, old_address); @@ -30,8 +36,13 @@ if (x.type->value == get(Type_ordinal, "address")) { put(Memory, old_address, old_refcount-1); } // perform the write - trace(9999, "mem") << "storing " << no_scientific(data.at(0)) << " in location " << x.value << end(); - put(Memory, x.value, new_address); + trace(9999, "mem") << "storing " << no_scientific(new_address) << " in location " << canonized_loc.value << end(); + if (!canonized_loc.value) { + tb_shutdown(); + DUMP(""); + exit(0); + } + put(Memory, canonized_loc.value, new_address); // increment refcount of new address if (new_address) { int new_refcount = get_or_insert(Memory, new_address); @@ -40,7 +51,6 @@ if (x.type->value == get(Type_ordinal, "address")) { put(Memory, new_address, new_refcount+1); } // End Update Reference Count - return; } :(scenario refcounts_reflexive) @@ -72,3 +82,78 @@ def foo [ +mem: incrementing refcount of 1000: 1 -> 2 +run: {1: ("address" "number")} <- new {number: "type"} +mem: decrementing refcount of 1000: 2 -> 1 + +//: fix up any instructions that don't follow the usual flow of read_memory +//: before the RUN switch, and write_memory after + +:(scenario refcounts_put) +container foo [ + x:address:number +] +def main [ + 1:address:number <- new number:type + 2:address:foo <- new foo:type + *2:address:foo <- put *2:address:foo, x:offset, 1:address:number +] ++run: {1: ("address" "number")} <- new {number: "type"} ++mem: incrementing refcount of 1000: 0 -> 1 ++run: {2: ("address" "foo")} <- new {foo: "type"} ++mem: incrementing refcount of 1002: 0 -> 1 ++run: {2: ("address" "foo"), "lookup": ()} <- put {2: ("address" "foo"), "lookup": ()}, {x: "offset"}, {1: ("address" "number")} +# put increments refcount ++mem: incrementing refcount of 1000: 1 -> 2 + +:(after "Write Memory in PUT in Run") +reagent element = element_type(base.type, offset); +assert(!has_property(element, "lookup")); +element.value = address; +if (is_mu_address(element)) { + write_memory_updating_refcounts(element, ingredients.at(2).at(0)); + goto finish_instruction; +} + +:(scenario refcounts_put_index) +def main [ + 1:address:number <- new number:type + # fake array because we can't yet create an array of addresses (wait for the + # support for dilated reagents and parsing more complex type trees) + 1003:number/raw <- copy 3 # skip refcount at 1002 + 2:address:array:address:number <- copy 1002/unsafe + *2:address:array:address:number <- put-index *2:address:array:address:number, 0, 1:address:number +] ++run: {1: ("address" "number")} <- new {number: "type"} ++mem: incrementing refcount of 1000: 0 -> 1 ++run: {2: ("address" "array" "address" "number")} <- copy {1002: "literal", "unsafe": ()} ++mem: incrementing refcount of 1002: 0 -> 1 ++run: {2: ("address" "array" "address" "number"), "lookup": ()} <- put-index {2: ("address" "array" "address" "number"), "lookup": ()}, {0: "literal"}, {1: ("address" "number")} +# put-index increments refcount ++mem: incrementing refcount of 1000: 1 -> 2 + +:(after "Write Memory in PUT_INDEX in Run") +if (is_mu_address(element)) { + write_memory_updating_refcounts(element, value.at(0)); + goto finish_instruction; +} + +:(scenario refcounts_maybe_convert) +exclusive-container foo [ + x:number + p:address:number +] +def main [ + 1:address:number <- new number:type + 2:foo <- merge 1/p, 1:address:number + 4:address:number, 5:boolean <- maybe-convert 2:foo, p:variant +] ++run: {1: ("address" "number")} <- new {number: "type"} ++mem: incrementing refcount of 1000: 0 -> 1 ++run: {2: "foo"} <- merge {1: "literal", "p": ()}, {1: ("address" "number")} ++run: {4: ("address" "number")}, {5: "boolean"} <- maybe-convert {2: "foo"}, {p: "variant"} +# maybe-convert increments refcount on success ++mem: incrementing refcount of 1000: 1 -> 2 + +:(after "Write Memory in Successful MAYBE_CONVERT") +if (is_mu_address(product)) { + write_memory_updating_refcounts(product, get_or_insert(Memory, base_address+/*skip tag*/1)); + goto finish_instruction; +} |