about summary refs log blame commit diff stats
path: root/014literal_string.cc
blob: 421e873f90b1996fa53918dabe46f7ecf633d14a (plain) (tree)
"o"><tag_condition_info> key; key.insert(tag_condition_info(/*tag is at offset*/0, tag)); append_addresses(/*skip tag offset*/1, variant_type(type, tag).type, metadata.address, key); } } } void append_addresses(int base_offset, const type_tree* type, map<set<tag_condition_info>, set<address_element_info> >& out, const set<tag_condition_info>& key) { const type_info& info = get(Type, type->value); if (type->name == "address") { get_or_insert(out, key).insert(address_element_info(base_offset, new type_tree(*type->right))); return; } if (info.kind == CONTAINER) { for (int curr_index = 0, curr_offset = base_offset; curr_index < SIZE(info.elements); ++curr_index) { trace(9993, "transform") << "checking container " << type->name << ", element " << curr_index << end(); reagent/*copy*/ element = element_type(type, curr_index); // Compute Container Address Offset(element) if (is_mu_address(element)) { trace(9993, "transform") << "address at offset " << curr_offset << end(); get_or_insert(out, key).insert(address_element_info(curr_offset, new type_tree(*element.type->right))); ++curr_offset; } else if (is_mu_container(element)) { append_addresses(curr_offset, element.type, out, key); curr_offset += size_of(element); } else if (is_mu_exclusive_container(element)) { const type_info& element_info = get(Type, element.type->value); for (int tag = 0; tag < SIZE(element_info.elements); ++tag) { set<tag_condition_info> new_key = key; new_key.insert(tag_condition_info(curr_offset, tag)); if (!contains_key(out, new_key)) append_addresses(curr_offset+/*skip tag*/1, variant_type(element.type, tag).type, out, new_key); } curr_offset += size_of(element); } else { // non-address primitive ++curr_offset; } } } else if (info.kind == EXCLUSIVE_CONTAINER) { for (int tag = 0; tag < SIZE(info.elements); ++tag) { set<tag_condition_info> new_key = key; new_key.insert(tag_condition_info(base_offset, tag)); if (!contains_key(out, new_key)) append_addresses(base_offset+/*skip tag*/1, variant_type(type, tag).type, out, new_key); } } } int payload_size(const type_tree* type) { assert(type->name == "address"); assert(type->right->name != "array"); return size_of(type->right) + /*refcount*/1; } //: use metadata.address to update refcounts within containers, arrays and //: exclusive containers :(before "End Update Refcounts in write_memory(x)") if (is_mu_container(x) || is_mu_exclusive_container(x)) update_container_refcounts(x, data); :(before "End Update Refcounts in PUT") if (is_mu_container(element) || is_mu_exclusive_container(element)) update_container_refcounts(element, ingredients.at(2)); :(before "End Update Refcounts in PUT_INDEX") if (is_mu_container(element) || is_mu_exclusive_container(element)) update_container_refcounts(element, value); :(before "End Update Refcounts in Successful MAYBE_CONVERT") if (is_mu_container(product) || is_mu_exclusive_container(product)) { vector<double> data; for (int i = 0; i < size_of(product); ++i) data.push_back(get_or_insert(Memory, base_address+/*skip tag*/1+i)); update_container_refcounts(product, data); } :(code) void update_container_refcounts(const reagent& x, const vector<double>& data) { assert(is_mu_container(x) || is_mu_exclusive_container(x)); const container_metadata& metadata = get(Container_metadata, x.type); for (map<set<tag_condition_info>, set<address_element_info> >::const_iterator p = metadata.address.begin(); p != metadata.address.end(); ++p) { if (!all_match(data, p->first)) continue; for (set<address_element_info>::const_iterator info = p->second.begin(); info != p->second.end(); ++info) update_refcounts(get_or_insert(Memory, x.value + info->offset), data.at(info->offset), info->payload_type, size_of(info->payload_type)+/*refcount*/1); } } bool all_match(const vector<double>& data, const set<tag_condition_info>& conditions) { for (set<tag_condition_info>::const_iterator p = conditions.begin(); p != conditions.end(); ++p) { if (data.at(p->offset) != p->tag) return false; } return true; } :(scenario refcounts_put_container) container foo [ a:bar # contains an address ] container bar [ x:address:number ] def main [ 1:address:number <- new number:type 2:bar <- merge 1:address:number 3:address:foo <- new foo:type *3:address:foo <- put *3:address:foo, a:offset, 2:bar ] +run: {1: ("address" "number")} <- new {number: "type"} +mem: incrementing refcount of 1000: 0 -> 1 +run: {2: "bar"} <- merge {1: ("address" "number")} +mem: incrementing refcount of 1000: 1 -> 2 +run: {3: ("address" "foo"), "lookup": ()} <- put {3: ("address" "foo"), "lookup": ()}, {a: "offset"}, {2: "bar"} # put increments refcount inside container +mem: incrementing refcount of 1000: 2 -> 3 :(scenario refcounts_put_index_container) container bar [ x:address:number ] def main [ 1:address:number <- new number:type 2:bar <- merge 1:address:number 3:address:array:bar <- new bar:type, 3 *3:address:array:bar <- put-index *3:address:array:bar, 0, 2:bar ] +run: {1: ("address" "number")} <- new {number: "type"} +mem: incrementing refcount of 1000: 0 -> 1 +run: {2: "bar"} <- merge {1: ("address" "number")} +mem: incrementing refcount of 1000: 1 -> 2 +run: {3: ("address" "array" "bar"), "lookup": ()} <- put-index {3: ("address" "array" "bar"), "lookup": ()}, {0: "literal"}, {2: "bar"} # put-index increments refcount inside container +mem: incrementing refcount of 1000: 2 -> 3 :(scenario refcounts_maybe_convert_container) exclusive-container foo [ a:number b:bar # contains an address ] container bar [ x:address:number ] def main [ 1:address:number <- new number:type 2:bar <- merge 1:address:number 3:foo <- merge 1/b, 2:bar 5:bar, 6:boolean <- maybe-convert 3:foo, 1:variant/b ] +run: {1: ("address" "number")} <- new {number: "type"} +mem: incrementing refcount of 1000: 0 -> 1 +run: {2: "bar"} <- merge {1: ("address" "number")} +mem: incrementing refcount of 1000: 1 -> 2 +run: {3: "foo"} <- merge {1: "literal", "b": ()}, {2: "bar"} +mem: incrementing refcount of 1000: 2 -> 3 +run: {5: "bar"}, {6: "boolean"} <- maybe-convert {3: "foo"}, {1: "variant", "b": ()} +mem: incrementing refcount of 1000: 3 -> 4 :(scenario refcounts_copy_doubly_nested) container foo [ a:bar # no addresses b:curr # contains addresses ] container bar [ x:number y:number ] container curr [ x:number y:address:number # address inside container inside container ] def main [ 1:address:number <- new number:type 2:address:curr <- new curr:type *2:address:curr <- put *2:address:curr, 1:offset/y, 1:address:number 3:address:foo <- new foo:type *3:address:foo <- put *3:address:foo, 1:offset/b, *2:address:curr 4:foo <- copy *3:address:foo ] +transform: compute address offsets for container foo +transform: checking container foo, element 1 +transform: address at offset 3 +run: {1: ("address" "number")} <- new {number: "type"} +mem: incrementing refcount of 1000: 0 -> 1 # storing an address in a container updates its refcount +run: {2: ("address" "curr"), "lookup": ()} <- put {2: ("address" "curr"), "lookup": ()}, {1: "offset", "y": ()}, {1: ("address" "number")} +mem: incrementing refcount of 1000: 1 -> 2 # storing a container in a container updates refcounts of any contained addresses +run: {3: ("address" "foo"), "lookup": ()} <- put {3: ("address" "foo"), "lookup": ()}, {1: "offset", "b": ()}, {2: ("address" "curr"), "lookup": ()} +mem: incrementing refcount of 1000: 2 -> 3 # copying a container containing a container containing an address updates refcount +run: {4: "foo"} <- copy {3: ("address" "foo"), "lookup": ()} +mem: incrementing refcount of 1000: 3 -> 4 :(scenario refcounts_copy_exclusive_container_within_container) container foo [ a:number b:bar ] exclusive-container bar [ x:number y:number z:address:number ] def main [ 1:address:number <- new number:type 2:bar <- merge 0/x, 34 3:foo <- merge 12, 2:bar 5:bar <- merge 1/y, 35 6:foo <- merge 13, 5:bar 8:bar <- merge 2/z, 1:address:number 9:foo <- merge 14, 8:bar 11:foo <- copy 9:foo ] +run: {1: ("address" "number")} <- new {number: "type"} +mem: incrementing refcount of 1000: 0 -> 1 # no change while merging items of other types +run: {8: "bar"} <- merge {2: "literal", "z": ()}, {1: ("address" "number")} +mem: incrementing refcount of 1000: 1 -> 2 +run: {9: "foo"} <- merge {14: "literal"}, {8: "bar"} +mem: incrementing refcount of 1000: 2 -> 3 +run: {11: "foo"} <- copy {9: "foo"} +mem: incrementing refcount of 1000: 3 -> 4 :(scenario refcounts_copy_container_within_exclusive_container) exclusive-container foo [ a:number b:bar ] container bar [ x:number y:number z:address:number ] def main [ 1:address:number <- new number:type 2:foo <- merge 0/a, 34 6:foo <- merge 0/a, 35 10:bar <- merge 2/x, 15/y, 1:address:number 13:foo <- merge 1/b, 10:bar 17:foo <- copy 13:foo ] +run: {1: ("address" "number")} <- new {number: "type"} +mem: incrementing refcount of 1000: 0 -> 1 # no change while merging items of other types +run: {10: "bar"} <- merge {2: "literal", "x": ()}, {15: "literal", "y": ()}, {1: ("address" "number")} +mem: incrementing refcount of 1000: 1 -> 2 +run: {13: "foo"} <- merge {1: "literal", "b": ()}, {10: "bar"} +mem: incrementing refcount of 1000: 2 -> 3 +run: {17: "foo"} <- copy {13: "foo"} +mem: incrementing refcount of 1000: 3 -> 4 :(scenario refcounts_copy_exclusive_container_within_exclusive_container) exclusive-container foo [ a:number b:bar ] exclusive-container bar [ x:number y:address:number ] def main [ 1:address:number <- new number:type 10:foo <- merge 1/b, 1/y, 1:address:number 20:foo <- copy 10:foo ] +run: {1: ("address" "number")} <- new {number: "type"} +mem: incrementing refcount of 1000: 0 -> 1 # no change while merging items of other types +run: {10: "foo"} <- merge {1: "literal", "b": ()}, {1: "literal", "y": ()}, {1: ("address" "number")} +mem: incrementing refcount of 1000: 1 -> 2 +run: {20: "foo"} <- copy {10: "foo"} +mem: incrementing refcount of 1000: 2 -> 3 :(code) bool is_mu_container(const reagent& r) { return is_mu_container(r.type); } bool is_mu_container(const type_tree* type) { if (!type) return false; 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) { return is_mu_exclusive_container(r.type); } bool is_mu_exclusive_container(const type_tree* type) { if (!type) return false; if (type->value == 0) return false; type_info& info = get(Type, type->value); return info.kind == EXCLUSIVE_CONTAINER; }