(index<- )        ./libstd/rt/global_heap.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  
  12  //! The global (exchange) heap.
  13  
  14  use libc::{c_void, size_t, free, malloc, realloc};
  15  use ptr::{RawPtr, mut_null};
  16  use intrinsics::abort;
  17  use raw;
  18  use mem::size_of;
  19  
  20  #[inline]
  21  pub fn get_box_size(body_size: uint, body_align: uint) -> uint {
  22      let header_size = size_of::<raw::Box<()>>();
  23      let total_size = align_to(header_size, body_align) + body_size;
  24      total_size
  25  }
  26  
  27  // Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power
  28  // of two.
  29  #[inline]
  30  fn align_to(size: uint, align: uint) -> uint {
  31      assert!(align != 0);
  32      (size + align - 1) & !(align - 1)
  33  }
  34  
  35  /// A wrapper around libc::malloc, aborting on out-of-memory
  36  #[inline]
  37  pub unsafe fn malloc_raw(size: uint) -> *mut u8 {
  38      // `malloc(0)` may allocate, but it may also return a null pointer
  39      // http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html
  40      if size == 0 {
  41          mut_null()
  42      } else {
  43          let p = malloc(size as size_t);
  44          if p.is_null() {
  45              // we need a non-allocating way to print an error here
  46              abort();
  47          }
  48          p as *mut u8
  49      }
  50  }
  51  
  52  /// A wrapper around libc::realloc, aborting on out-of-memory
  53  #[inline]
  54  pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 {
  55      // `realloc(ptr, 0)` may allocate, but it may also return a null pointer
  56      // http://pubs.opengroup.org/onlinepubs/9699919799/functions/realloc.html
  57      if size == 0 {
  58          free(ptr as *mut c_void);
  59          mut_null()
  60      } else {
  61          let p = realloc(ptr as *mut c_void, size as size_t);
  62          if p.is_null() {
  63              // we need a non-allocating way to print an error here
  64              abort();
  65          }
  66          p as *mut u8
  67      }
  68  }
  69  
  70  /// The allocator for unique pointers without contained managed pointers.
  71  #[cfg(not(test))]
  72  #[lang="exchange_malloc"]
  73  #[inline]
  74  pub unsafe fn exchange_malloc(size: uint) -> *mut u8 {
  75      // The compiler never calls `exchange_free` on Box<ZeroSizeType>, so
  76      // zero-size allocations can point to this `static`. It would be incorrect
  77      // to use a null pointer, due to enums assuming types like unique pointers
  78      // are never null.
  79      static EMPTY: () = ();
  80  
  81      if size == 0 {
  82          &EMPTY as *() as *mut u8
  83      } else {
  84          malloc_raw(size)
  85      }
  86  }
  87  
  88  // FIXME: #7496
  89  #[cfg(not(test))]
  90  #[lang="closure_exchange_malloc"]
  91  #[inline]
  92  pub unsafe fn closure_exchange_malloc_(drop_gluefn(*mut u8), size: uint, align: uint) -> *u8 {
  93      closure_exchange_malloc(drop_glue, size, align)
  94  }
  95  
  96  #[inline]
  97  pub unsafe fn closure_exchange_malloc(drop_gluefn(*mut u8), size: uint, align: uint) -> *u8 {
  98      let total_size = get_box_size(size, align);
  99      let p = malloc_raw(total_size);
 100  
 101      let alloc = p as *mut raw::Box<()>;
 102      (*alloc).drop_glue = drop_glue;
 103  
 104      alloc as *u8
 105  }
 106  
 107  // NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
 108  // inside a landing pad may corrupt the state of the exception handler.
 109  #[cfg(not(test))]
 110  #[lang="exchange_free"]
 111  #[inline]
 112  pub unsafe fn exchange_free_(ptr: *u8) {
 113      exchange_free(ptr)
 114  }
 115  
 116  #[inline]
 117  pub unsafe fn exchange_free(ptr: *u8) {
 118      free(ptr as *mut c_void);
 119  }
 120  
 121  #[cfg(test)]
 122  mod bench {
 123      extern crate test;
 124      use self::test::Bencher;
 125  
 126      #[bench]
 127      fn alloc_owned_small(b: &mut Bencher) {
 128          b.iter(|| {
 129              box 10
 130          })
 131      }
 132  
 133      #[bench]
 134      fn alloc_owned_big(b: &mut Bencher) {
 135          b.iter(|| {
 136              box [10, ..1000]
 137          })
 138      }
 139  }


libstd/rt/global_heap.rs:20:10-20:10 -fn- definition:
pub fn get_box_size(body_size: uint, body_align: uint) -> uint {
    let header_size = size_of::<raw::Box<()>>();
    let total_size = align_to(header_size, body_align) + body_size;
references:- 2
97: pub unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
98:     let total_size = get_box_size(size, align);
99:     let p = malloc_raw(total_size);
libstd/rt/local_heap.rs:
60:     pub fn alloc(&mut self, drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut Box {
61:         let total_size = global_heap::get_box_size(size, align);
62:         let alloc = self.memory_region.malloc(total_size);


libstd/rt/global_heap.rs:116:10-116:10 -fn- definition:
pub unsafe fn exchange_free(ptr: *u8) {
    free(ptr as *mut c_void);
}
references:- 6
112: pub unsafe fn exchange_free_(ptr: *u8) {
113:     exchange_free(ptr)
114: }
libstd/rt/local_heap.rs:
228:             self.live_allocations -= 1;
229:             global_heap::exchange_free(alloc as *u8)
230:         }
libstd/slice.rs:
331:                     }
332:                     exchange_free(ret as *u8);
333:                 });
--
770:         unsafe {
771:             exchange_free(self.allocation as *u8)
772:         }
libstd/rc.rs:
179:                 if self.weak() == 0 {
180:                     exchange_free(self.ptr as *u8)
181:                 }


libstd/rt/global_heap.rs:36:10-36:10 -fn- definition:
pub unsafe fn malloc_raw(size: uint) -> *mut u8 {
    // `malloc(0)` may allocate, but it may also return a null pointer
    // http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html
references:- 8
98:     let total_size = get_box_size(size, align);
99:     let p = malloc_raw(total_size);
libstd/rt/local_heap.rs:
189:         let alloc: *AllocHeader = unsafe {
190:             global_heap::malloc_raw(total_size) as *AllocHeader
191:         };
libstd/slice.rs:
307:         unsafe {
308:             let ret = malloc_raw(size) as *mut RawVec<()>;
libstd/vec.rs:
1495:         unsafe {
1496:             let ret = malloc_raw(size) as *mut RawVec<()>;
libstd/c_str.rs:
104:             let len = self.len() + 1;
105:             let buf = unsafe { malloc_raw(len) } as *mut libc::c_char;
106:             unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
--
329:         let self_len = self.len();
330:         let buf = malloc_raw(self_len + 1);
libstd/vec.rs:
98:             let size = capacity.checked_mul(&size_of::<T>()).expect("capacity overflow");
99:             let ptr = unsafe { malloc_raw(size) };
100:             Vec { len: 0, cap: capacity, ptr: ptr as *mut T }


libstd/rt/global_heap.rs:53:10-53:10 -fn- definition:
pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 {
    // `realloc(ptr, 0)` may allocate, but it may also return a null pointer
    // http://pubs.opengroup.org/onlinepubs/9699919799/functions/realloc.html
references:- 4
libstd/rt/local_heap.rs:
208:         let alloc: *AllocHeader = unsafe {
209:             global_heap::realloc_raw(orig_alloc as *mut u8,
210:                                      total_size) as *AllocHeader
libstd/vec.rs:
505:                 // Overflow check is unnecessary as the vector is already at least this large.
506:                 self.ptr = realloc_raw(self.ptr as *mut u8, self.len * size_of::<T>()) as *mut T;
507:             }
--
555:             unsafe {
556:                 self.ptr = realloc_raw(self.ptr as *mut u8, size) as *mut T;
557:             }