Skip to content

Commit 252d3da

Browse files
committed
Auto merge of #41469 - arielb1:rustc-spring-cleaning, r=eddyb
Performance audit, Spring 2017 Fix up some quite important performance "surprises" I've found running callgrind on rustc.
2 parents cb4065b + a660ad8 commit 252d3da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+322
-185
lines changed

src/liballoc/heap.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
issue = "27700")]
1717

1818
use core::{isize, usize};
19-
#[cfg(not(test))]
2019
use core::intrinsics::{min_align_of_val, size_of_val};
2120

2221
#[allow(improper_ctypes)]
@@ -158,10 +157,9 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
158157
}
159158
}
160159

161-
#[cfg(not(test))]
162-
#[lang = "box_free"]
160+
#[cfg_attr(not(test), lang = "box_free")]
163161
#[inline]
164-
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
162+
pub(crate) unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
165163
let size = size_of_val(&*ptr);
166164
let align = min_align_of_val(&*ptr);
167165
// We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
#![feature(needs_allocator)]
8888
#![feature(optin_builtin_traits)]
8989
#![feature(placement_in_syntax)]
90+
#![cfg_attr(stage0, feature(pub_restricted))]
9091
#![feature(shared)]
9192
#![feature(staged_api)]
9293
#![feature(unboxed_closures)]

src/liballoc/rc.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ use core::ops::CoerceUnsized;
239239
use core::ptr::{self, Shared};
240240
use core::convert::From;
241241

242-
use heap::deallocate;
242+
use heap::{allocate, deallocate, box_free};
243243
use raw_vec::RawVec;
244244

245245
struct RcBox<T: ?Sized> {
@@ -248,7 +248,6 @@ struct RcBox<T: ?Sized> {
248248
value: T,
249249
}
250250

251-
252251
/// A single-threaded reference-counting pointer.
253252
///
254253
/// See the [module-level documentation](./index.html) for more details.
@@ -438,6 +437,38 @@ impl Rc<str> {
438437
}
439438
}
440439

440+
impl<T> Rc<[T]> {
441+
/// Constructs a new `Rc<[T]>` from a `Box<[T]>`.
442+
#[doc(hidden)]
443+
#[unstable(feature = "rustc_private",
444+
reason = "for internal use in rustc",
445+
issue = "0")]
446+
pub fn __from_array(value: Box<[T]>) -> Rc<[T]> {
447+
unsafe {
448+
let ptr: *mut RcBox<[T]> =
449+
mem::transmute([mem::align_of::<RcBox<[T; 1]>>(), value.len()]);
450+
// FIXME(custom-DST): creating this invalid &[T] is dubiously defined,
451+
// we should have a better way of getting the size/align
452+
// of a DST from its unsized part.
453+
let ptr = allocate(size_of_val(&*ptr), align_of_val(&*ptr));
454+
let ptr: *mut RcBox<[T]> = mem::transmute([ptr as usize, value.len()]);
455+
456+
// Initialize the new RcBox.
457+
ptr::write(&mut (*ptr).strong, Cell::new(1));
458+
ptr::write(&mut (*ptr).weak, Cell::new(1));
459+
ptr::copy_nonoverlapping(
460+
value.as_ptr(),
461+
&mut (*ptr).value as *mut [T] as *mut T,
462+
value.len());
463+
464+
// Free the original allocation without freeing its (moved) contents.
465+
box_free(Box::into_raw(value));
466+
467+
Rc { ptr: Shared::new(ptr as *const _) }
468+
}
469+
}
470+
}
471+
441472
impl<T: ?Sized> Rc<T> {
442473
/// Creates a new [`Weak`][weak] pointer to this value.
443474
///

src/librustc/infer/freshen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
9999
ty::ReEmpty |
100100
ty::ReErased => {
101101
// replace all free regions with 'erased
102-
self.tcx().mk_region(ty::ReErased)
102+
self.tcx().types.re_erased
103103
}
104104
}
105105
}

src/librustc/infer/region_inference/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
948948
} else {
949949
// otherwise, we don't know what the free region is,
950950
// so we must conservatively say the LUB is static:
951-
self.tcx.mk_region(ReStatic)
951+
self.tcx.types.re_static
952952
}
953953
}
954954

@@ -971,7 +971,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
971971
if a == b {
972972
a
973973
} else {
974-
self.tcx.mk_region(ReStatic)
974+
self.tcx.types.re_static
975975
}
976976
}
977977
}
@@ -1018,7 +1018,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
10181018

10191019
fn construct_var_data(&self) -> Vec<VarValue<'tcx>> {
10201020
(0..self.num_vars() as usize)
1021-
.map(|_| Value(self.tcx.mk_region(ty::ReEmpty)))
1021+
.map(|_| Value(self.tcx.types.re_empty))
10221022
.collect()
10231023
}
10241024

@@ -1493,7 +1493,7 @@ fn lookup<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
14931493
-> &'tcx ty::Region {
14941494
match values[rid.index as usize] {
14951495
Value(r) => r,
1496-
ErrorValue => tcx.mk_region(ReStatic), // Previously reported error.
1496+
ErrorValue => tcx.types.re_static, // Previously reported error.
14971497
}
14981498
}
14991499

src/librustc/middle/cstore.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,13 @@ pub trait CrateStore {
188188
fn visibility(&self, def: DefId) -> ty::Visibility;
189189
fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
190190
fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
191-
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
191+
fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]>;
192192
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
193193

194194
// trait info
195195
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
196196

197197
// impl info
198-
fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity;
199198
fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
200199

201200
// trait/impl-item info
@@ -323,14 +322,13 @@ impl CrateStore for DummyCrateStore {
323322
}
324323
fn item_generics_cloned(&self, def: DefId) -> ty::Generics
325324
{ bug!("item_generics_cloned") }
326-
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
325+
fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]> { bug!("item_attrs") }
327326
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
328327

329328
// trait info
330329
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
331330

332331
// impl info
333-
fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity { bug!("impl_polarity") }
334332
fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
335333

336334
// trait/impl-item info

src/librustc/middle/expr_use_visitor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
426426

427427
hir::ExprMatch(ref discr, ref arms, _) => {
428428
let discr_cmt = return_if_err!(self.mc.cat_expr(&discr));
429-
let r = self.tcx().mk_region(ty::ReEmpty);
429+
let r = self.tcx().types.re_empty;
430430
self.borrow_expr(&discr, r, ty::ImmBorrow, MatchDiscriminant);
431431

432432
// treatment of the discriminant is handled while walking the arms.

src/librustc/middle/lang_items.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,10 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
223223

224224
pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
225225
for attribute in attrs {
226-
match attribute.value_str() {
227-
Some(value) if attribute.check_name("lang") => return Some(value),
228-
_ => {}
226+
if attribute.check_name("lang") {
227+
if let Some(value) = attribute.value_str() {
228+
return Some(value)
229+
}
229230
}
230231
}
231232

src/librustc/middle/mem_categorization.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -871,8 +871,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
871871
// we can promote to a constant, otherwise equal to enclosing temp
872872
// lifetime.
873873
let (re, old_re) = if promotable {
874-
(self.tcx().mk_region(ty::ReStatic),
875-
self.tcx().mk_region(ty::ReStatic))
874+
(self.tcx().types.re_static,
875+
self.tcx().types.re_static)
876876
} else {
877877
self.temporary_scope(id)
878878
};

src/librustc/traits/fulfill.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
443443
// Otherwise, we have something of the form
444444
// `for<'a> T: 'a where 'a not in T`, which we can treat as `T: 'static`.
445445
Some(t_a) => {
446-
let r_static = selcx.tcx().mk_region(ty::ReStatic);
446+
let r_static = selcx.tcx().types.re_static;
447447
register_region_obligation(t_a, r_static,
448448
obligation.cause.clone(),
449449
region_obligations);

src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ pub fn get_vtable_methods<'a, 'tcx>(
629629
// the method may have some early-bound lifetimes, add
630630
// regions for those
631631
let substs = Substs::for_item(tcx, def_id,
632-
|_, _| tcx.mk_region(ty::ReErased),
632+
|_, _| tcx.types.re_erased,
633633
|def, _| trait_ref.substs().type_for_def(def));
634634

635635
// the trait type may have higher-ranked lifetimes in it;

src/librustc/traits/select.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -943,17 +943,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
943943
debug!("Retaining candidate #{}/{}: {:?}",
944944
i, candidates.len(), candidates[i]);
945945
i += 1;
946+
947+
// If there are *STILL* multiple candidates, give up
948+
// and report ambiguity.
949+
if i > 1 {
950+
debug!("multiple matches, ambig");
951+
return Ok(None);
952+
}
946953
}
947954
}
948955
}
949956

950-
// If there are *STILL* multiple candidates, give up and
951-
// report ambiguity.
952-
if candidates.len() > 1 {
953-
debug!("multiple matches, ambig");
954-
return Ok(None);
955-
}
956-
957957
// If there are *NO* candidates, then there are no impls --
958958
// that we know of, anyway. Note that in the case where there
959959
// are unbound type variables within the obligation, it might

src/librustc/ty/context.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ pub struct CommonTypes<'tcx> {
190190
pub f64: Ty<'tcx>,
191191
pub never: Ty<'tcx>,
192192
pub err: Ty<'tcx>,
193+
194+
pub re_empty: &'tcx Region,
195+
pub re_static: &'tcx Region,
196+
pub re_erased: &'tcx Region,
193197
}
194198

195199
#[derive(RustcEncodable, RustcDecodable)]
@@ -360,6 +364,14 @@ impl<'tcx> TypeckTables<'tcx> {
360364
impl<'tcx> CommonTypes<'tcx> {
361365
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
362366
let mk = |sty| interners.intern_ty(sty, None);
367+
let mk_region = |r| {
368+
if let Some(r) = interners.region.borrow().get(&r) {
369+
return r.0;
370+
}
371+
let r = interners.arena.alloc(r);
372+
interners.region.borrow_mut().insert(Interned(r));
373+
&*r
374+
};
363375
CommonTypes {
364376
bool: mk(TyBool),
365377
char: mk(TyChar),
@@ -379,6 +391,10 @@ impl<'tcx> CommonTypes<'tcx> {
379391
u128: mk(TyUint(ast::UintTy::U128)),
380392
f32: mk(TyFloat(ast::FloatTy::F32)),
381393
f64: mk(TyFloat(ast::FloatTy::F64)),
394+
395+
re_empty: mk_region(Region::ReEmpty),
396+
re_static: mk_region(Region::ReStatic),
397+
re_erased: mk_region(Region::ReErased),
382398
}
383399
}
384400
}
@@ -1232,7 +1248,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12321248
}
12331249

12341250
pub fn mk_static_str(self) -> Ty<'tcx> {
1235-
self.mk_imm_ref(self.mk_region(ty::ReStatic), self.mk_str())
1251+
self.mk_imm_ref(self.types.re_static, self.mk_str())
12361252
}
12371253

12381254
pub fn mk_adt(self, def: &'tcx AdtDef, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {

src/librustc/ty/fold.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
410410
pub fn erase_late_bound_regions<T>(self, value: &Binder<T>) -> T
411411
where T : TypeFoldable<'tcx>
412412
{
413-
self.replace_late_bound_regions(value, |_| self.mk_region(ty::ReErased)).0
413+
self.replace_late_bound_regions(value, |_| self.types.re_erased).0
414414
}
415415

416416
/// Rewrite any late-bound regions so that they are anonymous. Region numbers are
@@ -538,7 +538,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
538538
// whenever a substitution occurs.
539539
match *r {
540540
ty::ReLateBound(..) => r,
541-
_ => self.tcx().mk_region(ty::ReErased)
541+
_ => self.tcx().types.re_erased
542542
}
543543
}
544544
}
@@ -565,6 +565,22 @@ pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region {
565565
}
566566
}
567567

568+
pub fn shift_region_ref<'a, 'gcx, 'tcx>(
569+
tcx: TyCtxt<'a, 'gcx, 'tcx>,
570+
region: &'tcx ty::Region,
571+
amount: u32)
572+
-> &'tcx ty::Region
573+
{
574+
match region {
575+
&ty::ReLateBound(debruijn, br) if amount > 0 => {
576+
tcx.mk_region(ty::ReLateBound(debruijn.shifted(amount), br))
577+
}
578+
_ => {
579+
region
580+
}
581+
}
582+
}
583+
568584
pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
569585
amount: u32, value: &T) -> T
570586
where T: TypeFoldable<'tcx>
@@ -573,7 +589,7 @@ pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
573589
value, amount);
574590

575591
value.fold_with(&mut RegionFolder::new(tcx, &mut false, &mut |region, _current_depth| {
576-
tcx.mk_region(shift_region(*region, amount))
592+
shift_region_ref(tcx, region, amount)
577593
}))
578594
}
579595

src/librustc/ty/instance.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ use hir::def_id::DefId;
1313
use ty::{self, Ty, TypeFoldable, Substs};
1414
use util::ppaux;
1515

16-
use std::borrow::Cow;
1716
use std::fmt;
18-
use syntax::ast;
19-
2017

2118
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
2219
pub struct Instance<'tcx> {
@@ -59,7 +56,7 @@ impl<'tcx> InstanceDef<'tcx> {
5956
}
6057

6158
#[inline]
62-
pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Cow<'tcx, [ast::Attribute]> {
59+
pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> {
6360
tcx.get_attrs(self.def_id())
6461
}
6562

0 commit comments

Comments
 (0)