diff options
| author | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2017-04-20 15:08:41 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-04-22 21:00:50 +0300 |
| commit | ece6c8434bc4eba1d3addfa4d5900264e55395fc (patch) | |
| tree | 5fe4185c3ba908c2eb5c9660111eb18f9d4918f1 /src/liballoc | |
| parent | acd0e40b86d718d339b13f594242575c28e966f7 (diff) | |
| download | rust-ece6c8434bc4eba1d3addfa4d5900264e55395fc.tar.gz rust-ece6c8434bc4eba1d3addfa4d5900264e55395fc.zip | |
cache attributes of items from foreign crates
this avoids parsing item attributes on each call to `item_attrs`, which takes off 33% (!) of translation time and 50% (!) of trans-item collection time.
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/heap.rs | 6 | ||||
| -rw-r--r-- | src/liballoc/lib.rs | 1 | ||||
| -rw-r--r-- | src/liballoc/rc.rs | 35 |
3 files changed, 36 insertions, 6 deletions
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 08a0b2a6d00..056af13016c 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -16,7 +16,6 @@ issue = "27700")] use core::{isize, usize}; -#[cfg(not(test))] use core::intrinsics::{min_align_of_val, size_of_val}; #[allow(improper_ctypes)] @@ -158,10 +157,9 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { } } -#[cfg(not(test))] -#[lang = "box_free"] +#[cfg_attr(not(test), lang = "box_free")] #[inline] -unsafe fn box_free<T: ?Sized>(ptr: *mut T) { +pub(crate) unsafe fn box_free<T: ?Sized>(ptr: *mut T) { let size = size_of_val(&*ptr); let align = min_align_of_val(&*ptr); // We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary. diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0c01eabd593..c70d82392f9 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -87,6 +87,7 @@ #![feature(needs_allocator)] #![feature(optin_builtin_traits)] #![feature(placement_in_syntax)] +#![cfg_attr(stage0, feature(pub_restricted))] #![feature(shared)] #![feature(staged_api)] #![feature(unboxed_closures)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index fed718e9be4..69e5351cad5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -239,7 +239,7 @@ use core::ops::CoerceUnsized; use core::ptr::{self, Shared}; use core::convert::From; -use heap::deallocate; +use heap::{allocate, deallocate, box_free}; use raw_vec::RawVec; struct RcBox<T: ?Sized> { @@ -248,7 +248,6 @@ struct RcBox<T: ?Sized> { value: T, } - /// A single-threaded reference-counting pointer. /// /// See the [module-level documentation](./index.html) for more details. @@ -438,6 +437,38 @@ impl Rc<str> { } } +impl<T> Rc<[T]> { + /// Constructs a new `Rc<[T]>` from a `Box<[T]>`. + #[doc(hidden)] + #[unstable(feature = "rustc_private", + reason = "for internal use in rustc", + issue = "0")] + pub fn __from_array(value: Box<[T]>) -> Rc<[T]> { + unsafe { + let ptr: *mut RcBox<[T]> = + mem::transmute([mem::align_of::<RcBox<[T; 1]>>(), value.len()]); + // FIXME(custom-DST): creating this invalid &[T] is dubiously defined, + // we should have a better way of getting the size/align + // of a DST from its unsized part. + let ptr = allocate(size_of_val(&*ptr), align_of_val(&*ptr)); + let ptr: *mut RcBox<[T]> = mem::transmute([ptr as usize, value.len()]); + + // Initialize the new RcBox. + ptr::write(&mut (*ptr).strong, Cell::new(1)); + ptr::write(&mut (*ptr).weak, Cell::new(1)); + ptr::copy_nonoverlapping( + value.as_ptr(), + &mut (*ptr).value as *mut [T] as *mut T, + value.len()); + + // Free the original allocation without freeing its (moved) contents. + box_free(Box::into_raw(value)); + + Rc { ptr: Shared::new(ptr as *const _) } + } + } +} + impl<T: ?Sized> Rc<T> { /// Creates a new [`Weak`][weak] pointer to this value. /// |
