From 3a7a408386b8b1fbeb82cf6d695a168296c02793 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Fri, 23 Mar 2012 17:51:54 -0700
Subject: [PATCH] rt: Free all outstanding boxes at task death

---
 mk/rt.mk                        |  1 +
 src/rt/rust_box_annihilator.cpp | 15 +++++++++++++++
 src/rt/rust_task.cpp            |  5 +++++
 3 files changed, 21 insertions(+)
 create mode 100644 src/rt/rust_box_annihilator.cpp

diff --git a/mk/rt.mk b/mk/rt.mk
index c0223070e57..2eaa784e191 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -67,6 +67,7 @@ RUNTIME_CS_$(1) := \
               rt/rust_abi.cpp \
               rt/rust_cc.cpp \
               rt/rust_debug.cpp \
+              rt/rust_box_annihilator.cpp \
               rt/memory_region.cpp \
               rt/boxed_region.cpp \
               rt/arch/$$(HOST_$(1))/context.cpp
diff --git a/src/rt/rust_box_annihilator.cpp b/src/rt/rust_box_annihilator.cpp
new file mode 100644
index 00000000000..29c69aa1766
--- /dev/null
+++ b/src/rt/rust_box_annihilator.cpp
@@ -0,0 +1,15 @@
+#include "rust_internal.h"
+#include "rust_shape.h"
+
+void
+annihilate_boxes(rust_task *task) {
+    LOG(task, gc, "annihilating boxes for task %p", task);
+
+    boxed_region *boxed = &task->boxed;
+    rust_opaque_box *box = boxed->first_live_alloc();
+    while (box != NULL) {
+        rust_opaque_box *tmp = box;
+        box = box->next;
+        boxed->free(tmp);
+    }
+}
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index b06a2b2d8b7..de3069ddf58 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -87,12 +87,17 @@ struct cleanup_args {
     bool threw_exception;
 };
 
+void
+annihilate_boxes(rust_task *task);
+
 void
 cleanup_task(cleanup_args *args) {
     spawn_args *a = args->spargs;
     bool threw_exception = args->threw_exception;
     rust_task *task = a->task;
 
+    cc::do_cc(task);
+    annihilate_boxes(task);
     cc::do_final_cc(task);
 
     task->die();