about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-05-08 16:47:18 -0700
committerBrian Anderson <banderson@mozilla.com>2012-05-30 21:23:33 -0700
commit508ccca014fcc3a8ef241868ea05e36058b3e61c (patch)
tree7c6d2e53921eff3bf172bf16d6de8f3e76e2033c /src
parent6d37c90ce638f6bbf2b9abdc6625fcb1d8887bfe (diff)
downloadrust-508ccca014fcc3a8ef241868ea05e36058b3e61c.tar.gz
rust-508ccca014fcc3a8ef241868ea05e36058b3e61c.zip
rt: Add upcall_exchange_malloc/free
Diffstat (limited to 'src')
-rw-r--r--src/rt/rust_upcall.cpp55
-rw-r--r--src/rt/rustrt.def.in4
-rw-r--r--src/rustc/back/upcall.rs7
3 files changed, 65 insertions, 1 deletions
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 9ad1f3a5e4d..55d7fc489ad 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -152,6 +152,61 @@ upcall_trace(char const *msg,
 }
 
 /**********************************************************************
+ * Allocate an object in the exchange heap
+ */
+
+struct s_exchange_malloc_args {
+    uintptr_t retval;
+    type_desc *td;
+};
+
+extern "C" CDECL void
+upcall_s_exchange_malloc(s_exchange_malloc_args *args) {
+    rust_task *task = rust_get_current_task();
+    LOG_UPCALL_ENTRY(task);
+
+    LOG(task, mem, "upcall exchange malloc(0x%" PRIxPTR ")", args->td);
+
+    // Copied from boxed_region
+    size_t header_size = sizeof(rust_opaque_box);
+    size_t body_size = args->td->size;
+    size_t body_align = args->td->align;
+    size_t total_size = align_to(header_size, body_align) + body_size;
+
+    void *p = task->kernel->malloc(total_size, "exchange malloc");
+    memset(p, '\0', total_size);
+
+    rust_opaque_box *header = static_cast<rust_opaque_box*>(p);
+    header->td = args->td;
+
+    args->retval = (uintptr_t)header;
+}
+
+extern "C" CDECL uintptr_t
+upcall_exchange_malloc(type_desc *td) {
+    s_exchange_malloc_args args = {0, td};
+    UPCALL_SWITCH_STACK(&args, upcall_s_exchange_malloc);
+    return args.retval;
+}
+
+struct s_exchange_free_args {
+    void *ptr;
+};
+
+extern "C" CDECL void
+upcall_s_exchange_free(s_exchange_free_args *args) {
+    rust_task *task = rust_get_current_task();
+    LOG_UPCALL_ENTRY(task);
+    task->kernel->free(args->ptr);
+}
+
+extern "C" CDECL void
+upcall_exchange_free(void *ptr) {
+    s_exchange_free_args args = {ptr};
+    UPCALL_SWITCH_STACK(&args, upcall_s_exchange_free);
+}
+
+/**********************************************************************
  * Allocate an object in the task-local heap.
  */
 
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index d982110bb99..aaa4fcd8cec 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -88,6 +88,8 @@ upcall_call_shim_on_rust_stack
 upcall_new_stack
 upcall_del_stack
 upcall_reset_stack_limit
+upcall_exchange_malloc
+upcall_exchange_free
 rust_uv_loop_new
 rust_uv_loop_delete
 rust_uv_loop_refcount
@@ -161,4 +163,4 @@ rust_port_take
 rust_port_drop
 rust_port_task
 rust_task_inhibit_kill
-rust_task_allow_kill
\ No newline at end of file
+rust_task_allow_kill
diff --git a/src/rustc/back/upcall.rs b/src/rustc/back/upcall.rs
index 7cc71fca0b2..ec78b5bb946 100644
--- a/src/rustc/back/upcall.rs
+++ b/src/rustc/back/upcall.rs
@@ -12,6 +12,8 @@ type upcalls =
      trace: ValueRef,
      malloc: ValueRef,
      free: ValueRef,
+     exchange_malloc: ValueRef,
+     exchange_free: ValueRef,
      validate_box: ValueRef,
      shared_malloc: ValueRef,
      shared_free: ValueRef,
@@ -62,6 +64,11 @@ fn declare_upcalls(targ_cfg: @session::config,
                         T_ptr(T_i8()))),
           free:
               nothrow(dv("free", [T_ptr(T_i8())])),
+          exchange_malloc:
+              nothrow(d("exchange_malloc", [T_ptr(tydesc_type)],
+                        T_ptr(T_i8()))),
+          exchange_free:
+              nothrow(dv("exchange_free", [T_ptr(T_i8())])),
           validate_box:
               nothrow(dv("validate_box", [T_ptr(T_i8())])),
           shared_malloc: