about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-11-09 14:15:07 -0800
committerGraydon Hoare <graydon@mozilla.com>2010-11-09 14:15:07 -0800
commit89946609f2de815ea87df3b001fff0caf9efa0d5 (patch)
tree0945861dddd480b822827d77205f90584d0c2586 /src/rt
parent3e9be14757bfcaa65e388a9acd7e2ca97cccfbd0 (diff)
Support a special const-value refcount, use it for const strings.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust_builtin.cpp12
-rw-r--r--src/rt/rust_internal.h7
-rw-r--r--src/rt/rust_upcall.cpp5
3 files changed, 20 insertions, 4 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index d221e6e587b..cb16fbf067d 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -61,8 +61,12 @@ align_of(rust_task *task, type_desc *t) {
   return t->align;
 }
 
-extern "C" CDECL size_t
-refcount(rust_task *task, type_desc *t, size_t *v) {
+extern "C" CDECL intptr_t
+refcount(rust_task *task, type_desc *t, intptr_t *v) {
+
+    if (*v == CONST_REFCOUNT)
+        return CONST_REFCOUNT;
+
     // Passed-in value has refcount 1 too high
     // because it was ref'ed while making the call.
     return (*v) - 1;
@@ -277,7 +281,9 @@ debug_box(rust_task *task, type_desc *t, rust_box *box)
     task->log(rust_log::STDLIB, "debug_box(0x%" PRIxPTR ")", box);
     debug_tydesc_helper(task, t);
     task->log(rust_log::STDLIB, "  refcount %" PRIdPTR,
-              box->ref_count - 1);  // -1 because we ref'ed for this call
+              box->ref_count == CONST_REFCOUNT
+              ? CONST_REFCOUNT
+              : box->ref_count - 1);  // -1 because we ref'ed for this call
     for (uintptr_t i = 0; i < t->size; ++i) {
         task->log(rust_log::STDLIB,
                   "  byte %" PRIdPTR ": 0x%" PRIx8, i, box->data[i]);
diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h
index d1eec48bc3b..f008d9f6bdb 100644
--- a/src/rt/rust_internal.h
+++ b/src/rt/rust_internal.h
@@ -81,6 +81,13 @@ struct frame_glue_fns;
 
 static size_t const TIME_SLICE_IN_MS = 10;
 
+// Since every refcounted object is > 4 bytes, any refcount with any of the
+// top two bits set is invalid. We reserve a particular bit pattern in this
+// set for indicating objects that are "constant" as far as the memory model
+// knows.
+
+static intptr_t const CONST_REFCOUNT = 0x7badface;
+
 // Every reference counted object should derive from this base class.
 
 template <typename T> struct rc_base {
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 9742b22af78..ebf81faf3ac 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -424,7 +424,10 @@ upcall_vec_grow(rust_task *task,
             task->fail(4);
             return NULL;
         }
-        v->deref();
+
+        if (v->ref_count != CONST_REFCOUNT)
+            v->deref();
+
         v = new (mem) rust_vec(dom, alloc, 0, NULL);
         *need_copy = 1;
     }