diff options
-rw-r--r-- | 036refcount.cc | 22 | ||||
-rw-r--r-- | 037abandon.cc | 121 | ||||
-rw-r--r-- | 043space.cc | 1 |
3 files changed, 129 insertions, 15 deletions
diff --git a/036refcount.cc b/036refcount.cc index a7da07b8..ad87b089 100644 --- a/036refcount.cc +++ b/036refcount.cc @@ -278,7 +278,7 @@ bool append_addresses(int base_offset, const type_tree* type, vector<address_ele const type_info& info = get(Type, type->value); if (type->name == "address") { assert(type->right && type->right->name != "array"); // array types can't be handled without a full reagent and its value - out.push_back(address_element_info(base_offset, new type_tree(*type))); + out.push_back(address_element_info(base_offset, new type_tree(*type->right))); return true; } if (info.kind == PRIMITIVE) return true; @@ -288,7 +288,7 @@ bool append_addresses(int base_offset, const type_tree* type, vector<address_ele // Compute Container Address Offset(element) if (is_mu_address(element)) { trace(9993, "transform") << "address at offset " << curr_offset << end(); - out.push_back(address_element_info(curr_offset, new type_tree(*element.type))); + out.push_back(address_element_info(curr_offset, new type_tree(*element.type->right))); ++curr_offset; } else if (is_mu_container(element)) { @@ -346,13 +346,13 @@ void update_container_refcounts(const reagent& x, const vector<double>& data) { const container_metadata& metadata = get(Container_metadata, x.type); for (int i = 0; i < SIZE(metadata.address); ++i) { const address_element_info& info = metadata.address.at(i); - update_refcounts(get_or_insert(Memory, x.value + info.offset), data.at(info.offset), info.payload_type, size_of(info.payload_type)); + update_refcounts(get_or_insert(Memory, x.value + info.offset), data.at(info.offset), info.payload_type, size_of(info.payload_type)+/*refcount*/1); } for (map<pair<int, int>, vector<address_element_info> >::const_iterator p = metadata.maybe_address.begin(); p != metadata.maybe_address.end(); ++p) { if (data.at(p->first.first) != p->first.second) continue; for (int i = 0; i < SIZE(p->second); ++i) { const address_element_info& info = p->second.at(i); - update_refcounts(get_or_insert(Memory, x.value + info.offset), data.at(info.offset), info.payload_type, size_of(info.payload_type)); + update_refcounts(get_or_insert(Memory, x.value + info.offset), data.at(info.offset), info.payload_type, size_of(info.payload_type)+/*refcount*/1); } } } @@ -515,13 +515,19 @@ def main [ :(code) bool is_mu_container(const reagent& r) { - if (r.type->value == 0) return false; - type_info& info = get(Type, r.type->value); + return is_mu_container(r.type); +} +bool is_mu_container(const type_tree* type) { + if (type->value == 0) return false; + type_info& info = get(Type, type->value); return info.kind == CONTAINER; } bool is_mu_exclusive_container(const reagent& r) { - if (r.type->value == 0) return false; - type_info& info = get(Type, r.type->value); + return is_mu_exclusive_container(r.type); +} +bool is_mu_exclusive_container(const type_tree* type) { + if (type->value == 0) return false; + type_info& info = get(Type, type->value); return info.kind == EXCLUSIVE_CONTAINER; } diff --git a/037abandon.cc b/037abandon.cc index eb367490..ea26020a 100644 --- a/037abandon.cc +++ b/037abandon.cc @@ -16,7 +16,7 @@ def main [ :(before "End Decrement Reference Count(old_address, payload_type, payload_size)") if (old_refcount == 0) { trace(9999, "mem") << "automatically abandoning " << old_address << end(); - abandon(old_address, payload_size); + abandon(old_address, payload_type, payload_size); } //: When abandoning addresses we'll save them to a 'free list', segregated by size. @@ -25,17 +25,46 @@ if (old_refcount == 0) { map<int, int> free_list; :(code) -void abandon(int address, int size) { - trace(9999, "abandon") << "saving in free-list of size " << size << end(); +void abandon(int address, const type_tree* payload_type, int payload_size) { + trace(9999, "abandon") << "updating refcounts inside " << address << ": " << to_string(payload_type) << end(); //? Total_free += size; //? Num_free++; //? cerr << "abandon: " << size << '\n'; + // decrement any contained refcounts + if (payload_type->name == "array") { + reagent element; + element.type = copy_array_element(payload_type); + int array_length = get_or_insert(Memory, address+/*skip refcount*/1); + assert(element.type->name != "array"); + if (is_mu_address(element)) { + for (element.value = address+/*skip refcount*/1+/*skip length*/1; element.value < address+/*skip refcount*/1+/*skip length*/1+array_length; ++element.value) + update_refcounts(element, 0); + } + else if (is_mu_container(element) || is_mu_exclusive_container(element)) { + int element_size = size_of(element); + vector<double> zeros; + zeros.resize(element_size); + for (int i = 0; i < array_length; ++i) { + element.value = address + /*skip refcount*/1 + /*skip array length*/1 + i*element_size; + update_container_refcounts(element, zeros); + } + } + } + else if (is_mu_container(payload_type) || is_mu_exclusive_container(payload_type)) { + reagent tmp; + tmp.value = address + /*skip refcount*/1; + tmp.type = new type_tree(*payload_type); + vector<double> zeros; + zeros.resize(size_of(payload_type)); + update_container_refcounts(tmp, zeros); + } // clear memory - for (int curr = address; curr < address+size; ++curr) + for (int curr = address; curr < address+payload_size; ++curr) put(Memory, curr, 0); // append existing free list to address - put(Memory, address, get_or_insert(Current_routine->free_list, size)); - put(Current_routine->free_list, size, address); + trace(9999, "abandon") << "saving " << address << " in free-list of size " << payload_size << end(); + put(Memory, address, get_or_insert(Current_routine->free_list, payload_size)); + put(Current_routine->free_list, payload_size, address); } :(before "ensure_space(size)" following "case ALLOCATE") @@ -128,4 +157,82 @@ def main [ ] +run: {10: ("address" "array" "number")} <- new {number: "type"}, {25: "literal"} # abandoned array is of old size (20, not 25) -+abandon: saving in free-list of size 22 ++abandon: saving 1000 in free-list of size 22 + +:(scenario refcounts_abandon_address_in_container) +# container containing an address +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 + 1:address:number <- copy 0 + 2:address:foo <- copy 0 +] ++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")} ++mem: incrementing refcount of 1000: 1 -> 2 ++run: {1: ("address" "number")} <- copy {0: "literal"} ++mem: decrementing refcount of 1000: 2 -> 1 ++run: {2: ("address" "foo")} <- copy {0: "literal"} +# start abandoning container containing address ++mem: decrementing refcount of 1002: 1 -> 0 +# nested abandon ++mem: decrementing refcount of 1000: 1 -> 0 ++abandon: saving 1000 in free-list of size 2 +# actually abandon the container containing address ++abandon: saving 1002 in free-list of size 2 + +# todo: move past dilated reagent +:(scenario refcounts_abandon_address_in_array) +def main [ + 1:address:number <- new number:type + 2:address:array:address:number <- new {(address number): type}, 3 + *2:address:array:address:number <- put-index *2:address:array:address:number, 1, 1:address:number + 1:address:number <- copy 0 + 2:address:array:address:number <- copy 0 +] ++run: {1: ("address" "number")} <- new {number: "type"} ++mem: incrementing refcount of 1000: 0 -> 1 ++run: {2: ("address" "array" "address" "number"), "lookup": ()} <- put-index {2: ("address" "array" "address" "number"), "lookup": ()}, {1: "literal"}, {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" "array" "address" "number")} <- copy {0: "literal"} +# nested abandon ++mem: decrementing refcount of 1000: 1 -> 0 ++abandon: saving 1000 in free-list of size 2 + +:(scenario refcounts_abandon_address_in_container_in_array) +# container containing an address +container foo [ + x:address:number +] +def main [ + 1:address:number <- new number:type + 2:address:array:foo <- new foo:type, 3 + 3:foo <- merge 1:address:number + *2:address:array:foo <- put-index *2:address:array:foo, 1, 3:foo + 1:address:number <- copy 0 + 3:foo <- merge 0 + 2:address:array:foo <- copy 0 +] ++run: {1: ("address" "number")} <- new {number: "type"} ++mem: incrementing refcount of 1000: 0 -> 1 ++run: {3: "foo"} <- merge {1: ("address" "number")} ++mem: incrementing refcount of 1000: 1 -> 2 ++run: {2: ("address" "array" "foo"), "lookup": ()} <- put-index {2: ("address" "array" "foo"), "lookup": ()}, {1: "literal"}, {3: "foo"} ++mem: incrementing refcount of 1000: 2 -> 3 ++run: {1: ("address" "number")} <- copy {0: "literal"} ++mem: decrementing refcount of 1000: 3 -> 2 ++run: {3: "foo"} <- merge {0: "literal"} ++mem: decrementing refcount of 1000: 2 -> 1 ++run: {2: ("address" "array" "foo")} <- copy {0: "literal"} +# nested abandon ++mem: decrementing refcount of 1000: 1 -> 0 ++abandon: saving 1000 in free-list of size 2 diff --git a/043space.cc b/043space.cc index 936f552d..094cb827 100644 --- a/043space.cc +++ b/043space.cc @@ -258,6 +258,7 @@ void try_reclaim_locals() { //? } //? } abandon(current_call().default_space, + inst.products.at(0).type->right, /*refcount*/1 + /*array length*/1 + /*number-of-locals*/Name[r][""]); } |