about summary refs log tree commit diff
path: root/src/rt/rust_gc.cpp
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-08-19 18:52:12 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-08-19 18:52:36 -0700
commit8fa86672ab21a3ef437bbf3af17972091fb9e146 (patch)
tree69ae078d4a480bf6ea76c3098b54d4a91e525488 /src/rt/rust_gc.cpp
parenta3f4a1b6adf9d5e8664f0dbccc62d425d1bab7b1 (diff)
downloadrust-8fa86672ab21a3ef437bbf3af17972091fb9e146.tar.gz
rust-8fa86672ab21a3ef437bbf3af17972091fb9e146.zip
rt: Implement stack crawling
Diffstat (limited to 'src/rt/rust_gc.cpp')
-rw-r--r--src/rt/rust_gc.cpp37
1 files changed, 26 insertions, 11 deletions
diff --git a/src/rt/rust_gc.cpp b/src/rt/rust_gc.cpp
index e10d2055884..ff6ca86f854 100644
--- a/src/rt/rust_gc.cpp
+++ b/src/rt/rust_gc.cpp
@@ -1,12 +1,14 @@
 // Rust garbage collection.
 
 #include <algorithm>
+#include <iostream>
 #include <utility>
 #include <vector>
 #include <stdint.h>
 
 #include "rust_gc.h"
 #include "rust_internal.h"
+#include "rust_shape.h"
 
 #ifdef __WIN32__
 #include <windows.h>
@@ -24,13 +26,10 @@ struct frame {
     uint8_t *bp;    // The frame pointer.
     void (*ra)();   // The return address.
 
-    frame(void *in_bp) : bp((uint8_t *)in_bp) {}
-
-    inline void read_ra() {
-        ra = *(void (**)())(bp + sizeof(void *));
-    }
+    frame(void *in_bp, void (*in_ra)()) : bp((uint8_t *)in_bp), ra(in_ra) {}
 
     inline void next() {
+        ra = *(void (**)())(bp + sizeof(void *));
         bp = *(uint8_t **)bp;
     }
 };
@@ -106,11 +105,15 @@ public:
 
 class gc {
 private:
+    rust_task *task;
+
     void mark(std::vector<root> &roots);
     void sweep();
 
 public:
-    void run(rust_task *task);
+    gc(rust_task *in_task) : task(in_task) {}
+
+    void run();
     std::vector<frame> backtrace();
 };
 
@@ -127,6 +130,14 @@ gc::mark(std::vector<root> &roots) {
     std::vector<root>::iterator ri = roots.begin(), rend = roots.end();
     while (ri < rend) {
         DPRINT("root: %p\n", ri->data);
+
+        shape::arena arena;
+        shape::type_param *params = shape::type_param::make(ri->tydesc,
+                                                            arena);
+        shape::log log(task, ri->tydesc->shape, params,
+                       ri->tydesc->shape_tables, ri->data, std::cerr);
+        log.walk(true);
+
         ++ri;
     }
     // TODO
@@ -140,9 +151,13 @@ gc::sweep() {
 std::vector<frame>
 gc::backtrace() {
     std::vector<frame> frames;
-    frame f(__builtin_frame_address(0));
+
+    // Ideally we would use the current value of EIP here, but there's no
+    // portable way to get that and there are never any GC roots in our C++
+    // frames anyhow.
+    frame f(__builtin_frame_address(0), (void (*)())NULL);
+
     while (f.ra != END_OF_STACK_RA) {
-        f.read_ra();
         frames.push_back(f);
         f.next();
     }
@@ -150,7 +165,7 @@ gc::backtrace() {
 }
 
 void
-gc::run(rust_task *task) {
+gc::run() {
     safe_point_map map;
 
     // Find roots.
@@ -187,8 +202,8 @@ maybe_gc(rust_task *task) {
     }
 
     if (zeal) {
-        gc gc;
-        gc.run(task);
+        gc gc(task);
+        gc.run();
     }
 }