about summary refs log tree commit diff
path: root/src/rt/boxed_region.cpp
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-02-01 18:52:08 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-02-01 18:52:08 -0800
commit196d69beb2c91b29013d44d7a3855561fef600ab (patch)
tree01c3878cd9fea6364d8659da36fae42c2b69cfc8 /src/rt/boxed_region.cpp
parent31166438063236e6d2ad021cf2169fce2b3839b4 (diff)
downloadrust-196d69beb2c91b29013d44d7a3855561fef600ab.tar.gz
rust-196d69beb2c91b29013d44d7a3855561fef600ab.zip
make boxes self-describing (fixes #1493)" (take 2)
this will be used to generate a new snapshot.
Diffstat (limited to 'src/rt/boxed_region.cpp')
-rw-r--r--src/rt/boxed_region.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/rt/boxed_region.cpp b/src/rt/boxed_region.cpp
new file mode 100644
index 00000000000..937069bc38c
--- /dev/null
+++ b/src/rt/boxed_region.cpp
@@ -0,0 +1,59 @@
+#include <assert.h>
+#include "boxed_region.h"
+#include "rust_internal.h"
+
+// #define DUMP_BOXED_REGION
+
+rust_opaque_box *boxed_region::malloc(type_desc *td) {
+    size_t header_size = sizeof(rust_opaque_box);
+    size_t body_size = td->size;
+    size_t body_align = td->align;
+    size_t total_size = align_to(header_size, body_align) + body_size;
+    rust_opaque_box *box =
+      (rust_opaque_box*)backing_region->malloc(total_size, "@");
+    box->td = td;
+    box->ref_count = 1;
+    box->prev = NULL;
+    box->next = live_allocs;
+    if (live_allocs) live_allocs->prev = box;
+    live_allocs = box;
+
+#   ifdef DUMP_BOXED_REGION
+    fprintf(stderr, "Allocated box %p with td %p,"
+            " size %lu==%lu+%lu, align %lu, prev %p, next %p\n",
+            box, td, total_size, header_size, body_size, body_align,
+            box->prev, box->next);
+#   endif
+
+    return box;
+}
+
+rust_opaque_box *boxed_region::calloc(type_desc *td) {
+    rust_opaque_box *box = malloc(td);
+    memset(box_body(box), 0, td->size);
+    return box;
+}
+
+void boxed_region::free(rust_opaque_box *box) {
+    // This turns out to not be true in various situations,
+    // like when we are unwinding after a failure.
+    //
+    // assert(box->ref_count == 0);
+
+    // This however should always be true.  Helps to detect
+    // double frees (kind of).
+    assert(box->td != NULL);
+
+#   ifdef DUMP_BOXED_REGION
+    fprintf(stderr, "Freed box %p with td %p, prev %p, next %p\n",
+            box, box->td, box->prev, box->next);
+#   endif
+
+    if (box->prev) box->prev->next = box->next;
+    if (box->next) box->next->prev = box->prev;
+    if (live_allocs == box) live_allocs = box->next;
+    box->prev = NULL;
+    box->next = NULL;
+    box->td = NULL;
+    backing_region->free(box);
+}