diff options
| author | Michael Sullivan <sully@msully.net> | 2012-06-13 17:59:21 -0700 |
|---|---|---|
| committer | Michael Sullivan <sully@msully.net> | 2012-06-13 17:59:21 -0700 |
| commit | 4c0d41cffae78725c20a40302e81ef1246c3e4c7 (patch) | |
| tree | 22bc0c98ad81612eff343237e5cc8d529e552f49 | |
| parent | 31f4b63dffb49e65d3de4ecbef573e15b0f44e36 (diff) | |
| download | rust-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.cpp | 26 | ||||
| -rw-r--r-- | src/rt/boxed_region.h | 14 | ||||
| -rw-r--r-- | src/rt/rust_kernel.cpp | 5 | ||||
| -rw-r--r-- | src/rt/rust_kernel.h | 11 | ||||
| -rw-r--r-- | src/rt/rust_upcall.cpp | 74 | ||||
| -rw-r--r-- | src/rt/rust_util.h | 7 | ||||
| -rw-r--r-- | src/rustc/back/upcall.rs | 4 |
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())])), |
