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.
This commit is contained in:
Ariel Ben-Yehuda
2017-04-20 15:08:41 +03:00
committed by Ariel Ben-Yehuda
parent acd0e40b86
commit ece6c8434b
11 changed files with 85 additions and 23 deletions

View File

@@ -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.

View File

@@ -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)]

View File

@@ -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.
///