]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #41056 - michaelwoerister:central-defpath-hashes, r=nikomatsakis
authorCorey Farwell <coreyf@rwell.org>
Fri, 7 Apr 2017 13:20:05 +0000 (09:20 -0400)
committerGitHub <noreply@github.com>
Fri, 7 Apr 2017 13:20:05 +0000 (09:20 -0400)
Handle DefPath hashing centrally as part of DefPathTable (+ save work during SVH calculation)

In almost all cases where we construct a `DefPath`, we just hash it and throw it away again immediately.
With this PR, the compiler will immediately compute and store the hash for each `DefPath` as it is allocated. This way we
+ can get rid of any subsequent `DefPath` hash caching (e.g. the `DefPathHashes`),
+ don't need to allocate a transient `Vec` for holding the `DefPath` (although I'm always surprised how little these small, dynamic allocations seem to hurt performance), and
+ we don't hash `DefPath` prefixes over and over again.

That last part is because we construct the hash for `prefix::foo` by hashing `(hash(prefix), foo)` instead of hashing every component of prefix.

The last commit of this PR is pretty neat, I think:
```
The SVH (Strict Version Hash) of a crate is currently computed
by hashing the ICHes (Incremental Computation Hashes) of the
crate's HIR. This is fine, expect that for incr. comp. we compute
two ICH values for each HIR item, one for the complete item and
one that just includes the item's interface. The two hashes are
are needed for dependency tracking but if we are compiling
non-incrementally and just need the ICH values for the SVH,
one of them is enough, giving us the opportunity to save some
work in this case.
```

r? @nikomatsakis

This PR depends on https://github.com/rust-lang/rust/pull/40878 to be merged first (you can ignore the first commit for reviewing, that's just https://github.com/rust-lang/rust/pull/40878).

src/bootstrap/dist.rs
src/bootstrap/lib.rs
src/bootstrap/sanity.rs
src/librustc/middle/reachable.rs
src/librustc/ty/maps.rs
src/librustc_borrowck/borrowck/README.md
src/librustc_driver/driver.rs

index ec992b47a6e4b0d3865cc071a31fa0b05dd3552a..6472b1a928cafd92cd9298da7ca0ef060ac3ad5f 100644 (file)
@@ -433,29 +433,32 @@ pub fn rust_src(build: &Build) {
         copy(&build.src.join(item), &dst_src.join(item));
     }
 
-    // Get cargo-vendor installed, if it isn't already.
-    let mut has_cargo_vendor = false;
-    let mut cmd = Command::new(&build.cargo);
-    for line in output(cmd.arg("install").arg("--list")).lines() {
-        has_cargo_vendor |= line.starts_with("cargo-vendor ");
-    }
-    if !has_cargo_vendor {
+    // If we're building from git sources, we need to vendor a complete distribution.
+    if build.src_is_git {
+        // Get cargo-vendor installed, if it isn't already.
+        let mut has_cargo_vendor = false;
+        let mut cmd = Command::new(&build.cargo);
+        for line in output(cmd.arg("install").arg("--list")).lines() {
+            has_cargo_vendor |= line.starts_with("cargo-vendor ");
+        }
+        if !has_cargo_vendor {
+            let mut cmd = Command::new(&build.cargo);
+            cmd.arg("install")
+               .arg("--force")
+               .arg("--debug")
+               .arg("--vers").arg(CARGO_VENDOR_VERSION)
+               .arg("cargo-vendor")
+               .env("RUSTC", &build.rustc);
+            build.run(&mut cmd);
+        }
+
+        // Vendor all Cargo dependencies
         let mut cmd = Command::new(&build.cargo);
-        cmd.arg("install")
-           .arg("--force")
-           .arg("--debug")
-           .arg("--vers").arg(CARGO_VENDOR_VERSION)
-           .arg("cargo-vendor")
-           .env("RUSTC", &build.rustc);
+        cmd.arg("vendor")
+           .current_dir(&dst_src.join("src"));
         build.run(&mut cmd);
     }
 
-    // Vendor all Cargo dependencies
-    let mut cmd = Command::new(&build.cargo);
-    cmd.arg("vendor")
-       .current_dir(&dst_src.join("src"));
-    build.run(&mut cmd);
-
     // Create source tarball in rust-installer format
     let mut cmd = Command::new(SH_CMD);
     cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh")))
index 84254d7d6ae515b2f49afaa647e58aec2bcb2b63..8303a40bb6965fffc48bfa7ce4e2f3c8a485dbce 100644 (file)
@@ -162,6 +162,7 @@ pub struct Build {
     cxx: HashMap<String, gcc::Tool>,
     crates: HashMap<String, Crate>,
     is_sudo: bool,
+    src_is_git: bool,
 }
 
 #[derive(Debug)]
@@ -233,6 +234,7 @@ pub fn new(flags: Flags, config: Config) -> Build {
         };
         let rust_info = channel::GitInfo::new(&src);
         let cargo_info = channel::GitInfo::new(&src.join("cargo"));
+        let src_is_git = src.join(".git").exists();
 
         Build {
             flags: flags,
@@ -251,6 +253,7 @@ pub fn new(flags: Flags, config: Config) -> Build {
             lldb_version: None,
             lldb_python_dir: None,
             is_sudo: is_sudo,
+            src_is_git: src_is_git,
         }
     }
 
@@ -307,10 +310,7 @@ enum State {
             OutOfSync,
         }
 
-        if !self.config.submodules {
-            return
-        }
-        if fs::metadata(self.src.join(".git")).is_err() {
+        if !self.src_is_git || !self.config.submodules {
             return
         }
         let git = || {
index 235ce9360eff46a2004f6fcef30ebb7e64fe9a35..d1b235f4691dca7e476e4f862849b1f93bfe2c88 100644 (file)
@@ -65,7 +65,7 @@ pub fn check(build: &mut Build) {
 
     // If we've got a git directory we're gona need git to update
     // submodules and learn about various other aspects.
-    if fs::metadata(build.src.join(".git")).is_ok() {
+    if build.src_is_git {
         need_cmd("git".as_ref());
     }
 
index b0e39442af98c9997f9885949d3b2e56e07d3178..e5dd48534a6a136ad452e09c9a01226dd1f7196e 100644 (file)
 // makes all other generics or inline functions that it references
 // reachable as well.
 
-use dep_graph::DepNode;
 use hir::map as hir_map;
 use hir::def::Def;
-use hir::def_id::DefId;
+use hir::def_id::{DefId, CrateNum};
 use ty::{self, TyCtxt};
+use ty::maps::Providers;
 use middle::privacy;
 use session::config;
 use util::nodemap::{NodeSet, FxHashSet};
@@ -362,7 +362,11 @@ fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
 }
 
 pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet {
-    let _task = tcx.dep_graph.in_task(DepNode::Reachability);
+    ty::queries::reachable_set::get(tcx, DUMMY_SP, LOCAL_CRATE)
+}
+
+fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> NodeSet {
+    debug_assert!(crate_num == LOCAL_CRATE);
 
     let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
 
@@ -408,3 +412,10 @@ pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet {
     // Return the set of reachable symbols.
     reachable_context.reachable_symbols
 }
+
+pub fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        reachable_set,
+        ..*providers
+    };
+}
index 4a183191cef29c70c82920b26f1873cf04e37c73..823bdc9e092ac8290801a25a1b8b3e7ac83a61dd 100644 (file)
@@ -15,6 +15,7 @@
 use mir;
 use session::CompileResult;
 use ty::{self, CrateInherentImpls, Ty, TyCtxt};
+use util::nodemap::NodeSet;
 
 use rustc_data_structures::indexed_vec::IndexVec;
 use std::cell::{RefCell, RefMut};
@@ -209,6 +210,11 @@ fn describe(_: TyCtxt, _: CrateNum) -> String {
     }
 }
 
+impl<'tcx> QueryDescription for queries::reachable_set<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        format!("reachability")
+    }
+}
 
 macro_rules! define_maps {
     (<$tcx:tt>
@@ -440,6 +446,8 @@ fn default() -> Self {
     /// Performs the privacy check and computes "access levels".
     pub privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,
 
+    pub reachable_set: reachability_dep_node(CrateNum) -> NodeSet,
+
     pub mir_shims: mir_shim(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>
 }
 
@@ -451,6 +459,10 @@ fn crate_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
     DepNode::Coherence
 }
 
+fn reachability_dep_node(_: CrateNum) -> DepNode<DefId> {
+    DepNode::Reachability
+}
+
 fn mir_shim(instance: ty::InstanceDef) -> DepNode<DefId> {
     instance.dep_node()
 }
index 5cfbd59d3336881ecc0e6d450ae8198e338c3af4..034b7cbadd9c64a20cde15f215d00d01ac4be3cb 100644 (file)
@@ -347,7 +347,7 @@ ALIASABLE(*LV, MQ)                 // M-Deref-Unique
   ALIASABLE(LV, MQ)
 ```
 
-### Checking mutability of immutable pointer types
+### Checking aliasability of immutable pointer types
 
 Immutable pointer types like `&T` are aliasable, and hence can only be
 borrowed immutably:
@@ -357,7 +357,7 @@ ALIASABLE(*LV, imm)                // M-Deref-Borrowed-Imm
   TYPE(LV) = &Ty
 ```
 
-### Checking mutability of mutable pointer types
+### Checking aliasability of mutable pointer types
 
 `&mut T` can be frozen, so it is acceptable to borrow it as either imm or mut:
 
@@ -633,7 +633,7 @@ Here is a concrete example of a bug this rule prevents:
 
 ```rust
 // Test region-reborrow-from-shorter-mut-ref.rs:
-fn copy_pointer<'a,'b,T>(x: &'a mut &'b mut T) -> &'b mut T {
+fn copy_borrowed_ptr<'a,'b,T>(x: &'a mut &'b mut T) -> &'b mut T {
     &mut **p // ERROR due to clause (1)
 }
 fn main() {
index 4e6c919c7f5691ed1d05350c1bb15ef07f45c05f..bdb05d06b0b10646b8b75769abe776043d0d9b7e 100644 (file)
@@ -893,6 +893,7 @@ macro_rules! try_with_f {
     rustc_privacy::provide(&mut local_providers);
     typeck::provide(&mut local_providers);
     ty::provide(&mut local_providers);
+    reachable::provide(&mut local_providers);
 
     let mut extern_providers = ty::maps::Providers::default();
     cstore::provide(&mut extern_providers);