rt: Introduce a self-describing box representation and functions to create and free them
This commit is contained in:
parent
5f44a1356e
commit
3632629acc
@ -0,0 +1,18 @@
|
||||
/* Rust box representation. */
|
||||
|
||||
#ifndef RUST_BOX_H
|
||||
#define RUST_BOX_H
|
||||
|
||||
#include "rust_internal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct rust_box {
|
||||
RUST_REFCOUNTED(rust_box)
|
||||
type_desc *tydesc;
|
||||
rust_box *gc_next;
|
||||
rust_box *gc_prev;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "context.h"
|
||||
#include "rust_obstack.h"
|
||||
|
||||
struct rust_box;
|
||||
|
||||
struct stk_seg {
|
||||
unsigned int valgrind_id;
|
||||
uintptr_t limit;
|
||||
@ -57,7 +59,7 @@ rust_task : public kernel_owned<rust_task>, rust_cond
|
||||
context ctx;
|
||||
stk_seg *stk;
|
||||
uintptr_t runtime_sp; // Runtime sp while task running.
|
||||
void *gc_alloc_chain; // Linked list of GC allocations.
|
||||
rust_box *gc_alloc_chain; // Linked list of GC allocations.
|
||||
rust_scheduler *sched;
|
||||
rust_crate_cache *cache;
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "rust_box.h"
|
||||
#include "rust_gc.h"
|
||||
#include "rust_internal.h"
|
||||
#include "rust_unwind.h"
|
||||
@ -76,6 +77,25 @@ upcall_malloc(rust_task *task, size_t nbytes, type_desc *td) {
|
||||
return (uintptr_t) p;
|
||||
}
|
||||
|
||||
extern "C" CDECL rust_box *
|
||||
upcall_malloc_box(rust_task *task, size_t nbytes, type_desc *td) {
|
||||
LOG_UPCALL_ENTRY(task);
|
||||
|
||||
gc::maybe_gc(task);
|
||||
|
||||
rust_box *box = reinterpret_cast<rust_box *>
|
||||
(task->malloc(nbytes + sizeof(rust_box), "tdesc", td));
|
||||
box->ref_count = 1;
|
||||
box->tydesc = td;
|
||||
|
||||
box->gc_prev = NULL;
|
||||
if ((box->gc_next = task->gc_alloc_chain) != NULL)
|
||||
box->gc_next->gc_prev = box;
|
||||
task->gc_alloc_chain = box;
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever an object's ref count drops to zero.
|
||||
*/
|
||||
@ -90,6 +110,24 @@ upcall_free(rust_task *task, void* ptr, uintptr_t is_gc) {
|
||||
task->free(ptr, (bool) is_gc);
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
upcall_free_box(rust_task *task, rust_box *box) {
|
||||
LOG_UPCALL_ENTRY(task);
|
||||
|
||||
assert(!box->ref_count && "Box reference count is nonzero on free!");
|
||||
|
||||
if (box->gc_prev)
|
||||
box->gc_prev->gc_next = box->gc_next;
|
||||
else
|
||||
task->gc_alloc_chain = box->gc_next;
|
||||
if (box->gc_next)
|
||||
box->gc_next->gc_prev = box->gc_prev;
|
||||
|
||||
box->tydesc->drop_glue(NULL, task, (void *)box->tydesc,
|
||||
box->tydesc->first_param, box->data);
|
||||
task->free(box, false);
|
||||
}
|
||||
|
||||
extern "C" CDECL uintptr_t
|
||||
upcall_shared_malloc(rust_task *task, size_t nbytes, type_desc *td) {
|
||||
LOG_UPCALL_ENTRY(task);
|
||||
|
Loading…
x
Reference in New Issue
Block a user