Skip to content

Commit

Permalink
Separate encoding paths.
Browse files Browse the repository at this point in the history
The two paths will be modified independently in the next few commits.
  • Loading branch information
cjgillot committed Jul 15, 2021
1 parent 0a6c636 commit 47ea2ae
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 97 deletions.
51 changes: 23 additions & 28 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Expand Up @@ -30,7 +30,6 @@ use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
use rustc_serialize::{opaque, Decodable, Decoder};
use rustc_session::Session;
use rustc_span::hygiene::ExpnDataDecodeMode;
use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{self, hygiene::MacroKind, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
Expand Down Expand Up @@ -381,33 +380,29 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
}
};

rustc_span::hygiene::decode_expn_id(
decoder,
ExpnDataDecodeMode::Metadata(get_ctxt),
|_this, index| {
let cnum = expn_cnum.get().unwrap();
// Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
// are stored in the owning crate, to avoid duplication.
let crate_data = if cnum == LOCAL_CRATE {
local_cdata
} else {
local_cdata.cstore.get_crate_data(cnum)
};
let expn_data = crate_data
.root
.expn_data
.get(&crate_data, index)
.unwrap()
.decode((&crate_data, sess));
let expn_hash = crate_data
.root
.expn_hashes
.get(&crate_data, index)
.unwrap()
.decode((&crate_data, sess));
Ok((expn_data, expn_hash))
},
)
rustc_span::hygiene::decode_expn_id(decoder, get_ctxt, |_this, index| {
let cnum = expn_cnum.get().unwrap();
// Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
// are stored in the owning crate, to avoid duplication.
let crate_data = if cnum == LOCAL_CRATE {
local_cdata
} else {
local_cdata.cstore.get_crate_data(cnum)
};
let expn_data = crate_data
.root
.expn_data
.get(&crate_data, index)
.unwrap()
.decode((&crate_data, sess));
let expn_hash = crate_data
.root
.expn_hashes
.get(&crate_data, index)
.unwrap()
.decode((&crate_data, sess));
Ok((expn_data, expn_hash))
})
}
}

Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Expand Up @@ -31,7 +31,7 @@ use rustc_session::config::CrateType;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext};
use rustc_span::{
hygiene::{ExpnDataEncodeMode, HygieneEncodeContext, MacroKind},
hygiene::{HygieneEncodeContext, MacroKind},
RealFileName,
};
use rustc_target::abi::VariantIdx;
Expand Down Expand Up @@ -176,12 +176,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SyntaxContext {

impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
rustc_span::hygiene::raw_encode_expn_id(
*self,
&s.hygiene_ctxt,
ExpnDataEncodeMode::Metadata,
s,
)
rustc_span::hygiene::raw_encode_expn_id(*self, &s.hygiene_ctxt, s)
}
}

Expand Down
14 changes: 4 additions & 10 deletions compiler/rustc_middle/src/ty/query/on_disk_cache.rs
Expand Up @@ -20,8 +20,7 @@ use rustc_serialize::{
};
use rustc_session::Session;
use rustc_span::hygiene::{
ExpnDataDecodeMode, ExpnDataEncodeMode, ExpnId, HygieneDecodeContext, HygieneEncodeContext,
SyntaxContext, SyntaxContextData,
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
};
use rustc_span::source_map::{SourceMap, StableSourceFileId};
use rustc_span::CachingSourceMapView;
Expand Down Expand Up @@ -793,9 +792,9 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
let expn_data = decoder.expn_data;
rustc_span::hygiene::decode_expn_id(
rustc_span::hygiene::decode_expn_id_incrcomp(
decoder,
ExpnDataDecodeMode::incr_comp(decoder.hygiene_context),
decoder.hygiene_context,
|this, index| {
// This closure is invoked if we haven't already decoded the data for the `ExpnId` we are deserializing.
// We look up the position of the associated `ExpnData` and decode it.
Expand Down Expand Up @@ -983,12 +982,7 @@ where
E: 'a + OpaqueEncoder,
{
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
rustc_span::hygiene::raw_encode_expn_id(
*self,
s.hygiene_context,
ExpnDataEncodeMode::IncrComp,
s,
)
rustc_span::hygiene::raw_encode_expn_id_incrcomp(*self, s.hygiene_context, s)
}
}

Expand Down
139 changes: 87 additions & 52 deletions compiler/rustc_span/src/hygiene.rs
Expand Up @@ -1076,22 +1076,74 @@ pub struct HygieneDecodeContext {
remapped_expns: Lock<Vec<Option<ExpnId>>>,
}

pub fn decode_expn_id<'a, D: Decoder, G>(
pub fn decode_expn_id_incrcomp<D: Decoder>(
d: &mut D,
mode: ExpnDataDecodeMode<'a, G>,
context: &HygieneDecodeContext,
decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>,
) -> Result<ExpnId, D::Error>
where
G: FnOnce(CrateNum) -> &'a HygieneDecodeContext,
{
) -> Result<ExpnId, D::Error> {
let index = u32::decode(d)?;
let context = match mode {
ExpnDataDecodeMode::IncrComp(context) => context,
ExpnDataDecodeMode::Metadata(get_context) => {
let krate = CrateNum::decode(d)?;
get_context(krate)

// Do this after decoding, so that we decode a `CrateNum`
// if necessary
if index == ExpnId::root().as_u32() {
debug!("decode_expn_id: deserialized root");
return Ok(ExpnId::root());
}

let outer_expns = &context.remapped_expns;

// Ensure that the lock() temporary is dropped early
{
if let Some(expn_id) = outer_expns.lock().get(index as usize).copied().flatten() {
return Ok(expn_id);
}
};
}

// Don't decode the data inside `HygieneData::with`, since we need to recursively decode
// other ExpnIds
let (mut expn_data, hash) = decode_data(d, index)?;

let expn_id = HygieneData::with(|hygiene_data| {
if let Some(&expn_id) = hygiene_data.expn_hash_to_expn_id.get(&hash) {
return expn_id;
}

let expn_id = ExpnId(hygiene_data.expn_data.len() as u32);

// If we just deserialized an `ExpnData` owned by
// the local crate, its `orig_id` will be stale,
// so we need to update it to its own value.
// This only happens when we deserialize the incremental cache,
// since a crate will never decode its own metadata.
if expn_data.krate == LOCAL_CRATE {
expn_data.orig_id = Some(expn_id.0);
}

hygiene_data.expn_data.push(Some(expn_data));
hygiene_data.expn_hashes.push(hash);
let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id);
debug_assert!(_old_id.is_none());

let mut expns = outer_expns.lock();
let new_len = index as usize + 1;
if expns.len() < new_len {
expns.resize(new_len, None);
}
expns[index as usize] = Some(expn_id);
drop(expns);
expn_id
});
Ok(expn_id)
}

pub fn decode_expn_id<'a, D: Decoder>(
d: &mut D,
get_context: impl FnOnce(CrateNum) -> &'a HygieneDecodeContext,
decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>,
) -> Result<ExpnId, D::Error> {
let index = u32::decode(d)?;
let krate = CrateNum::decode(d)?;
let context = get_context(krate);

// Do this after decoding, so that we decode a `CrateNum`
// if necessary
Expand Down Expand Up @@ -1274,56 +1326,39 @@ pub fn raw_encode_syntax_context<E: Encoder>(
ctxt.0.encode(e)
}

pub fn raw_encode_expn_id<E: Encoder>(
pub fn raw_encode_expn_id_incrcomp<E: Encoder>(
expn: ExpnId,
context: &HygieneEncodeContext,
mode: ExpnDataEncodeMode,
e: &mut E,
) -> Result<(), E::Error> {
// Record the fact that we need to serialize the corresponding
// `ExpnData`
let needs_data = || {
if !context.serialized_expns.lock().contains(&expn) {
context.latest_expns.lock().insert(expn);
}
};

match mode {
ExpnDataEncodeMode::IncrComp => {
// Always serialize the `ExpnData` in incr comp mode
needs_data();
expn.0.encode(e)
}
ExpnDataEncodeMode::Metadata => {
let data = expn.expn_data();
// We only need to serialize the ExpnData
// if it comes from this crate.
// We currently don't serialize any hygiene information data for
// proc-macro crates: see the `SpecializedEncoder<Span>` impl
// for crate metadata.
if data.krate == LOCAL_CRATE {
needs_data();
}
data.orig_id.expect("Missing orig_id").encode(e)?;
data.krate.encode(e)
}
if !context.serialized_expns.lock().contains(&expn) {
context.latest_expns.lock().insert(expn);
}
expn.0.encode(e)
}

pub enum ExpnDataEncodeMode {
IncrComp,
Metadata,
}

pub enum ExpnDataDecodeMode<'a, F: FnOnce(CrateNum) -> &'a HygieneDecodeContext> {
IncrComp(&'a HygieneDecodeContext),
Metadata(F),
}

impl<'a> ExpnDataDecodeMode<'a, Box<dyn FnOnce(CrateNum) -> &'a HygieneDecodeContext>> {
pub fn incr_comp(ctxt: &'a HygieneDecodeContext) -> Self {
ExpnDataDecodeMode::IncrComp(ctxt)
pub fn raw_encode_expn_id<E: Encoder>(
expn: ExpnId,
context: &HygieneEncodeContext,
e: &mut E,
) -> Result<(), E::Error> {
let data = expn.expn_data();
// We only need to serialize the ExpnData
// if it comes from this crate.
// We currently don't serialize any hygiene information data for
// proc-macro crates: see the `SpecializedEncoder<Span>` impl
// for crate metadata.
if data.krate == LOCAL_CRATE {
// Record the fact that we need to serialize the corresponding
// `ExpnData`
if !context.serialized_expns.lock().contains(&expn) {
context.latest_expns.lock().insert(expn);
}
}
data.orig_id.expect("Missing orig_id").encode(e)?;
data.krate.encode(e)
}

impl<E: Encoder> Encodable<E> for SyntaxContext {
Expand Down

0 comments on commit 47ea2ae

Please sign in to comment.