Skip to content

Commit c9c2980

Browse files
committed
Auto merge of #47243 - wesleywiser:incr_fingerprint_encoding, r=michaelwoerister
[incremental] Specialize encoding and decoding of Fingerprints This saves the storage space used by about 32 bits per `Fingerprint`. On average, this reduces the size of the `/target/{mode}/incremental` folder by roughly 5% [Full details here](https://gist.github.com/wesleywiser/264076314794fbd6a4c110d7c1adc43e). Fixes #45875 r? @michaelwoerister
2 parents f62f774 + 01c890e commit c9c2980

File tree

5 files changed

+78
-2
lines changed

5 files changed

+78
-2
lines changed

src/librustc/ich/fingerprint.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use std::mem;
1112
use rustc_data_structures::stable_hasher;
13+
use serialize;
14+
use serialize::opaque::{EncodeResult, Encoder, Decoder};
1215

13-
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
16+
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
1417
pub struct Fingerprint(u64, u64);
1518

1619
impl Fingerprint {
@@ -46,6 +49,21 @@ impl Fingerprint {
4649
format!("{:x}{:x}", self.0, self.1)
4750
}
4851

52+
pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
53+
let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };
54+
55+
encoder.emit_raw_bytes(&bytes)
56+
}
57+
58+
pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
59+
let mut bytes = [0; 16];
60+
61+
decoder.read_raw_bytes(&mut bytes)?;
62+
63+
let [l, r]: [u64; 2] = unsafe { mem::transmute(bytes) };
64+
65+
Ok(Fingerprint(u64::from_le(l), u64::from_le(r)))
66+
}
4967
}
5068

5169
impl ::std::fmt::Display for Fingerprint {
@@ -69,3 +87,19 @@ impl<CTX> stable_hasher::HashStable<CTX> for Fingerprint {
6987
::std::hash::Hash::hash(self, hasher);
7088
}
7189
}
90+
91+
impl serialize::UseSpecializedEncodable for Fingerprint { }
92+
93+
impl serialize::UseSpecializedDecodable for Fingerprint { }
94+
95+
impl<'a> serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder<'a> {
96+
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
97+
f.encode_opaque(self)
98+
}
99+
}
100+
101+
impl<'a> serialize::SpecializedDecoder<Fingerprint> for serialize::opaque::Decoder<'a> {
102+
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
103+
Fingerprint::decode_opaque(self)
104+
}
105+
}

src/librustc/ty/maps/on_disk_cache.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use hir;
1414
use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
1515
RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
1616
use hir::map::definitions::DefPathHash;
17-
use ich::CachingCodemapView;
17+
use ich::{CachingCodemapView, Fingerprint};
1818
use mir;
1919
use rustc_data_structures::fx::FxHashMap;
2020
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -660,6 +660,12 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx, 'x> {
660660
}
661661
}
662662

663+
impl<'a, 'tcx, 'x> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx, 'x> {
664+
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
665+
Fingerprint::decode_opaque(&mut self.opaque)
666+
}
667+
}
668+
663669
impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
664670
for CacheDecoder<'a, 'tcx, 'x> {
665671
#[inline]
@@ -879,6 +885,14 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 't
879885
}
880886
}
881887

888+
impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
889+
for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
890+
{
891+
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
892+
f.encode_opaque(&mut self.encoder)
893+
}
894+
}
895+
882896
impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>>
883897
for CacheEncoder<'enc, 'a, 'tcx, E>
884898
where E: 'enc + ty_codec::TyEncoder,

src/librustc_metadata/decoder.rs

+6
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,12 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
330330
}
331331
}
332332

333+
impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
334+
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
335+
Fingerprint::decode_opaque(&mut self.opaque)
336+
}
337+
}
338+
333339
impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
334340
for DecodeContext<'a, 'tcx> {
335341
#[inline]

src/librustc_metadata/encoder.rs

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
1818
use rustc::hir::def::CtorKind;
1919
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
2020
use rustc::hir::map::definitions::DefPathTable;
21+
use rustc::ich::Fingerprint;
2122
use rustc::middle::dependency_format::Linkage;
2223
use rustc::middle::lang_items;
2324
use rustc::mir;
@@ -192,6 +193,12 @@ impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext
192193
}
193194
}
194195

196+
impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'a, 'tcx> {
197+
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
198+
f.encode_opaque(&mut self.opaque)
199+
}
200+
}
201+
195202
impl<'a, 'tcx, T: Encodable> SpecializedEncoder<mir::ClearCrossCrate<T>>
196203
for EncodeContext<'a, 'tcx> {
197204
fn specialized_encode(&mut self,

src/libserialize/opaque.rs

+15
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ impl<'a> Encoder<'a> {
2727
pub fn new(cursor: &'a mut io::Cursor<Vec<u8>>) -> Encoder<'a> {
2828
Encoder { cursor: cursor }
2929
}
30+
31+
pub fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
32+
self.cursor.write_all(s)
33+
}
3034
}
3135

3236

@@ -169,6 +173,17 @@ impl<'a> Decoder<'a> {
169173
pub fn advance(&mut self, bytes: usize) {
170174
self.position += bytes;
171175
}
176+
177+
pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> {
178+
let start = self.position;
179+
let end = start + s.len();
180+
181+
s.copy_from_slice(&self.data[start..end]);
182+
183+
self.position = end;
184+
185+
Ok(())
186+
}
172187
}
173188

174189
macro_rules! read_uleb128 {

0 commit comments

Comments
 (0)