Exemple #1
0
void boxed_region::free(rust_opaque_box *box) {
    // This turns out to not be true in various situations,
    // like when we are unwinding after a failure.
    //
    // assert(box->ref_count == 0);

    // This however should always be true.  Helps to detect
    // double frees (kind of).
    assert(box->td != NULL);

    LOG(rust_get_current_task(), box,
        "@free(%p) with td %p, prev %p, next %p\n",
        box, box->td, box->prev, box->next);

    if (box->prev) box->prev->next = box->next;
    if (box->next) box->next->prev = box->prev;
    if (live_allocs == box) live_allocs = box->next;

    if (env->poison_on_free) {
        memset(box_body(box), 0xab, box->td->size);
    }

    box->prev = NULL;
    box->next = NULL;
    box->td = NULL;

    backing_region->free(box);
}
Exemple #2
0
extern "C" CDECL void
debug_box(type_desc *t, rust_opaque_box *box) {
    rust_task *task = rust_get_current_task();
    LOG(task, stdlib, "debug_box(0x%" PRIxPTR ")", box);
    debug_tydesc_helper(t);
    LOG(task, stdlib, "  refcount %" PRIdPTR,
        box->ref_count - 1);  // -1 because we ref'ed for this call
    uint8_t *data = (uint8_t *)box_body(box);
    for (uintptr_t i = 0; i < t->size; ++i) {
        LOG(task, stdlib, "  byte %" PRIdPTR ": 0x%" PRIx8, i, data[i]);
    }
}
Exemple #3
0
extern "C" CDECL void
upcall_s_malloc(s_malloc_args *args) {
    rust_task *task = args->task;
    LOG_UPCALL_ENTRY(task);
    LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", args->td);

    rust_opaque_box *box = task->boxed.malloc(args->td, args->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,
        args->td, (uintptr_t)box, (uintptr_t)body);

    args->retval = (uintptr_t)box;
}
Exemple #4
0
extern "C" CDECL void
upcall_s_malloc(s_malloc_args *args) {
    rust_task *task = rust_task_thread::get_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;
}
Exemple #5
0
// This runs on the Rust stack
void task_start_wrapper(spawn_args *a)
{
    rust_task *task = a->task;

    bool threw_exception = false;
    try {
        // The first argument is the return pointer; as the task fn 
        // must have void return type, we can safely pass 0.
        a->f(0, a->envptr, a->argptr);
    } catch (rust_task *ex) {
        A(task->thread, ex == task,
          "Expected this task to be thrown for unwinding");
        threw_exception = true;

        if (task->c_stack) {
            task->return_c_stack();
        }

        // Since we call glue code below we need to make sure we
        // have the stack limit set up correctly
        task->reset_stack_limit();
    }

    // We should have returned any C stack by now
    I(task->thread, task->c_stack == NULL);

    rust_opaque_box* env = a->envptr;
    if(env) {
        // free the environment (which should be a unique closure).
        const type_desc *td = env->td;
        td->drop_glue(NULL, NULL, td->first_param, box_body(env));
        upcall_shared_free(env);
    }

    // The cleanup work needs lots of stack
    cleanup_args ca = {a, threw_exception};
    task->call_on_c_stack(&ca, (void*)cleanup_task);

    task->ctx.next->swap(task->ctx);
}
Exemple #6
0
// This runs on the Rust stack
void task_start_wrapper(spawn_args *a)
{
    rust_task *task = a->task;

    bool threw_exception = false;
    try {
        a->f(a->envptr, a->argptr);
    } catch (rust_task *ex) {
        assert(ex == task && "Expected this task to be thrown for unwinding");
        threw_exception = true;

        if (task->c_stack) {
            task->return_c_stack();
        }

        // Since we call glue code below we need to make sure we
        // have the stack limit set up correctly
        task->reset_stack_limit();
    }

    // We should have returned any C stack by now
    assert(task->c_stack == NULL);

    rust_opaque_box* env = a->envptr;
    if(env) {
        // free the environment (which should be a unique closure).
        const type_desc *td = env->td;
        td->drop_glue(NULL,
                      box_body(env));
        task->kernel->region()->free(env);
    }

    // The cleanup work needs lots of stack
    cleanup_args ca = {a, threw_exception};
    task->call_on_c_stack(&ca, (void*)cleanup_task);

    task->ctx.next->swap(task->ctx);
}
Exemple #7
0
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;
}