Skip to content

Commit 1fe48e6

Browse files
moar checkpointing
1 parent 4e5405f commit 1fe48e6

10 files changed

Lines changed: 172 additions & 133 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4288,7 +4288,6 @@ dependencies = [
42884288
"rustc_macros",
42894289
"rustc_middle",
42904290
"rustc_proc_macro",
4291-
"rustc_query_system",
42924291
"rustc_serialize",
42934292
"rustc_session",
42944293
"rustc_span",

compiler/rustc_interface/src/passes.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,13 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
951951
let definitions = FreezeLock::new(Definitions::new(stable_crate_id));
952952

953953
let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default());
954-
let untracked =
955-
Untracked { cstore, source_span: AppendOnlyIndexVec::new(), definitions, stable_crate_ids };
954+
let untracked = Untracked {
955+
cstore,
956+
source_span: AppendOnlyIndexVec::new(),
957+
definitions,
958+
stable_crate_ids,
959+
local_crate_hash: OnceLock::new(),
960+
};
956961

957962
// We're constructing the HIR here; we don't care what we will
958963
// read, since we haven't even constructed the *input* to

compiler/rustc_metadata/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ rustc_middle = { path = "../rustc_middle" }
2525
# We must use the proc_macro version that we will compile proc-macros against,
2626
# not the one from our own sysroot.
2727
rustc_proc_macro = { path = "../rustc_proc_macro" }
28-
rustc_query_system = { path = "../rustc_query_system" }
2928
rustc_serialize = { path = "../rustc_serialize" }
3029
rustc_session = { path = "../rustc_session" }
3130
rustc_span = { path = "../rustc_span" }

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,4 +740,101 @@ fn provide_cstore_hooks(providers: &mut Providers) {
740740
cdata.imported_source_file(tcx, file_index as u32);
741741
}
742742
};
743+
744+
providers.queries.crate_hash = |tcx: TyCtxt<'_>, _: LocalCrate| {
745+
*tcx.untracked()
746+
.local_crate_hash
747+
.get()
748+
.expect("crate_hash(LOCAL_CRATE) called before metadata encoding")
749+
};
743750
}
751+
752+
/*pub(super) fn crate_hash(tcx: TyCtxt<'_>, cnum: rustc_hir::def_id::CrateNum) -> Svh {
753+
let cstore = CStore::from_tcx(tcx);
754+
let crate_data = cstore.get_crate_data(cnum);
755+
crate_data.root.header.hash
756+
757+
let upstream_crates = upstream_crates(tcx);
758+
759+
let resolutions = tcx.resolutions(());
760+
761+
// We hash the final, remapped names of all local source files so we
762+
// don't have to include the path prefix remapping commandline args.
763+
// If we included the full mapping in the SVH, we could only have
764+
// reproducible builds by compiling from the same directory. So we just
765+
// hash the result of the mapping instead of the mapping itself.
766+
let mut source_file_names: Vec<_> = tcx
767+
.sess
768+
.source_map()
769+
.files()
770+
.iter()
771+
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
772+
.map(|source_file| source_file.stable_id)
773+
.collect();
774+
775+
source_file_names.sort_unstable();
776+
777+
// We have to take care of debugger visualizers explicitly. The HIR (and
778+
// thus `hir_body_hash`) contains the #[debugger_visualizer] attributes but
779+
// these attributes only store the file path to the visualizer file, not
780+
// their content. Yet that content is exported into crate metadata, so any
781+
// changes to it need to be reflected in the crate hash.
782+
let debugger_visualizers: Vec<_> = tcx
783+
.debugger_visualizers(LOCAL_CRATE)
784+
.iter()
785+
// We ignore the path to the visualizer file since it's not going to be
786+
// encoded in crate metadata and we already hash the full contents of
787+
// the file.
788+
.map(DebuggerVisualizerFile::path_erased)
789+
.collect();
790+
791+
let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| {
792+
let mut stable_hasher = StableHasher::new();
793+
metadata_hash.hash_stable(&mut hcx, &mut stable_hasher);
794+
upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
795+
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
796+
debugger_visualizers.hash_stable(&mut hcx, &mut stable_hasher);
797+
if tcx.sess.opts.incremental.is_some() {
798+
let definitions = tcx.untracked().definitions.freeze();
799+
let mut owner_spans: Vec<_> = tcx
800+
.hir_crate_items(())
801+
.definitions()
802+
.map(|def_id| {
803+
let def_path_hash = definitions.def_path_hash(def_id);
804+
let span = tcx.source_span(def_id);
805+
debug_assert_eq!(span.parent(), None);
806+
(def_path_hash, span)
807+
})
808+
.collect();
809+
owner_spans.sort_unstable_by_key(|bn| bn.0);
810+
owner_spans.hash_stable(&mut hcx, &mut stable_hasher);
811+
}
812+
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
813+
tcx.stable_crate_id(LOCAL_CRATE).hash_stable(&mut hcx, &mut stable_hasher);
814+
// Hash visibility information since it does not appear in HIR.
815+
// FIXME: Figure out how to remove `visibilities_for_hashing` by hashing visibilities on
816+
// the fly in the resolver, storing only their accumulated hash in `ResolverGlobalCtxt`,
817+
// and combining it with other hashes here.
818+
resolutions.visibilities_for_hashing.hash_stable(&mut hcx, &mut stable_hasher);
819+
with_metavar_spans(|mspans| {
820+
mspans.freeze_and_get_read_spans().hash_stable(&mut hcx, &mut stable_hasher);
821+
});
822+
stable_hasher.finish()
823+
});
824+
825+
Svh::new(crate_hash)
826+
}
827+
828+
fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
829+
let mut upstream_crates: Vec<_> = tcx
830+
.crates(())
831+
.iter()
832+
.map(|&cnum| {
833+
let stable_crate_id = tcx.stable_crate_id(cnum);
834+
let hash = tcx.crate_hash(cnum);
835+
(stable_crate_id, hash)
836+
})
837+
.collect();
838+
upstream_crates.sort_unstable_by_key(|&(stable_crate_id, _)| stable_crate_id);
839+
upstream_crates
840+
}*/

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ use std::io::{Read, Seek, Write};
55
use std::path::{Path, PathBuf};
66
use std::sync::Arc;
77

8+
use rustc_data_structures::fingerprint::Fingerprint;
9+
//use rustc_data_structures::Svh;
810
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
911
use rustc_data_structures::memmap::{Mmap, MmapMut};
1012
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
11-
use rustc_data_structures::sync::{join, par_for_each_in};
13+
use rustc_data_structures::sync::{par_for_each_in, par_join};
1214
use rustc_data_structures::temp_dir::MaybeTempDir;
1315
use rustc_data_structures::thousands::usize_with_underscores;
1416
use rustc_feature::Features;
@@ -19,6 +21,7 @@ use rustc_hir::definitions::DefPathData;
1921
use rustc_hir::find_attr;
2022
use rustc_hir_pretty::id_to_string;
2123
use rustc_middle::dep_graph::WorkProductId;
24+
use rustc_middle::ich::StableHashingContext;
2225
use rustc_middle::middle::dependency_format::Linkage;
2326
use rustc_middle::mir::interpret;
2427
use rustc_middle::query::Providers;
@@ -27,7 +30,6 @@ use rustc_middle::ty::AssocContainer;
2730
use rustc_middle::ty::codec::TyEncoder;
2831
use rustc_middle::ty::fast_reject::{self, TreatParams};
2932
use rustc_middle::{bug, span_bug};
30-
use rustc_query_system::ich::StableHashingContext;
3133
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque};
3234
use rustc_session::config::{CrateType, OptLevel, TargetModifier};
3335
use rustc_span::hygiene::HygieneEncodeContext;
@@ -42,7 +44,7 @@ use crate::errors::{FailCreateFileEncoder, FailWriteFile};
4244
use crate::rmeta::*;
4345

4446
// Struct to enable split borrows.
45-
struct ContextEncoder<'a> {
47+
pub(super) struct ContextEncoder<'a> {
4648
opaque: opaque::FileEncoder,
4749
stable_hasher: StableHasher,
4850
hcx: StableHashingContext<'a>,
@@ -120,9 +122,17 @@ impl<'a> Encoder for ContextEncoder<'a> {
120122

121123
impl<'a> ContextEncoder<'a> {
122124
#[inline]
123-
fn position(&self) -> usize {
125+
pub(super) fn position(&self) -> usize {
124126
self.opaque.position()
125127
}
128+
129+
pub(super) fn write_m_with<const N: usize>(&mut self, b: &[u8; N], m: usize) {
130+
(b[..m]).hash_stable(&mut self.hcx, &mut self.stable_hasher);
131+
self.opaque.write_with(|dest| {
132+
*dest = *b;
133+
m
134+
});
135+
}
126136
}
127137

128138
macro_rules! encoder_methods {
@@ -194,11 +204,6 @@ impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> {
194204
}
195205

196206
fn encode_def_id(&mut self, def_id: DefId) {
197-
HashStable::<StableHashingContext<'_>>::hash_stable(
198-
&def_id,
199-
&mut self.encoder.hcx,
200-
&mut self.encoder.stable_hasher,
201-
);
202207
def_id.krate.encode(self);
203208
def_id.index.encode(self);
204209
}
@@ -231,17 +236,15 @@ impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> {
231236
if offset < last_location {
232237
let needed = bytes_needed(offset);
233238
SpanTag::indirect(true, needed as u8).encode(self);
234-
self.encoder.opaque.write_with(|dest| {
235-
*dest = offset.to_le_bytes();
236-
needed
237-
});
239+
self.encoder.write_m_with(&offset.to_le_bytes(), needed);
240+
offset.hash_stable(&mut self.encoder.hcx, &mut self.encoder.stable_hasher);
238241
} else {
239242
let needed = bytes_needed(last_location);
240243
SpanTag::indirect(false, needed as u8).encode(self);
241-
self.encoder.opaque.write_with(|dest| {
242-
*dest = last_location.to_le_bytes();
243-
needed
244-
});
244+
self.encoder.write_m_with(&last_location.to_le_bytes(), needed);
245+
246+
last_location
247+
.hash_stable(&mut self.encoder.hcx, &mut self.encoder.stable_hasher);
245248
}
246249
}
247250
Entry::Vacant(v) => {
@@ -648,7 +651,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
648651
adapted.set_some(on_disk_index, self.lazy(adapted_source_file));
649652
}
650653

651-
adapted.encode(&mut self.encoder.opaque)
654+
adapted.encode(&mut self.encoder)
652655
}
653656

654657
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
@@ -732,7 +735,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
732735
// encode_def_path_table.
733736
let proc_macro_data = stat!("proc-macro-data", || self.encode_proc_macros());
734737

735-
let tables = stat!("tables", || self.tables.encode(&mut self.encoder.opaque));
738+
let tables = stat!("tables", || self.tables.encode(&mut self.encoder));
736739

737740
let debugger_visualizers =
738741
stat!("debugger-visualizers", || self.encode_debugger_visualizers());
@@ -768,11 +771,26 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
768771

769772
let root = stat!("final", || {
770773
let attrs = tcx.hir_krate_attrs();
774+
let new_hash = Svh::new(self.encoder.stable_hasher.clone().finish());
775+
776+
/*eprintln!("crate: {:?}", tcx.crate_name(LOCAL_CRATE));
777+
eprintln!("crate HASH: {:?}", new_hash);
778+
if let Some(hash) = tcx.untracked().local_crate_hash.get() {
779+
eprintln!("resetting hash: {:?}", hash);
780+
}*/
781+
782+
tcx.untracked().local_crate_hash.set(new_hash).expect("local_crate_hash set twice");
783+
784+
/*let old_hash = tcx.crate_hash(new_hash);
785+
eprintln!("OLD HASH: {:?}", old_hash);
786+
eprintln!("NEW HASH: {:?}", new_hash);
787+
assert_eq!(old_hash, new_hash, "Hash mismatch!");*/
788+
771789
self.lazy(CrateRoot {
772790
header: CrateHeader {
773791
name: tcx.crate_name(LOCAL_CRATE),
774792
triple: tcx.sess.opts.target_triple.clone(),
775-
hash: tcx.crate_hash(LOCAL_CRATE),
793+
hash: new_hash,
776794
is_proc_macro_crate: proc_macro_data.is_some(),
777795
is_stub: false,
778796
},
@@ -2018,9 +2036,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
20182036
);
20192037

20202038
(
2021-
syntax_contexts.encode(&mut self.encoder.opaque),
2022-
expn_data_table.encode(&mut self.encoder.opaque),
2023-
expn_hash_table.encode(&mut self.encoder.opaque),
2039+
syntax_contexts.encode(&mut self.encoder),
2040+
expn_data_table.encode(&mut self.encoder),
2041+
expn_hash_table.encode(&mut self.encoder),
20242042
)
20252043
}
20262044

@@ -2475,10 +2493,25 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
24752493
let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub");
24762494

24772495
with_encode_metadata_header(tcx, ref_path, |ecx| {
2496+
//let new_hash = Svh::new(ecx.encoder.stable_hasher.clone().finish());
2497+
2498+
/*eprintln!("crate: {:?}", tcx.crate_name(LOCAL_CRATE));
2499+
eprintln!("encoding hash HASH: {:?}", new_hash);
2500+
if let Some(hash) = tcx.untracked().local_crate_hash.get() {
2501+
eprintln!("resetting hash: {:?}", hash);
2502+
}
2503+
2504+
2505+
tcx.untracked().local_crate_hash.set(new_hash).expect("local_crate_hash set twice");*/
2506+
24782507
let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader {
24792508
name: tcx.crate_name(LOCAL_CRATE),
24802509
triple: tcx.sess.opts.target_triple.clone(),
2481-
hash: tcx.crate_hash(LOCAL_CRATE),
2510+
hash: *tcx
2511+
.untracked()
2512+
.local_crate_hash
2513+
.get()
2514+
.expect("The hash should have been calculated during metadataencoding"),
24822515
is_proc_macro_crate: false,
24832516
is_stub: true,
24842517
});

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ use rustc_middle::mir::ConstValue;
3535
use rustc_middle::ty::fast_reject::SimplifiedType;
3636
use rustc_middle::ty::{self, Ty, TyCtxt};
3737
use rustc_middle::util::Providers;
38-
use rustc_serialize::opaque::FileEncoder;
3938
use rustc_session::config::{SymbolManglingVersion, TargetModifier};
4039
use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
4140
use rustc_span::edition::Edition;
@@ -46,6 +45,7 @@ use table::TableBuilder;
4645

4746
use crate::creader::CrateMetadataRef;
4847
use crate::eii::EiiMapEncodedKeyValue;
48+
use crate::rmeta::encoder::ContextEncoder;
4949

5050
mod decoder;
5151
mod def_path_hash_map;
@@ -367,7 +367,7 @@ macro_rules! define_tables {
367367
}
368368

369369
impl TableBuilders {
370-
fn encode(&self, buf: &mut FileEncoder) -> LazyTables {
370+
fn encode(&self, buf: &mut ContextEncoder<'_>) -> LazyTables {
371371
LazyTables {
372372
$($name1: self.$name1.encode(buf),)+
373373
$($name2: self.$name2.encode(buf),)+

compiler/rustc_metadata/src/rmeta/table.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_hir::def::CtorOf;
22
use rustc_index::Idx;
33

44
use crate::rmeta::decoder::Metadata;
5+
use crate::rmeta::encoder::ContextEncoder;
56
use crate::rmeta::*;
67

78
pub(super) trait IsDefault: Default {
@@ -486,15 +487,12 @@ impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBui
486487
}
487488
}
488489

489-
pub(crate) fn encode(&self, buf: &mut FileEncoder) -> LazyTable<I, T> {
490+
pub(crate) fn encode(&self, buf: &mut ContextEncoder<'_>) -> LazyTable<I, T> {
490491
let pos = buf.position();
491492

492493
let width = self.width;
493494
for block in &self.blocks {
494-
buf.write_with(|dest| {
495-
*dest = *block;
496-
width
497-
});
495+
buf.write_m_with(block, width);
498496
}
499497

500498
LazyTable::from_position_and_encoded_size(

0 commit comments

Comments
 (0)