about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Sullivan <sully@msully.net>2012-06-13 17:59:21 -0700
committerMichael Sullivan <sully@msully.net>2012-06-13 17:59:21 -0700
commit4c0d41cffae78725c20a40302e81ef1246c3e4c7 (patch)
tree22bc0c98ad81612eff343237e5cc8d529e552f49
parent31f4b63dffb49e65d3de4ecbef573e15b0f44e36 (diff)
downloadrust-4c0d41cffae78725c20a40302e81ef1246c3e4c7.tar.gz
rust-4c0d41cffae78725c20a40302e81ef1246c3e4c7.zip
Add a malloc_dyn upcall for dynamically sized allocations on the shared heap.
-rw-r--r--src/rt/boxed_region.cpp26
-rw-r--r--src/rt/boxed_region.h14
-rw-r--r--src/rt/rust_kernel.cpp5
-rw-r--r--src/rt/rust_kernel.h11
-rw-r--r--src/rt/rust_upcall.cpp74
-rw-r--r--src/rt/rust_util.h7
-rw-r--r--src/rustc/back/upcall.rs4
7 files changed, 102 insertions, 39 deletions
diff --git a/src/rt/boxed_region.cpp b/src/rt/boxed_region.cpp
index 20b608a7060..6b04028c3fc 100644
--- a/src/rt/boxed_region.cpp
+++ b/src/rt/boxed_region.cpp
@@ -2,14 +2,12 @@
 #include "rust_globals.h"
 #include "rust_task.h"
 #include "rust_env.h"
+#include "rust_util.h"
 
 // #define DUMP_BOXED_REGION
 
-rust_opaque_box *boxed_region::malloc(type_desc *td) {
-    size_t header_size = sizeof(rust_opaque_box);
-    size_t body_size = td->size;
-    size_t body_align = td->align;
-    size_t total_size = align_to(header_size, body_align) + body_size;
+rust_opaque_box *boxed_region::malloc(type_desc *td, size_t body_size) {
+    size_t total_size = get_box_size(body_size, td->align);
     rust_opaque_box *box =
       (rust_opaque_box*)backing_region->malloc(total_size, "@");
     box->td = td;
@@ -22,14 +20,14 @@ rust_opaque_box *boxed_region::malloc(type_desc *td) {
     LOG(rust_get_current_task(), box,
         "@malloc()=%p with td %p, size %lu==%lu+%lu, "
         "align %lu, prev %p, next %p\n",
-        box, td, total_size, header_size, body_size, body_align,
-        box->prev, box->next);
+        box, td, total_size, sizeof(rust_opaque_box), body_size,
+        td->align, box->prev, box->next);
 
     return box;
 }
 
-rust_opaque_box *boxed_region::calloc(type_desc *td) {
-    rust_opaque_box *box = malloc(td);
+rust_opaque_box *boxed_region::calloc(type_desc *td, size_t body_size) {
+    rust_opaque_box *box = malloc(td, body_size);
     memset(box_body(box), 0, td->size);
     return box;
 }
@@ -62,3 +60,13 @@ void boxed_region::free(rust_opaque_box *box) {
 
     backing_region->free(box);
 }
+
+//
+// Local Variables:
+// mode: C++
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
+//
diff --git a/src/rt/boxed_region.h b/src/rt/boxed_region.h
index a3a90f9b7d6..17282d3e5d5 100644
--- a/src/rt/boxed_region.h
+++ b/src/rt/boxed_region.h
@@ -34,9 +34,19 @@ public:
 
     rust_opaque_box *first_live_alloc() { return live_allocs; }
 
-    rust_opaque_box *malloc(type_desc *td);
-    rust_opaque_box *calloc(type_desc *td);
+    rust_opaque_box *malloc(type_desc *td, size_t body_size);
+    rust_opaque_box *calloc(type_desc *td, size_t body_size);
     void free(rust_opaque_box *box);
 };
 
 #endif /* BOXED_REGION_H */
+
+//
+// Local Variables:
+// mode: C++
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
+//
diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp
index 4451f362f27..dc743aceef8 100644
--- a/src/rt/rust_kernel.cpp
+++ b/src/rt/rust_kernel.cpp
@@ -63,6 +63,11 @@ rust_kernel::malloc(size_t size, const char *tag) {
 }
 
 void *
+rust_kernel::calloc(size_t size, const char *tag) {
+    return _region.calloc(size, tag);
+}
+
+void *
 rust_kernel::realloc(void *mem, size_t size) {
     return _region.realloc(mem, size);
 }
diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h
index 8a963dbb25c..ba2c6a7bff0 100644
--- a/src/rt/rust_kernel.h
+++ b/src/rt/rust_kernel.h
@@ -113,6 +113,7 @@ public:
     void fatal(char const *fmt, ...);
 
     void *malloc(size_t size, const char *tag);
+    void *calloc(size_t size, const char *tag);
     void *realloc(void *mem, size_t size);
     void free(void *mem);
     memory_region *region() { return &_region; }
@@ -165,3 +166,13 @@ template <typename T> struct kernel_owned {
 };
 
 #endif /* RUST_KERNEL_H */
+
+//
+// Local Variables:
+// mode: C++
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
+//
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index f523f82a4f5..f5745fe4b86 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -144,14 +144,8 @@ exchange_malloc(rust_task *task, type_desc *td, uintptr_t size) {
 
     LOG(task, mem, "upcall exchange malloc(0x%" PRIxPTR ")", td);
 
-    // Copied from boxed_region
-    size_t header_size = sizeof(rust_opaque_box);
-    size_t body_size = size;
-    size_t body_align = td->align;
-    // FIXME: This alignment calculation is suspicious. Is it right?
-    size_t total_size = align_to(header_size, body_align) + body_size;
-
-    void *p = task->kernel->malloc(total_size, "exchange malloc");
+    size_t total_size = get_box_size(size, td->align);
+    void *p = task->kernel->calloc(total_size, "exchange malloc");
 
     rust_opaque_box *header = static_cast<rust_opaque_box*>(p);
     header->ref_count = -1; // This is not ref counted
@@ -159,8 +153,6 @@ exchange_malloc(rust_task *task, type_desc *td, uintptr_t size) {
     header->prev = 0;
     header->next = 0;
 
-    memset(&header[1], '\0', body_size);
-
     return (uintptr_t)header;
 }
 
@@ -174,8 +166,7 @@ upcall_s_exchange_malloc(s_exchange_malloc_args *args) {
     rust_task *task = rust_get_current_task();
     LOG_UPCALL_ENTRY(task);
 
-    uintptr_t retval = exchange_malloc(task, args->td, args->td->size);
-    args->retval = retval;
+    args->retval = exchange_malloc(task, args->td, args->td->size);
 }
 
 extern "C" CDECL uintptr_t
@@ -196,8 +187,7 @@ upcall_s_exchange_malloc_dyn(s_exchange_malloc_dyn_args *args) {
     rust_task *task = rust_get_current_task();
     LOG_UPCALL_ENTRY(task);
 
-    uintptr_t retval = exchange_malloc(task, args->td, args->size);
-    args->retval = retval;
+    args->retval = exchange_malloc(task, args->td, args->size);
 }
 
 extern "C" CDECL uintptr_t
@@ -228,22 +218,14 @@ upcall_exchange_free(void *ptr) {
  * Allocate an object in the task-local heap.
  */
 
-struct s_malloc_args {
-    uintptr_t retval;
-    type_desc *td;
-};
-
-extern "C" CDECL void
-upcall_s_malloc(s_malloc_args *args) {
-    rust_task *task = rust_get_current_task();
-    LOG_UPCALL_ENTRY(task);
-
-    LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", args->td);
+extern "C" CDECL uintptr_t
+shared_malloc(rust_task *task, type_desc *td, uintptr_t size) {
+    LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", td);
 
     cc::maybe_cc(task);
 
     // FIXME--does this have to be calloc?
-    rust_opaque_box *box = task->boxed.calloc(args->td);
+    rust_opaque_box *box = task->boxed.calloc(td, size);
     void *body = box_body(box);
 
     debug::maybe_track_origin(task, box);
@@ -251,8 +233,22 @@ upcall_s_malloc(s_malloc_args *args) {
     LOG(task, mem,
         "upcall malloc(0x%" PRIxPTR ") = box 0x%" PRIxPTR
         " with body 0x%" PRIxPTR,
-        args->td, (uintptr_t)box, (uintptr_t)body);
-    args->retval = (uintptr_t) box;
+        td, (uintptr_t)box, (uintptr_t)body);
+
+    return (uintptr_t)box;
+}
+
+struct s_malloc_args {
+    uintptr_t retval;
+    type_desc *td;
+};
+
+extern "C" CDECL void
+upcall_s_malloc(s_malloc_args *args) {
+    rust_task *task = rust_get_current_task();
+    LOG_UPCALL_ENTRY(task);
+
+    args->retval = shared_malloc(task, args->td, args->td->size);
 }
 
 extern "C" CDECL uintptr_t
@@ -262,6 +258,28 @@ upcall_malloc(type_desc *td) {
     return args.retval;
 }
 
+struct s_malloc_dyn_args {
+    uintptr_t retval;
+    type_desc *td;
+    uintptr_t size;
+};
+
+extern "C" CDECL void
+upcall_s_malloc_dyn(s_malloc_dyn_args *args) {
+    rust_task *task = rust_get_current_task();
+    LOG_UPCALL_ENTRY(task);
+
+    args->retval = shared_malloc(task, args->td, args->size);
+}
+
+extern "C" CDECL uintptr_t
+upcall_malloc_dyn(type_desc *td, uintptr_t size) {
+    s_malloc_dyn_args args = {0, td, size};
+    UPCALL_SWITCH_STACK(&args, upcall_s_malloc_dyn);
+    return args.retval;
+}
+
+
 /**********************************************************************
  * Called whenever an object in the task-local heap is freed.
  */
diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h
index 3e0a343f5e9..a7bb56c7c37 100644
--- a/src/rt/rust_util.h
+++ b/src/rt/rust_util.h
@@ -104,6 +104,13 @@ make_str_vec(rust_kernel* kernel, size_t nstrs, char **strs) {
     return v;
 }
 
+inline size_t get_box_size(size_t body_size, size_t body_align) {
+    size_t header_size = sizeof(rust_opaque_box);
+    // FIXME: This alignment calculation is suspicious. Is it right?
+    size_t total_size = align_to(header_size, body_align) + body_size;
+    return total_size;
+}
+
 // Initialization helpers for ISAAC RNG
 
 inline void isaac_seed(rust_kernel* kernel, uint8_t* dest)
diff --git a/src/rustc/back/upcall.rs b/src/rustc/back/upcall.rs
index 33fec5fab03..c24e23d2655 100644
--- a/src/rustc/back/upcall.rs
+++ b/src/rustc/back/upcall.rs
@@ -11,6 +11,7 @@ type upcalls =
     {_fail: ValueRef,
      trace: ValueRef,
      malloc: ValueRef,
+     malloc_dyn: ValueRef,
      free: ValueRef,
      exchange_malloc: ValueRef,
      exchange_malloc_dyn: ValueRef,
@@ -58,6 +59,9 @@ fn declare_upcalls(targ_cfg: @session::config,
                               int_t]),
           malloc:
               nothrow(d("malloc", [T_ptr(tydesc_type)],
+          malloc_dyn:
+              nothrow(d("malloc_dyn",
+                        [T_ptr(tydesc_type), int_t],
                         T_ptr(T_i8()))),
           free:
               nothrow(dv("free", [T_ptr(T_i8())])),