diff options
| author | bors <bors@rust-lang.org> | 2014-02-07 19:31:31 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-02-07 19:31:31 -0800 |
| commit | 80c6c73647cc3294c587d8089d6628d8969f0b71 (patch) | |
| tree | 7a6e789f7123151a8fd0e4b2fe1bd7abfb7e0dcf /src/libstd/rt | |
| parent | 29e500db8a98a86b3de56688cd9fa6571a840470 (diff) | |
| parent | 95d897c579621d92a17e9f0bc4edb3ffa24477c7 (diff) | |
| download | rust-80c6c73647cc3294c587d8089d6628d8969f0b71.tar.gz rust-80c6c73647cc3294c587d8089d6628d8969f0b71.zip | |
auto merge of #12059 : thestinger/rust/glue, r=pcwalton
A follow-up from the work I started with 383e3fd13b99827b5dbb107da7433bd0a70dea80.
Diffstat (limited to 'src/libstd/rt')
| -rw-r--r-- | src/libstd/rt/env.rs | 2 | ||||
| -rw-r--r-- | src/libstd/rt/global_heap.rs | 27 | ||||
| -rw-r--r-- | src/libstd/rt/local_heap.rs | 61 |
3 files changed, 88 insertions, 2 deletions
diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs index 729e377e1af..571ed77592f 100644 --- a/src/libstd/rt/env.rs +++ b/src/libstd/rt/env.rs @@ -10,6 +10,8 @@ //! Runtime environment settings +// NOTE: remove `POISON_ON_FREE` after a snapshot + use from_str::from_str; use option::{Some, None}; use os; diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 6bee8cb70f5..2f553585f38 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -10,7 +10,9 @@ use libc::{c_void, size_t, free, malloc, realloc}; use ptr::{RawPtr, mut_null}; -use unstable::intrinsics::{TyDesc, abort}; +#[cfg(stage0)] +use unstable::intrinsics::TyDesc; +use unstable::intrinsics::abort; use unstable::raw; use mem::size_of; @@ -73,14 +75,23 @@ pub unsafe fn exchange_malloc(size: uint) -> *u8 { } // FIXME: #7496 -#[cfg(not(test))] +#[cfg(not(test), stage0)] #[lang="closure_exchange_malloc"] #[inline] pub unsafe fn closure_exchange_malloc_(td: *u8, size: uint) -> *u8 { closure_exchange_malloc(td, size) } +// FIXME: #7496 +#[cfg(not(test), not(stage0))] +#[lang="closure_exchange_malloc"] #[inline] +pub unsafe fn closure_exchange_malloc_(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 { + closure_exchange_malloc(drop_glue, size, align) +} + +#[inline] +#[cfg(stage0)] pub unsafe fn closure_exchange_malloc(td: *u8, size: uint) -> *u8 { let td = td as *TyDesc; let size = size; @@ -96,6 +107,18 @@ pub unsafe fn closure_exchange_malloc(td: *u8, size: uint) -> *u8 { alloc as *u8 } +#[inline] +#[cfg(not(stage0))] +pub unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 { + let total_size = get_box_size(size, align); + let p = malloc_raw(total_size); + + let alloc = p as *mut raw::Box<()>; + (*alloc).drop_glue = drop_glue; + + alloc as *u8 +} + // NB: Calls to free CANNOT be allowed to fail, as throwing an exception from // inside a landing pad may corrupt the state of the exception handler. #[cfg(not(test))] diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index 79936b4afad..3bee9e48b60 100644 --- a/src/libstd/rt/local_heap.rs +++ b/src/libstd/rt/local_heap.rs @@ -21,6 +21,7 @@ use rt::env; use rt::global_heap; use rt::local::Local; use rt::task::Task; +#[cfg(stage0)] use unstable::intrinsics::TyDesc; use unstable::raw; use vec::ImmutableVector; @@ -60,6 +61,7 @@ impl LocalHeap { } #[inline] + #[cfg(stage0)] pub fn alloc(&mut self, td: *TyDesc, size: uint) -> *mut Box { let total_size = global_heap::get_box_size(size, unsafe { (*td).align }); let alloc = self.memory_region.malloc(total_size); @@ -81,6 +83,28 @@ impl LocalHeap { } #[inline] + #[cfg(not(stage0))] + pub fn alloc(&mut self, drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut Box { + let total_size = global_heap::get_box_size(size, align); + let alloc = self.memory_region.malloc(total_size); + { + // Make sure that we can't use `mybox` outside of this scope + let mybox: &mut Box = unsafe { cast::transmute(alloc) }; + // Clear out this box, and move it to the front of the live + // allocations list + mybox.drop_glue = drop_glue; + mybox.ref_count = 1; + mybox.prev = ptr::mut_null(); + mybox.next = self.live_allocs; + if !self.live_allocs.is_null() { + unsafe { (*self.live_allocs).prev = alloc; } + } + self.live_allocs = alloc; + } + return alloc; + } + + #[inline] pub fn realloc(&mut self, ptr: *mut Box, size: uint) -> *mut Box { // Make sure that we can't use `mybox` outside of this scope let total_size = size + mem::size_of::<Box>(); @@ -102,6 +126,7 @@ impl LocalHeap { } #[inline] + #[cfg(stage0)] pub fn free(&mut self, alloc: *mut Box) { { // Make sure that we can't use `mybox` outside of this scope @@ -133,6 +158,28 @@ impl LocalHeap { self.memory_region.free(alloc); } + + #[inline] + #[cfg(not(stage0))] + pub fn free(&mut self, alloc: *mut Box) { + { + // Make sure that we can't use `mybox` outside of this scope + let mybox: &mut Box = unsafe { cast::transmute(alloc) }; + + // Unlink it from the linked list + if !mybox.prev.is_null() { + unsafe { (*mybox.prev).next = mybox.next; } + } + if !mybox.next.is_null() { + unsafe { (*mybox.next).prev = mybox.prev; } + } + if self.live_allocs == alloc { + self.live_allocs = mybox.next; + } + } + + self.memory_region.free(alloc); + } } impl Drop for LocalHeap { @@ -292,6 +339,7 @@ impl Drop for MemoryRegion { } #[inline] +#[cfg(stage0)] pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 { // FIXME: Unsafe borrow for speed. Lame. let task: Option<*mut Task> = Local::try_unsafe_borrow(); @@ -303,6 +351,19 @@ pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 { } } +#[inline] +#[cfg(not(stage0))] +pub unsafe fn local_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 { + // FIXME: Unsafe borrow for speed. Lame. + let task: Option<*mut Task> = Local::try_unsafe_borrow(); + match task { + Some(task) => { + (*task).heap.alloc(drop_glue, size, align) as *u8 + } + None => rtabort!("local malloc outside of task") + } +} + // A little compatibility function #[inline] pub unsafe fn local_free(ptr: *u8) { |
