about summary refs log tree commit diff
path: root/src/rt/rust_obstack.cpp
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-09-01 11:47:11 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-09-01 11:47:59 -0700
commitcc08fd1ef9eecf325e370b4aeeba7d69ded65814 (patch)
treebc97f8f956ba157011c4eee33932f5de16589dff /src/rt/rust_obstack.cpp
parent9d00ef9a461ec04962f4ffbd6567364c0c2e9d73 (diff)
downloadrust-cc08fd1ef9eecf325e370b4aeeba7d69ded65814.tar.gz
rust-cc08fd1ef9eecf325e370b4aeeba7d69ded65814.zip
rt: Allow iteration over the dynastack
Diffstat (limited to 'src/rt/rust_obstack.cpp')
-rw-r--r--src/rt/rust_obstack.cpp76
1 files changed, 60 insertions, 16 deletions
diff --git a/src/rt/rust_obstack.cpp b/src/rt/rust_obstack.cpp
index 46fca601ca9..81d0076a37c 100644
--- a/src/rt/rust_obstack.cpp
+++ b/src/rt/rust_obstack.cpp
@@ -25,28 +25,14 @@ const size_t DEFAULT_ALIGNMENT = 16;
 struct rust_obstack_alloc {
     size_t len;
     const type_desc *tydesc;
+    uint32_t pad0;  // FIXME: x86-specific
+    uint32_t pad1;
     uint8_t data[];
 
     rust_obstack_alloc(size_t in_len, const type_desc *in_tydesc)
     : len(in_len), tydesc(in_tydesc) {}
 };
 
-// A contiguous set of allocations.
-struct rust_obstack_chunk {
-    rust_obstack_chunk *prev;
-    size_t size;
-    size_t alen;
-    size_t pad;
-    uint8_t data[];
-
-    rust_obstack_chunk(rust_obstack_chunk *in_prev, size_t in_size)
-    : prev(in_prev), size(in_size), alen(0) {}
-
-    void *alloc(size_t len, type_desc *tydesc);
-    bool free(void *ptr);
-    void *mark();
-};
-
 void *
 rust_obstack_chunk::alloc(size_t len, type_desc *tydesc) {
     alen = align_to(alen, DEFAULT_ALIGNMENT);
@@ -132,3 +118,61 @@ rust_obstack::mark() {
     return chunk ? chunk->mark() : NULL;
 }
 
+
+// Iteration over self-describing obstacks
+
+std::pair<const type_desc *,void *>
+rust_obstack::iterator::operator*() const {
+    return std::make_pair(alloc->tydesc, alloc->data);
+}
+
+rust_obstack::iterator &
+rust_obstack::iterator::operator++() {
+    uint8_t *adata = align_to(alloc->data + alloc->len, DEFAULT_ALIGNMENT);
+    alloc = reinterpret_cast<rust_obstack_alloc *>(adata);
+    if (reinterpret_cast<uint8_t *>(alloc) >= chunk->data + chunk->alen) {
+        // We reached the end of this chunk; go on to the next one.
+        chunk = chunk->prev;
+        if (chunk)
+            alloc = reinterpret_cast<rust_obstack_alloc *>(chunk->data);
+        else
+            alloc = NULL;
+    }
+    return *this;
+}
+
+bool
+rust_obstack::iterator::operator==(const rust_obstack::iterator &other)
+        const {
+    return chunk == other.chunk && alloc == other.alloc;
+}
+
+bool
+rust_obstack::iterator::operator!=(const rust_obstack::iterator &other)
+        const {
+    return !(*this == other);
+}
+
+
+// Debugging
+
+void
+rust_obstack::dump() const {
+    iterator b = begin(), e = end();
+    while (b != e) {
+        std::pair<const type_desc *,void *> data = *b;
+        shape::arena arena;
+        shape::type_param *params = shape::type_param::from_tydesc(data.first,
+                                                                   arena);
+        shape::log log(task, true, data.first->shape, params,
+                       data.first->shape_tables,
+                       reinterpret_cast<uint8_t *>(data.second), std::cerr);
+        log.walk();
+        std::cerr << "\n";
+
+        ++b;
+    }
+
+    std::cerr << "end of dynastack dump\n";
+}
+