]> git.lizzy.rs Git - rust.git/blobdiff - src/libarena/lib.rs
add an align parameter to exchange_malloc
[rust.git] / src / libarena / lib.rs
index 24e7a65e02a0ab73ce44c51c72b078b5510bf86f..ec9d4eaed9e01249ca3f019fe21a41f42ed52f83 100644 (file)
@@ -33,6 +33,7 @@
 use std::intrinsics::{TyDesc, get_tydesc};
 use std::intrinsics;
 use std::mem;
+use std::mem::min_align_of;
 use std::num;
 use std::ptr::read;
 use std::rc::Rc;
@@ -204,7 +205,7 @@ fn alloc_copy_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
     #[inline]
     fn alloc_copy<'a, T>(&'a mut self, op: || -> T) -> &'a T {
         unsafe {
-            let ptr = self.alloc_copy_inner(mem::size_of::<T>(), mem::min_align_of::<T>());
+            let ptr = self.alloc_copy_inner(mem::size_of::<T>(), min_align_of::<T>());
             let ptr: *mut T = transmute(ptr);
             mem::move_val_init(&mut (*ptr), op());
             return transmute(ptr);
@@ -261,7 +262,7 @@ fn alloc_noncopy<'a, T>(&'a mut self, op: || -> T) -> &'a T {
         unsafe {
             let tydesc = get_tydesc::<T>();
             let (ty_ptr, ptr) =
-                self.alloc_noncopy_inner(mem::size_of::<T>(), mem::min_align_of::<T>());
+                self.alloc_noncopy_inner(mem::size_of::<T>(), min_align_of::<T>());
             let ty_ptr: *mut uint = transmute(ty_ptr);
             let ptr: *mut T = transmute(ptr);
             // Write in our tydesc along with a bit indicating that it
@@ -353,11 +354,12 @@ struct TypedArenaChunk<T> {
 }
 
 impl<T> TypedArenaChunk<T> {
+    #[cfg(stage0)]
     #[inline]
     fn new(next: Option<Box<TypedArenaChunk<T>>>, capacity: uint)
            -> Box<TypedArenaChunk<T>> {
         let mut size = mem::size_of::<TypedArenaChunk<T>>();
-        size = round_up(size, mem::min_align_of::<T>());
+        size = round_up(size, min_align_of::<T>());
         let elem_size = mem::size_of::<T>();
         let elems_size = elem_size.checked_mul(&capacity).unwrap();
         size = size.checked_add(&elems_size).unwrap();
@@ -373,6 +375,27 @@ fn new(next: Option<Box<TypedArenaChunk<T>>>, capacity: uint)
         chunk
     }
 
+    #[inline]
+    #[cfg(not(stage0))]
+    fn new(next: Option<Box<TypedArenaChunk<T>>>, capacity: uint)
+           -> Box<TypedArenaChunk<T>> {
+        let mut size = mem::size_of::<TypedArenaChunk<T>>();
+        size = round_up(size, mem::min_align_of::<T>());
+        let elem_size = mem::size_of::<T>();
+        let elems_size = elem_size.checked_mul(&capacity).unwrap();
+        size = size.checked_add(&elems_size).unwrap();
+
+        let mut chunk = unsafe {
+            let chunk = global_heap::exchange_malloc(size, min_align_of::<TypedArenaChunk<T>>());
+            let mut chunk: Box<TypedArenaChunk<T>> = cast::transmute(chunk);
+            mem::move_val_init(&mut chunk.next, next);
+            chunk
+        };
+
+        chunk.capacity = capacity;
+        chunk
+    }
+
     /// Destroys this arena chunk. If the type descriptor is supplied, the
     /// drop glue is called; otherwise, drop glue is not called.
     #[inline]
@@ -402,7 +425,7 @@ unsafe fn destroy(&mut self, len: uint) {
     fn start(&self) -> *u8 {
         let this: *TypedArenaChunk<T> = self;
         unsafe {
-            cast::transmute(round_up(this.offset(1) as uint, mem::min_align_of::<T>()))
+            cast::transmute(round_up(this.offset(1) as uint, min_align_of::<T>()))
         }
     }