about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-11-08 09:57:31 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-11-08 09:57:31 -0800
commit2789e86118e1f4da63e5b8883ffdb4ef31c98887 (patch)
tree113c4b4958162f52d8a0d80fe1f2e790b869af8b
parent8ef7e4b1fe7411686150ee369ed60e37c8ebca0d (diff)
downloadmu-2789e86118e1f4da63e5b8883ffdb4ef31c98887.tar.gz
3651
I was under the impression that I only needed static array lengths for
container members, but these are *payload* types for allocations. So we
need to compute the size of a dynamic array.
-rw-r--r--036refcount.cc9
-rw-r--r--037abandon.cc22
2 files changed, 29 insertions, 2 deletions
diff --git a/036refcount.cc b/036refcount.cc
index 55291fa4..765efba7 100644
--- a/036refcount.cc
+++ b/036refcount.cc
@@ -711,8 +711,13 @@ if (is_mu_container(canonized_x) || is_mu_exclusive_container(canonized_x)) {
   const container_metadata& metadata = get(Container_metadata, canonized_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)
-      decrement_refcount(get_or_insert(Memory, canonized_x.value + info->offset), info->payload_type, size_of(info->payload_type)+/*refcount*/1);
+    for (set<address_element_info>::const_iterator info = p->second.begin();  info != p->second.end();  ++info) {
+      int element_address = get_or_insert(Memory, canonized_x.value + info->offset);
+      reagent/*local*/ element;
+      element.set_value(element_address+/*skip refcount*/1);
+      element.type = new type_tree(*info->payload_type);
+      decrement_refcount(element_address, info->payload_type, size_of(element)+/*refcount*/1);
+    }
   }
 }
 
diff --git a/037abandon.cc b/037abandon.cc
index d29d624a..fee39b96 100644
--- a/037abandon.cc
+++ b/037abandon.cc
@@ -223,3 +223,25 @@ def main [
 # nested abandon
 +mem: decrementing refcount of 1000: 1 -> 0
 +abandon: saving 1000 in free-list of size 2
+
+:(scenario refcounts_abandon_array_within_container)
+container foo [
+  x:address:array:num
+]
+def main [
+  1:address:array:num <- new number:type, 3
+  2:foo <- merge 1:address:array:num
+  1:address:array:num <- copy 0
+  2:foo <- copy 0
+]
++run: {1: ("address" "array" "number")} <- new {number: "type"}, {3: "literal"}
++mem: incrementing refcount of 1000: 0 -> 1
++run: {2: "foo"} <- merge {1: ("address" "array" "number")}
++mem: incrementing refcount of 1000: 1 -> 2
++run: {1: ("address" "array" "number")} <- copy {0: "literal"}
++mem: decrementing refcount of 1000: 2 -> 1
++run: {2: "foo"} <- copy {0: "literal"}
++mem: decrementing refcount of 1000: 1 -> 0
++mem: automatically abandoning 1000
+# make sure we save it in a free-list of the appropriate size
++abandon: saving 1000 in free-list of size 5