Skip to content

Commit b653026

Browse files
committed
Implemented first steps of a new, leaner hygiene data encoding scheme.
1 parent 754bf65 commit b653026

File tree

4 files changed

+243
-63
lines changed

4 files changed

+243
-63
lines changed

src/librustc_metadata/decoder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ impl<'a, 'tcx> SpecializedDecoder<hygiene::Mark> for DecodeContext<'a, 'tcx> {
244244
if !self.cdata().hygiene_data_being_decoded.get() && mark != 0 {
245245
let imported_hygiene = self.cdata().imported_hygiene_data();
246246

247-
Ok(hygiene::Mark::from_u32(mark + imported_hygiene.mark_translation_offset))
247+
Ok(imported_hygiene.translate_mark(hygiene::Mark::from_u32(mark)))
248248
} else {
249249
Ok(hygiene::Mark::from_u32(mark))
250250
}
@@ -258,7 +258,7 @@ impl<'a, 'tcx> SpecializedDecoder<SyntaxContext> for DecodeContext<'a, 'tcx> {
258258
if !self.cdata().hygiene_data_being_decoded.get() && ctxt != 0 {
259259
let imported_hygiene = self.cdata().imported_hygiene_data();
260260

261-
Ok(SyntaxContext::from_u32(ctxt + imported_hygiene.ctxt_translation_offset))
261+
Ok(imported_hygiene.translate_ctxt(SyntaxContext::from_u32(ctxt)))
262262
} else {
263263
Ok(SyntaxContext::from_u32(ctxt))
264264
}

src/librustc_metadata/encoder.rs

+40-11
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc::ty::{self, Ty, TyCtxt, ReprOptions};
2929
use rustc::session::config::{self, CrateTypeProcMacro};
3030
use rustc::util::nodemap::{FxHashMap, NodeSet};
3131

32-
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
32+
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, UseSpecializedEncodable, opaque};
3333

3434
use std::hash::Hash;
3535
use std::intrinsics;
@@ -61,6 +61,13 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
6161

6262
pub metadata_hashes: EncodedMetadataHashes,
6363
pub compute_ich: bool,
64+
// We need to encode hygiene info after all spans and possibly other data structures
65+
// that reference it have been encoded already, since we only encode those elements of it
66+
// that are actually used to avoid excessive memory usage. Thus, we need to keep track of
67+
// whether we already encoded the hygiene info (and thus committed to a specific set of
68+
// information to encode) to make sure we can catch bugs introduced by further changes
69+
// quickly.
70+
already_encoded_hygiene_data: bool,
6471
}
6572

6673
macro_rules! encoder_methods {
@@ -136,6 +143,26 @@ impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext
136143
}
137144
}
138145

146+
impl<'a, 'tcx> SpecializedEncoder<hygiene::SyntaxContext> for EncodeContext<'a, 'tcx> {
147+
fn specialized_encode(&mut self, ctxt: &hygiene::SyntaxContext) -> Result<(), Self::Error> {
148+
if self.already_encoded_hygiene_data {
149+
bug!("trying to encode syntax context `{:?}` after encoding hygiene data!", ctxt);
150+
} else {
151+
ctxt.default_encode(self)
152+
}
153+
}
154+
}
155+
156+
impl<'a, 'tcx> SpecializedEncoder<hygiene::Mark> for EncodeContext<'a, 'tcx> {
157+
fn specialized_encode(&mut self, mark: &hygiene::Mark) -> Result<(), Self::Error> {
158+
if self.already_encoded_hygiene_data {
159+
bug!("trying to encode mark `{:?}` after encoding hygiene data!", mark);
160+
} else {
161+
mark.default_encode(self)
162+
}
163+
}
164+
}
165+
139166
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
140167

141168
pub fn position(&self) -> usize {
@@ -323,9 +350,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
323350
self.lazy_seq_ref(adapted.iter().map(|rc| &**rc))
324351
}
325352

326-
fn encode_hygiene_data(&mut self) -> Lazy<hygiene::HygieneData> {
327-
self.tcx.sess.cstore.ensure_hygiene_data_loaded();
328-
hygiene::HygieneData::safe_with(|data| self.lazy(data))
353+
fn encode_hygiene_data(&mut self) -> Lazy<hygiene::HygieneDataMap> {
354+
// TODO(twk): remove the `ensure_hygiene_data_loaded` method!
355+
hygiene::HygieneData::safe_with(|data| self.lazy(&data.to_map()))
329356
}
330357

331358
fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
@@ -372,11 +399,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
372399
let codemap = self.encode_codemap();
373400
let codemap_bytes = self.position() - i;
374401

375-
// Encode hygiene data
376-
i = self.position();
377-
let hygiene_data = self.encode_hygiene_data();
378-
let hygiene_data_bytes = self.position() - i;
379-
380402
// Encode DefPathTable
381403
i = self.position();
382404
let def_path_table = self.encode_def_path_table();
@@ -407,6 +429,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
407429
let index = items.write_index(&mut self.opaque.cursor);
408430
let index_bytes = self.position() - i;
409431

432+
// Encode hygiene data
433+
i = self.position();
434+
let hygiene_data = self.encode_hygiene_data();
435+
let hygiene_data_bytes = self.position() - i;
436+
self.already_encoded_hygiene_data = true;
437+
410438
let tcx = self.tcx;
411439
let link_meta = self.link_meta;
412440
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro);
@@ -437,11 +465,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
437465
lang_items_missing,
438466
native_libraries,
439467
codemap,
440-
hygiene_data,
441468
def_path_table,
442469
impls,
443470
exported_symbols,
444471
index,
472+
hygiene_data,
445473
});
446474

447475
let total_bytes = self.position();
@@ -466,10 +494,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
466494
println!(" codemap bytes: {}", codemap_bytes);
467495
println!(" impl bytes: {}", impl_bytes);
468496
println!(" exp. symbols bytes: {}", exported_symbols_bytes);
469-
println!(" hygiene data bytes: {}", hygiene_data_bytes);
470497
println!(" def-path table bytes: {}", def_path_table_bytes);
471498
println!(" item bytes: {}", item_bytes);
472499
println!(" index bytes: {}", index_bytes);
500+
println!(" hygiene data bytes: {}", hygiene_data_bytes);
473501
println!(" zero bytes: {}", zero_bytes);
474502
println!(" total bytes: {}", total_bytes);
475503
}
@@ -1689,6 +1717,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
16891717
predicate_shorthands: Default::default(),
16901718
metadata_hashes: EncodedMetadataHashes::new(),
16911719
compute_ich,
1720+
already_encoded_hygiene_data: false,
16921721
};
16931722

16941723
// Encode the rustc version string in a predictable location.

src/librustc_metadata/schema.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,11 @@ pub struct CrateRoot {
204204
pub lang_items_missing: LazySeq<lang_items::LangItem>,
205205
pub native_libraries: LazySeq<NativeLibrary>,
206206
pub codemap: LazySeq<syntax_pos::FileMap>,
207-
pub hygiene_data: Lazy<hygiene::HygieneData>,
208207
pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
209208
pub impls: LazySeq<TraitImpls>,
210209
pub exported_symbols: LazySeq<DefIndex>,
211210
pub index: LazySeq<index::Index>,
211+
pub hygiene_data: Lazy<hygiene::HygieneDataMap>,
212212
}
213213

214214
#[derive(RustcEncodable, RustcDecodable)]

0 commit comments

Comments
 (0)