about summary refs log tree commit diff
path: root/src/rt/rust_upcall.cpp
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-01-17 10:57:11 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-02-01 18:18:07 -0800
commitc36207bfb82f794f17fc5854d4ae50284eddf329 (patch)
tree01c3878cd9fea6364d8659da36fae42c2b69cfc8 /src/rt/rust_upcall.cpp
parent49cb3fc7dfd2a8ee7f35aaa884da8f710cd4a94a (diff)
downloadrust-c36207bfb82f794f17fc5854d4ae50284eddf329.tar.gz
rust-c36207bfb82f794f17fc5854d4ae50284eddf329.zip
make boxes self-describing (fixes #1493)
Diffstat (limited to 'src/rt/rust_upcall.cpp')
-rw-r--r--src/rt/rust_upcall.cpp60
1 files changed, 42 insertions, 18 deletions
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 65299a7d244..09ad8d930c6 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -16,6 +16,20 @@
 #include <stdint.h>
 
 
+#ifdef __GNUC__
+#define LOG_UPCALL_ENTRY(task)                            \
+    LOG(task, upcall,                                     \
+        "> UPCALL %s - task: %s 0x%" PRIxPTR              \
+        " retpc: x%" PRIxPTR,                             \
+        __FUNCTION__,                                     \
+        (task)->name, (task),                             \
+        __builtin_return_address(0));
+#else
+#define LOG_UPCALL_ENTRY(task)                            \
+    LOG(task, upcall, "> UPCALL task: %s @x%" PRIxPTR,    \
+        (task)->name, (task));
+#endif
+
 // This is called to ensure we've set up our rust stacks
 // correctly. Strategically placed at entry to upcalls because they begin on
 // the rust stack and happen frequently enough to catch most stack changes,
@@ -98,7 +112,6 @@ upcall_fail(char const *expr,
 
 struct s_malloc_args {
     uintptr_t retval;
-    size_t nbytes;
     type_desc *td;
 };
 
@@ -107,31 +120,27 @@ upcall_s_malloc(s_malloc_args *args) {
     rust_task *task = rust_scheduler::get_task();
     LOG_UPCALL_ENTRY(task);
 
-    LOG(task, mem,
-        "upcall malloc(%" PRIdPTR ", 0x%" PRIxPTR ")",
-        args->nbytes, args->td);
+    LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", args->td);
 
     gc::maybe_gc(task);
     cc::maybe_cc(task);
 
-    // TODO: Maybe use dladdr here to find a more useful name for the
-    // type_desc.
-
-    void *p = task->malloc(args->nbytes, "tdesc", args->td);
-    memset(p, '\0', args->nbytes);
+    // FIXME--does this have to be calloc?
+    rust_opaque_box *box = task->boxed.calloc(args->td);
+    void *body = box_body(box);
 
-    task->local_allocs[p] = args->td;
-    debug::maybe_track_origin(task, p);
+    debug::maybe_track_origin(task, box);
 
     LOG(task, mem,
-        "upcall malloc(%" PRIdPTR ", 0x%" PRIxPTR ") = 0x%" PRIxPTR,
-        args->nbytes, args->td, (uintptr_t)p);
-    args->retval = (uintptr_t) p;
+        "upcall malloc(0x%" PRIxPTR ") = box 0x%" PRIxPTR
+        " with body 0x%" PRIxPTR,
+        args->td, (uintptr_t)box, (uintptr_t)body);
+    args->retval = (uintptr_t) box;
 }
 
 extern "C" CDECL uintptr_t
-upcall_malloc(size_t nbytes, type_desc *td) {
-    s_malloc_args args = {0, nbytes, td};
+upcall_malloc(type_desc *td) {
+    s_malloc_args args = {0, td};
     UPCALL_SWITCH_STACK(&args, upcall_s_malloc);
     return args.retval;
 }
@@ -155,10 +164,10 @@ upcall_s_free(s_free_args *args) {
              "upcall free(0x%" PRIxPTR ", is_gc=%" PRIdPTR ")",
              (uintptr_t)args->ptr, args->is_gc);
 
-    task->local_allocs.erase(args->ptr);
     debug::maybe_untrack_origin(task, args->ptr);
 
-    task->free(args->ptr, (bool) args->is_gc);
+    rust_opaque_box *box = (rust_opaque_box*) args->ptr;
+    task->boxed.free(box);
 }
 
 extern "C" CDECL void
@@ -168,6 +177,21 @@ upcall_free(void* ptr, uintptr_t is_gc) {
 }
 
 /**********************************************************************
+ * Sanity checks on boxes, insert when debugging possible
+ * use-after-free bugs.  See maybe_validate_box() in trans.rs.
+ */
+
+extern "C" CDECL void
+upcall_validate_box(rust_opaque_box* ptr) {
+    if (ptr) {
+        assert(ptr->ref_count > 0);
+        assert(ptr->td != NULL);
+        assert(ptr->td->align <= 8);
+        assert(ptr->td->size <= 4096); // might not really be true...
+    }
+}
+
+/**********************************************************************
  * Allocate an object in the exchange heap.
  */