-
-
Notifications
You must be signed in to change notification settings - Fork 15k
Computing crate_hash from metadata encoding instead of HIR (implements #94878) #154724
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,11 +2,14 @@ use std::borrow::Borrow; | |
| use std::collections::hash_map::Entry; | ||
| use std::fs::File; | ||
| use std::io::{Read, Seek, Write}; | ||
| use std::ops::Deref; | ||
| use std::path::{Path, PathBuf}; | ||
| use std::sync::Arc; | ||
|
|
||
| use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; | ||
| use rustc_data_structures::memmap::{Mmap, MmapMut}; | ||
| use rustc_data_structures::owned_slice::slice_owned; | ||
| use rustc_data_structures::stable_hash::{StableHash, StableHasher}; | ||
| use rustc_data_structures::sync::{par_for_each_in, par_join}; | ||
| use rustc_data_structures::temp_dir::MaybeTempDir; | ||
| use rustc_data_structures::thousands::usize_with_underscores; | ||
|
|
@@ -25,7 +28,7 @@ use rustc_middle::ty::AssocContainer; | |
| use rustc_middle::ty::codec::TyEncoder; | ||
| use rustc_middle::ty::fast_reject::{self, TreatParams}; | ||
| use rustc_middle::{bug, span_bug}; | ||
| use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque}; | ||
| use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; | ||
| use rustc_session::config::mitigation_coverage::DeniedPartialMitigation; | ||
| use rustc_session::config::{CrateType, OptLevel, TargetModifier}; | ||
| use rustc_span::hygiene::HygieneEncodeContext; | ||
|
|
@@ -40,7 +43,7 @@ use crate::errors::{FailCreateFileEncoder, FailWriteFile}; | |
| use crate::rmeta::*; | ||
|
|
||
| pub(super) struct EncodeContext<'a, 'tcx> { | ||
| opaque: opaque::FileEncoder, | ||
| opaque: opaque::FileEncoder<'a>, | ||
| tcx: TyCtxt<'tcx>, | ||
| feat: &'tcx rustc_feature::Features, | ||
| tables: TableBuilders, | ||
|
|
@@ -718,13 +721,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { | |
| let denied_partial_mitigations = stat!("denied-partial-mitigations", || self | ||
| .encode_enabled_denied_partial_mitigations()); | ||
|
|
||
| let hash = Svh::new(self.opaque.hash()); | ||
| tcx.untracked().local_crate_hash.set(hash).expect("local_crate_hash set twice"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we make |
||
|
|
||
| let root = stat!("final", || { | ||
| let attrs = tcx.hir_krate_attrs(); | ||
| self.lazy(CrateRoot { | ||
| header: CrateHeader { | ||
| name: tcx.crate_name(LOCAL_CRATE), | ||
| triple: tcx.sess.opts.target_triple.clone(), | ||
| hash: tcx.crate_hash(LOCAL_CRATE), | ||
| hash, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this the best position to put the hash? Should we put it close to the header, after the start position? This would let us finish encoding everything and make partial decoding easier. |
||
| is_proc_macro_crate: proc_macro_data.is_some(), | ||
| is_stub: false, | ||
| }, | ||
|
|
@@ -2428,22 +2434,6 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { | |
| // there's no need to do dep-graph tracking for any of it. | ||
| tcx.dep_graph.assert_ignored(); | ||
|
|
||
| // Generate the metadata stub manually, as that is a small file compared to full metadata. | ||
| if let Some(ref_path) = ref_path { | ||
| let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub"); | ||
|
|
||
| with_encode_metadata_header(tcx, ref_path, |ecx| { | ||
| let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader { | ||
| name: tcx.crate_name(LOCAL_CRATE), | ||
| triple: tcx.sess.opts.target_triple.clone(), | ||
| hash: tcx.crate_hash(LOCAL_CRATE), | ||
| is_proc_macro_crate: false, | ||
| is_stub: true, | ||
| }); | ||
| header.position.get() | ||
| }) | ||
| } | ||
|
|
||
| let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata"); | ||
|
|
||
| let dep_node = tcx.metadata_dep_node(); | ||
|
|
@@ -2462,6 +2452,31 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { | |
| Ok(_) => {} | ||
| Err(err) => tcx.dcx().emit_fatal(FailCreateFileEncoder { err }), | ||
| }; | ||
|
|
||
| // Read the SVH from the old metadata header. | ||
| let file = std::fs::File::open(&source_file).unwrap(); | ||
| let mmap = unsafe { Mmap::map(file) }.unwrap(); | ||
| let owned = slice_owned(mmap, Deref::deref); | ||
| let blob = MetadataBlob::new(owned); | ||
| let header = blob.expect("file already created").get_header(); | ||
| tcx.untracked().local_crate_hash.set(header.hash).expect("local_crate_hash set twice"); | ||
|
|
||
| // Generate the metadata stub manually, as that is a small file compared to full metadata. | ||
| if let Some(ref_path) = ref_path { | ||
| let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub"); | ||
|
|
||
| with_encode_metadata_header(tcx, ref_path, |ecx| { | ||
| let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader { | ||
| name: tcx.crate_name(LOCAL_CRATE), | ||
| triple: tcx.sess.opts.target_triple.clone(), | ||
| hash: tcx.crate_hash(LOCAL_CRATE), | ||
| is_proc_macro_crate: false, | ||
| is_stub: true, | ||
| }); | ||
| header.position.get() | ||
| }) | ||
| } | ||
|
|
||
| return; | ||
| }; | ||
|
|
||
|
|
@@ -2503,14 +2518,40 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { | |
| }, | ||
| None, | ||
| ); | ||
|
|
||
| // Generate the metadata stub manually, as that is a small file compared to full metadata. | ||
| if let Some(ref_path) = ref_path { | ||
| let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub"); | ||
|
|
||
| with_encode_metadata_header(tcx, ref_path, |ecx| { | ||
| let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader { | ||
| name: tcx.crate_name(LOCAL_CRATE), | ||
| triple: tcx.sess.opts.target_triple.clone(), | ||
| hash: tcx.crate_hash(LOCAL_CRATE), | ||
| is_proc_macro_crate: false, | ||
| is_stub: true, | ||
| }); | ||
| header.position.get() | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| fn with_encode_metadata_header( | ||
| tcx: TyCtxt<'_>, | ||
| path: &Path, | ||
| f: impl FnOnce(&mut EncodeContext<'_, '_>) -> usize, | ||
| ) { | ||
| let mut encoder = opaque::FileEncoder::new(path) | ||
| let mut stable_hasher = StableHasher::new(); | ||
| let krate = tcx.hir_crate(()); | ||
| let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash"); | ||
| tcx.with_stable_hashing_context(|mut hcx| { | ||
| // Add dep_tracking_hash to ensure the SVH changes when any tracked flag changes. | ||
| tcx.sess.opts.dep_tracking_hash(true).stable_hash(&mut hcx, &mut stable_hasher); | ||
| // Add HIR hash for untracked elements, e.g. DefKind::GlobalAsm. | ||
| hir_body_hash.stable_hash(&mut hcx, &mut stable_hasher); | ||
| }); | ||
|
|
||
| let mut encoder = opaque::FileEncoder::new(path, &mut stable_hasher) | ||
| .unwrap_or_else(|err| tcx.dcx().emit_fatal(FailCreateFileEncoder { err })); | ||
| encoder.emit_raw_bytes(METADATA_HEADER); | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where?
View changes since the review