diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-05-03 14:39:38 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-05-03 14:39:38 -0700 |
commit | 191e9bb224cad7c3ea62d986a89a9aa6301c1966 (patch) | |
tree | ebc0d0020617f12442981b098100688ed6766c2b /036refcount.cc | |
parent | 5331af09d0967d7679ecf37e61ec9347460e0f03 (diff) | |
download | mu-191e9bb224cad7c3ea62d986a89a9aa6301c1966.tar.gz |
2897
Diffstat (limited to '036refcount.cc')
-rw-r--r-- | 036refcount.cc | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/036refcount.cc b/036refcount.cc new file mode 100644 index 00000000..a3ea72f9 --- /dev/null +++ b/036refcount.cc @@ -0,0 +1,74 @@ +//: Update refcounts when copying addresses. +//: The top of layer 34 has more on refcounts. + +:(scenario refcounts) +def main [ + 1:address:number <- copy 1000/unsafe + 2:address:number <- copy 1:address:number + 1:address:number <- copy 0 + 2:address:number <- copy 0 +] ++run: {1: ("address" "number")} <- copy {1000: "literal", "unsafe": ()} ++mem: incrementing refcount of 1000: 0 -> 1 ++run: {2: ("address" "number")} <- copy {1: ("address" "number")} ++mem: incrementing refcount of 1000: 1 -> 2 ++run: {1: ("address" "number")} <- copy {0: "literal"} ++mem: decrementing refcount of 1000: 2 -> 1 ++run: {2: ("address" "number")} <- copy {0: "literal"} ++mem: decrementing refcount of 1000: 1 -> 0 + +:(before "End write_memory(reagent x) Special-cases") +if (x.type->value == get(Type_ordinal, "address")) { + // 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); + // decrement refcount of old address + if (old_address) { + int old_refcount = get_or_insert(Memory, old_address); + trace(9999, "mem") << "decrementing refcount of " << old_address << ": " << old_refcount << " -> " << (old_refcount-1) << end(); + 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); + // increment refcount of new address + if (new_address) { + int new_refcount = get_or_insert(Memory, new_address); + assert(new_refcount >= 0); // == 0 only when new_address == old_address + trace(9999, "mem") << "incrementing refcount of " << new_address << ": " << new_refcount << " -> " << (new_refcount+1) << end(); + put(Memory, new_address, new_refcount+1); + } + // End Update Reference Count + return; +} + +:(scenario refcounts_reflexive) +def main [ + 1:address:number <- new number:type + # idempotent copies leave refcount unchanged + 1:address:number <- copy 1:address:number +] ++run: {1: ("address" "number")} <- new {number: "type"} ++mem: incrementing refcount of 1000: 0 -> 1 ++run: {1: ("address" "number")} <- copy {1: ("address" "number")} ++mem: decrementing refcount of 1000: 1 -> 0 ++mem: incrementing refcount of 1000: 0 -> 1 + +:(scenario refcounts_call) +def main [ + 1:address:number <- new number:type + # passing in addresses to recipes increments refcount + foo 1:address:number + # return does NOT yet decrement refcount; memory must be explicitly managed + 1:address:number <- new number:type +] +def foo [ + 2:address:number <- next-ingredient +] ++run: {1: ("address" "number")} <- new {number: "type"} ++mem: incrementing refcount of 1000: 0 -> 1 ++run: {2: ("address" "number")} <- next-ingredient ++mem: incrementing refcount of 1000: 1 -> 2 ++run: {1: ("address" "number")} <- new {number: "type"} ++mem: decrementing refcount of 1000: 2 -> 1 |