diff options
| author | Graydon Hoare <[email protected]> | 2010-11-09 14:15:07 -0800 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-11-09 14:15:07 -0800 |
| commit | 89946609f2de815ea87df3b001fff0caf9efa0d5 (patch) | |
| tree | 0945861dddd480b822827d77205f90584d0c2586 /src/rt | |
| parent | Add a check for binding an alias. Good thing, as we had two instances in our ... (diff) | |
| download | rust-89946609f2de815ea87df3b001fff0caf9efa0d5.tar.xz rust-89946609f2de815ea87df3b001fff0caf9efa0d5.zip | |
Support a special const-value refcount, use it for const strings.
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 12 | ||||
| -rw-r--r-- | src/rt/rust_internal.h | 7 | ||||
| -rw-r--r-- | src/rt/rust_upcall.cpp | 5 |
3 files changed, 20 insertions, 4 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index d221e6e5..cb16fbf0 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 d1eec48b..f008d9f6 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 9742b22a..ebf81faf 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; } |