From 4c0d41cffae78725c20a40302e81ef1246c3e4c7 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Wed, 13 Jun 2012 17:59:21 -0700 Subject: [PATCH] Add a malloc_dyn upcall for dynamically sized allocations on the shared heap. --- src/rt/boxed_region.cpp | 26 +++++++++----- src/rt/boxed_region.h | 14 ++++++-- src/rt/rust_kernel.cpp | 5 +++ src/rt/rust_kernel.h | 11 ++++++ src/rt/rust_upcall.cpp | 76 +++++++++++++++++++++++++--------------- src/rt/rust_util.h | 7 ++++ src/rustc/back/upcall.rs | 4 +++ 7 files changed, 103 insertions(+), 40 deletions(-) diff --git a/src/rt/boxed_region.cpp b/src/rt/boxed_region.cpp index 20b608a7060a..6b04028c3fc9 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 a3a90f9b7d66..17282d3e5d5d 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 4451f362f271..dc743aceef80 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -62,6 +62,11 @@ rust_kernel::malloc(size_t size, const char *tag) { return _region.malloc(size, 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 8a963dbb25c1..ba2c6a7bff05 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 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 f523f82a4f5f..f5745fe4b86f 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(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,6 +218,26 @@ upcall_exchange_free(void *ptr) { * Allocate an object in the task-local heap. */ +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(td, size); + void *body = box_body(box); + + debug::maybe_track_origin(task, box); + + LOG(task, mem, + "upcall malloc(0x%" PRIxPTR ") = box 0x%" PRIxPTR + " with body 0x%" PRIxPTR, + td, (uintptr_t)box, (uintptr_t)body); + + return (uintptr_t)box; +} + struct s_malloc_args { uintptr_t retval; type_desc *td; @@ -238,21 +248,7 @@ 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); - - cc::maybe_cc(task); - - // FIXME--does this have to be calloc? - rust_opaque_box *box = task->boxed.calloc(args->td); - void *body = box_body(box); - - debug::maybe_track_origin(task, box); - - 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; + 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 3e0a343f5e9d..a7bb56c7c378 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 33fec5fab03e..c24e23d26552 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())])),