Skip to content

Commit 01c890e

Browse files
committed
[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%. Fixes #45875
1 parent fc2424b commit 01c890e

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
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
@@ -336,6 +336,12 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
336336
}
337337
}
338338

339+
impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
340+
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
341+
Fingerprint::decode_opaque(&mut self.opaque)
342+
}
343+
}
344+
339345
impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
340346
for DecodeContext<'a, 'tcx> {
341347
#[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;
@@ -154,6 +155,12 @@ impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext
154155
}
155156
}
156157

158+
impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'a, 'tcx> {
159+
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
160+
f.encode_opaque(&mut self.opaque)
161+
}
162+
}
163+
157164
impl<'a, 'tcx, T: Encodable> SpecializedEncoder<mir::ClearCrossCrate<T>>
158165
for EncodeContext<'a, 'tcx> {
159166
fn specialized_encode(&mut self,

src/libserialize/opaque.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,12 @@ impl<'a> Decoder<'a> {
175175
}
176176

177177
pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> {
178-
let len = s.len();
178+
let start = self.position;
179+
let end = start + s.len();
179180

180-
self.position += len;
181+
s.copy_from_slice(&self.data[start..end]);
181182

182-
s.copy_from_slice(&self.data[0..len]);
183+
self.position = end;
183184

184185
Ok(())
185186
}

0 commit comments

Comments
 (0)