Add a malloc_dyn upcall for dynamically sized allocations on the shared heap.
This commit is contained in:
@@ -2,14 +2,12 @@
|
|||||||
#include "rust_globals.h"
|
#include "rust_globals.h"
|
||||||
#include "rust_task.h"
|
#include "rust_task.h"
|
||||||
#include "rust_env.h"
|
#include "rust_env.h"
|
||||||
|
#include "rust_util.h"
|
||||||
|
|
||||||
// #define DUMP_BOXED_REGION
|
// #define DUMP_BOXED_REGION
|
||||||
|
|
||||||
rust_opaque_box *boxed_region::malloc(type_desc *td) {
|
rust_opaque_box *boxed_region::malloc(type_desc *td, size_t body_size) {
|
||||||
size_t header_size = sizeof(rust_opaque_box);
|
size_t total_size = get_box_size(body_size, td->align);
|
||||||
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 *box =
|
rust_opaque_box *box =
|
||||||
(rust_opaque_box*)backing_region->malloc(total_size, "@");
|
(rust_opaque_box*)backing_region->malloc(total_size, "@");
|
||||||
box->td = td;
|
box->td = td;
|
||||||
@@ -22,14 +20,14 @@ rust_opaque_box *boxed_region::malloc(type_desc *td) {
|
|||||||
LOG(rust_get_current_task(), box,
|
LOG(rust_get_current_task(), box,
|
||||||
"@malloc()=%p with td %p, size %lu==%lu+%lu, "
|
"@malloc()=%p with td %p, size %lu==%lu+%lu, "
|
||||||
"align %lu, prev %p, next %p\n",
|
"align %lu, prev %p, next %p\n",
|
||||||
box, td, total_size, header_size, body_size, body_align,
|
box, td, total_size, sizeof(rust_opaque_box), body_size,
|
||||||
box->prev, box->next);
|
td->align, box->prev, box->next);
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
rust_opaque_box *boxed_region::calloc(type_desc *td) {
|
rust_opaque_box *boxed_region::calloc(type_desc *td, size_t body_size) {
|
||||||
rust_opaque_box *box = malloc(td);
|
rust_opaque_box *box = malloc(td, body_size);
|
||||||
memset(box_body(box), 0, td->size);
|
memset(box_body(box), 0, td->size);
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
@@ -62,3 +60,13 @@ void boxed_region::free(rust_opaque_box *box) {
|
|||||||
|
|
||||||
backing_region->free(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 *first_live_alloc() { return live_allocs; }
|
||||||
|
|
||||||
rust_opaque_box *malloc(type_desc *td);
|
rust_opaque_box *malloc(type_desc *td, size_t body_size);
|
||||||
rust_opaque_box *calloc(type_desc *td);
|
rust_opaque_box *calloc(type_desc *td, size_t body_size);
|
||||||
void free(rust_opaque_box *box);
|
void free(rust_opaque_box *box);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BOXED_REGION_H */
|
#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);
|
return _region.malloc(size, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
rust_kernel::calloc(size_t size, const char *tag) {
|
||||||
|
return _region.calloc(size, tag);
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
rust_kernel::realloc(void *mem, size_t size) {
|
rust_kernel::realloc(void *mem, size_t size) {
|
||||||
return _region.realloc(mem, size);
|
return _region.realloc(mem, size);
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ public:
|
|||||||
void fatal(char const *fmt, ...);
|
void fatal(char const *fmt, ...);
|
||||||
|
|
||||||
void *malloc(size_t size, const char *tag);
|
void *malloc(size_t size, const char *tag);
|
||||||
|
void *calloc(size_t size, const char *tag);
|
||||||
void *realloc(void *mem, size_t size);
|
void *realloc(void *mem, size_t size);
|
||||||
void free(void *mem);
|
void free(void *mem);
|
||||||
memory_region *region() { return &_region; }
|
memory_region *region() { return &_region; }
|
||||||
@@ -165,3 +166,13 @@ template <typename T> struct kernel_owned {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif /* RUST_KERNEL_H */
|
#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);
|
LOG(task, mem, "upcall exchange malloc(0x%" PRIxPTR ")", td);
|
||||||
|
|
||||||
// Copied from boxed_region
|
size_t total_size = get_box_size(size, td->align);
|
||||||
size_t header_size = sizeof(rust_opaque_box);
|
void *p = task->kernel->calloc(total_size, "exchange malloc");
|
||||||
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");
|
|
||||||
|
|
||||||
rust_opaque_box *header = static_cast<rust_opaque_box*>(p);
|
rust_opaque_box *header = static_cast<rust_opaque_box*>(p);
|
||||||
header->ref_count = -1; // This is not ref counted
|
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->prev = 0;
|
||||||
header->next = 0;
|
header->next = 0;
|
||||||
|
|
||||||
memset(&header[1], '\0', body_size);
|
|
||||||
|
|
||||||
return (uintptr_t)header;
|
return (uintptr_t)header;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,8 +166,7 @@ upcall_s_exchange_malloc(s_exchange_malloc_args *args) {
|
|||||||
rust_task *task = rust_get_current_task();
|
rust_task *task = rust_get_current_task();
|
||||||
LOG_UPCALL_ENTRY(task);
|
LOG_UPCALL_ENTRY(task);
|
||||||
|
|
||||||
uintptr_t retval = exchange_malloc(task, args->td, args->td->size);
|
args->retval = exchange_malloc(task, args->td, args->td->size);
|
||||||
args->retval = retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL uintptr_t
|
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();
|
rust_task *task = rust_get_current_task();
|
||||||
LOG_UPCALL_ENTRY(task);
|
LOG_UPCALL_ENTRY(task);
|
||||||
|
|
||||||
uintptr_t retval = exchange_malloc(task, args->td, args->size);
|
args->retval = exchange_malloc(task, args->td, args->size);
|
||||||
args->retval = retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL uintptr_t
|
extern "C" CDECL uintptr_t
|
||||||
@@ -228,6 +218,26 @@ upcall_exchange_free(void *ptr) {
|
|||||||
* Allocate an object in the task-local heap.
|
* 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 {
|
struct s_malloc_args {
|
||||||
uintptr_t retval;
|
uintptr_t retval;
|
||||||
type_desc *td;
|
type_desc *td;
|
||||||
@@ -238,21 +248,7 @@ upcall_s_malloc(s_malloc_args *args) {
|
|||||||
rust_task *task = rust_get_current_task();
|
rust_task *task = rust_get_current_task();
|
||||||
LOG_UPCALL_ENTRY(task);
|
LOG_UPCALL_ENTRY(task);
|
||||||
|
|
||||||
LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", args->td);
|
args->retval = shared_malloc(task, args->td, args->td->size);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL uintptr_t
|
extern "C" CDECL uintptr_t
|
||||||
@@ -262,6 +258,28 @@ upcall_malloc(type_desc *td) {
|
|||||||
return args.retval;
|
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.
|
* 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;
|
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
|
// Initialization helpers for ISAAC RNG
|
||||||
|
|
||||||
inline void isaac_seed(rust_kernel* kernel, uint8_t* dest)
|
inline void isaac_seed(rust_kernel* kernel, uint8_t* dest)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ type upcalls =
|
|||||||
{_fail: ValueRef,
|
{_fail: ValueRef,
|
||||||
trace: ValueRef,
|
trace: ValueRef,
|
||||||
malloc: ValueRef,
|
malloc: ValueRef,
|
||||||
|
malloc_dyn: ValueRef,
|
||||||
free: ValueRef,
|
free: ValueRef,
|
||||||
exchange_malloc: ValueRef,
|
exchange_malloc: ValueRef,
|
||||||
exchange_malloc_dyn: ValueRef,
|
exchange_malloc_dyn: ValueRef,
|
||||||
@@ -58,6 +59,9 @@ fn declare_upcalls(targ_cfg: @session::config,
|
|||||||
int_t]),
|
int_t]),
|
||||||
malloc:
|
malloc:
|
||||||
nothrow(d("malloc", [T_ptr(tydesc_type)],
|
nothrow(d("malloc", [T_ptr(tydesc_type)],
|
||||||
|
malloc_dyn:
|
||||||
|
nothrow(d("malloc_dyn",
|
||||||
|
[T_ptr(tydesc_type), int_t],
|
||||||
T_ptr(T_i8()))),
|
T_ptr(T_i8()))),
|
||||||
free:
|
free:
|
||||||
nothrow(dv("free", [T_ptr(T_i8())])),
|
nothrow(dv("free", [T_ptr(T_i8())])),
|
||||||
|
|||||||
Reference in New Issue
Block a user