about summary refs log tree commit diff
path: root/src/rt/rust_cc.cpp
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-02-08 09:14:30 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-02-08 09:14:59 -0800
commit526e73d7f882bf9a88fe957661cc2e09291cef5b (patch)
tree78c551a1d0c7d0bbd5d337eb606cc1f570ecc6d1 /src/rt/rust_cc.cpp
parent3a1e33e134cf3adc8a1844b59f57828478b36aff (diff)
downloadrust-526e73d7f882bf9a88fe957661cc2e09291cef5b.tar.gz
rust-526e73d7f882bf9a88fe957661cc2e09291cef5b.zip
make shape code use the tydesc found in the box, not the shape str
Diffstat (limited to 'src/rt/rust_cc.cpp')
-rw-r--r--src/rt/rust_cc.cpp62
1 files changed, 33 insertions, 29 deletions
diff --git a/src/rt/rust_cc.cpp b/src/rt/rust_cc.cpp
index 03a4bed014e..ec54b1ef181 100644
--- a/src/rt/rust_cc.cpp
+++ b/src/rt/rust_cc.cpp
@@ -93,7 +93,11 @@ class irc : public shape::data<irc,shape::ptr> {
     }
 
     void walk_box2() {
-        shape::data<irc,shape::ptr>::walk_box_contents1();
+        // the box ptr can be NULL for env ptrs in closures and data
+        // not fully initialized
+        rust_opaque_box *box = *(rust_opaque_box**)dp;
+        if (box)
+            shape::data<irc,shape::ptr>::walk_box_contents1();
     }
 
     void walk_uniq2() {
@@ -103,8 +107,6 @@ class irc : public shape::data<irc,shape::ptr> {
     void walk_fn2(char code) {
         switch (code) {
           case shape::SHAPE_BOX_FN: {
-              // Record an irc for the environment box, but don't descend
-              // into it since it will be walked via the box's allocation
               shape::bump_dp<void*>(dp); // skip over the code ptr
               walk_box2();               // walk over the environment ptr
               break;
@@ -137,19 +139,19 @@ class irc : public shape::data<irc,shape::ptr> {
 
     void walk_uniq_contents2(irc &sub) { sub.walk(); }
 
-    void walk_box_contents2(irc &sub, shape::ptr &box_dp) {
-        maybe_record_irc(box_dp);
+    void walk_box_contents2(irc &sub) {
+        maybe_record_irc();
 
         // Do not traverse the contents of this box; it's in the allocation
         // somewhere, so we're guaranteed to come back to it (if we haven't
         // traversed it already).
     }
 
-    void maybe_record_irc(shape::ptr &box_dp) {
-        if (!box_dp)
-            return;
+    void maybe_record_irc() {
+        rust_opaque_box *box_ptr = *(rust_opaque_box **) dp;
 
-        rust_opaque_box *box_ptr = (rust_opaque_box *) box_dp;
+        if (!box_ptr)
+            return;
 
         // Bump the internal reference count of the box.
         if (ircs.find(box_ptr) == ircs.end()) {
@@ -326,7 +328,11 @@ class mark : public shape::data<mark,shape::ptr> {
     }
 
     void walk_box2() {
-        shape::data<mark,shape::ptr>::walk_box_contents1();
+        // the box ptr can be NULL for env ptrs in closures and data
+        // not fully initialized
+        rust_opaque_box *box = *(rust_opaque_box**)dp;
+        if (box)
+            shape::data<mark,shape::ptr>::walk_box_contents1();
     }
 
     void walk_uniq2() {
@@ -336,8 +342,6 @@ class mark : public shape::data<mark,shape::ptr> {
     void walk_fn2(char code) {
         switch (code) {
           case shape::SHAPE_BOX_FN: {
-              // Record an irc for the environment box, but don't descend
-              // into it since it will be walked via the box's allocation
               shape::data<mark,shape::ptr>::walk_fn_contents1();
               break;
           }
@@ -369,11 +373,11 @@ class mark : public shape::data<mark,shape::ptr> {
 
     void walk_uniq_contents2(mark &sub) { sub.walk(); }
 
-    void walk_box_contents2(mark &sub, shape::ptr &box_dp) {
-        if (!box_dp)
-            return;
+    void walk_box_contents2(mark &sub) {
+        rust_opaque_box *box_ptr = *(rust_opaque_box **) dp;
 
-        rust_opaque_box *box_ptr = (rust_opaque_box *) box_dp;
+        if (!box_ptr)
+            return;
 
         if (marked.find(box_ptr) != marked.end())
             return; // Skip to avoid chasing cycles.
@@ -516,7 +520,9 @@ class sweep : public shape::data<sweep,shape::ptr> {
     }
 
     void walk_box2() {
-        shape::data<sweep,shape::ptr>::walk_box_contents1();
+        // In sweep phase, do not walk the box contents.  There is an
+        // outer loop walking all remaining boxes, and this box may well
+        // have been freed already!
     }
 
     void walk_fn2(char code) {
@@ -524,14 +530,16 @@ class sweep : public shape::data<sweep,shape::ptr> {
           case shape::SHAPE_UNIQ_FN: {
               fn_env_pair pair = *(fn_env_pair*)dp;
 
-              // free closed over data:
-              shape::data<sweep,shape::ptr>::walk_fn_contents1();
-
-              // now free the embedded type descr:
-              upcall_s_free_shared_type_desc((type_desc*)pair.env->td);
-
-              // now free the ptr:
-              task->kernel->free(pair.env);
+              if (pair.env) {
+                  // free closed over data:
+                  shape::data<sweep,shape::ptr>::walk_fn_contents1();
+                  
+                  // now free the embedded type descr:
+                  upcall_s_free_shared_type_desc((type_desc*)pair.env->td);
+                  
+                  // now free the ptr:
+                  task->kernel->free(pair.env);
+              }
               break;
           }
           case shape::SHAPE_BOX_FN: {
@@ -579,10 +587,6 @@ class sweep : public shape::data<sweep,shape::ptr> {
 
     void walk_uniq_contents2(sweep &sub) { sub.walk(); }
 
-    void walk_box_contents2(sweep &sub, shape::ptr &box_dp) {
-        return;
-    }
-
     void walk_struct2(const uint8_t *end_sp) {
         while (this->sp != end_sp) {
             this->walk();