Add a malloc_dyn upcall for dynamically sized allocations on the shared heap.
This commit is contained in:
parent
31f4b63dff
commit
4c0d41cffa
@ -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:
|
||||
//
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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)
|
||||
|
@ -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())])),
|
||||
|
Loading…
x
Reference in New Issue
Block a user