Add a malloc_dyn upcall for dynamically sized allocations on the shared heap.

This commit is contained in:
Michael Sullivan 2012-06-13 17:59:21 -07:00
parent 31f4b63dff
commit 4c0d41cffa
7 changed files with 103 additions and 40 deletions

View File

@ -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:
//

View File

@ -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:
//

View File

@ -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);

View File

@ -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:
//

View File

@ -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,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.
*/

View File

@ -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)

View File

@ -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())])),