// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. #include "boxed_region.h" #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 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; box->ref_count = 1; box->prev = NULL; box->next = live_allocs; if (live_allocs) live_allocs->prev = box; live_allocs = box; /*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, sizeof(rust_opaque_box), body_size, td->align, box->prev, box->next);*/ return box; } rust_opaque_box *boxed_region::realloc(rust_opaque_box *box, size_t new_size) { // We also get called on the unique-vec-in-managed-heap path. assert(box->ref_count == 1 || box->ref_count == (size_t)(-2)); size_t total_size = new_size + sizeof(rust_opaque_box); rust_opaque_box *new_box = (rust_opaque_box*)backing_region->realloc(box, total_size); if (new_box->prev) new_box->prev->next = new_box; if (new_box->next) new_box->next->prev = new_box; if (live_allocs == box) live_allocs = new_box; /*LOG(rust_get_current_task(), box, "@realloc()=%p with orig=%p, size %lu==%lu+%lu", new_box, box, total_size, sizeof(rust_opaque_box), new_size);*/ return new_box; } 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; } 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 (poison_on_free) { memset(box_body(box), 0xab, box->td->size); } box->prev = NULL; box->next = NULL; box->td = NULL; 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: //