From fc2424b988c926004b93c28524be7f8a9388bdf7 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Tue, 19 Dec 2017 22:31:15 -0500 Subject: [PATCH 1/2] Add raw bytes functions Part of #45875 --- src/libserialize/opaque.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs index 99557659b297b..4b2549a1aed2b 100644 --- a/src/libserialize/opaque.rs +++ b/src/libserialize/opaque.rs @@ -27,6 +27,10 @@ impl<'a> Encoder<'a> { pub fn new(cursor: &'a mut io::Cursor>) -> Encoder<'a> { Encoder { cursor: cursor } } + + pub fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult { + self.cursor.write_all(s) + } } @@ -169,6 +173,16 @@ impl<'a> Decoder<'a> { pub fn advance(&mut self, bytes: usize) { self.position += bytes; } + + pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> { + let len = s.len(); + + self.position += len; + + s.copy_from_slice(&self.data[0..len]); + + Ok(()) + } } macro_rules! read_uleb128 { From 01c890ee961aa18e2bfea5c07f4cdd9a29053479 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 22 Dec 2017 22:41:09 -0500 Subject: [PATCH 2/2] [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 --- src/librustc/ich/fingerprint.rs | 36 ++++++++++++++++++++++++++- src/librustc/ty/maps/on_disk_cache.rs | 16 +++++++++++- src/librustc_metadata/decoder.rs | 6 +++++ src/librustc_metadata/encoder.rs | 7 ++++++ src/libserialize/opaque.rs | 7 +++--- 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/librustc/ich/fingerprint.rs b/src/librustc/ich/fingerprint.rs index dc7b9dbe2ef15..a7adf28c481b9 100644 --- a/src/librustc/ich/fingerprint.rs +++ b/src/librustc/ich/fingerprint.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::mem; use rustc_data_structures::stable_hasher; +use serialize; +use serialize::opaque::{EncodeResult, Encoder, Decoder}; -#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] pub struct Fingerprint(u64, u64); impl Fingerprint { @@ -46,6 +49,21 @@ impl Fingerprint { format!("{:x}{:x}", self.0, self.1) } + pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult { + let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) }; + + encoder.emit_raw_bytes(&bytes) + } + + pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result { + let mut bytes = [0; 16]; + + decoder.read_raw_bytes(&mut bytes)?; + + let [l, r]: [u64; 2] = unsafe { mem::transmute(bytes) }; + + Ok(Fingerprint(u64::from_le(l), u64::from_le(r))) + } } impl ::std::fmt::Display for Fingerprint { @@ -69,3 +87,19 @@ impl stable_hasher::HashStable for Fingerprint { ::std::hash::Hash::hash(self, hasher); } } + +impl serialize::UseSpecializedEncodable for Fingerprint { } + +impl serialize::UseSpecializedDecodable for Fingerprint { } + +impl<'a> serialize::SpecializedEncoder for serialize::opaque::Encoder<'a> { + fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { + f.encode_opaque(self) + } +} + +impl<'a> serialize::SpecializedDecoder for serialize::opaque::Decoder<'a> { + fn specialized_decode(&mut self) -> Result { + Fingerprint::decode_opaque(self) + } +} diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index dd8a7223289c2..cd796d3ad963a 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -14,7 +14,7 @@ use hir; use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId, RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE}; use hir::map::definitions::DefPathHash; -use ich::CachingCodemapView; +use ich::{CachingCodemapView, Fingerprint}; use mir; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -660,6 +660,12 @@ impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> { } } +impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> { + fn specialized_decode(&mut self) -> Result { + Fingerprint::decode_opaque(&mut self.opaque) + } +} + impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder> for CacheDecoder<'a, 'tcx, 'x> { #[inline] @@ -879,6 +885,14 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder for CacheEncoder<'enc, 'a, 't } } +impl<'enc, 'a, 'tcx> SpecializedEncoder +for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>> +{ + fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { + f.encode_opaque(&mut self.encoder) + } +} + impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder> for CacheEncoder<'enc, 'a, 'tcx, E> where E: 'enc + ty_codec::TyEncoder, diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index fb4a73891a34e..48a3d36e5ed0e 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -336,6 +336,12 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { } } +impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { + fn specialized_decode(&mut self) -> Result { + Fingerprint::decode_opaque(&mut self.opaque) + } +} + impl<'a, 'tcx, T: Decodable> SpecializedDecoder> for DecodeContext<'a, 'tcx> { #[inline] diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 5ddbb18450e2e..52ebc25940aca 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -18,6 +18,7 @@ use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary, use rustc::hir::def::CtorKind; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE}; use rustc::hir::map::definitions::DefPathTable; +use rustc::ich::Fingerprint; use rustc::middle::dependency_format::Linkage; use rustc::middle::lang_items; use rustc::mir; @@ -154,6 +155,12 @@ impl<'a, 'tcx> SpecializedEncoder> for EncodeContext } } +impl<'a, 'tcx> SpecializedEncoder for EncodeContext<'a, 'tcx> { + fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { + f.encode_opaque(&mut self.opaque) + } +} + impl<'a, 'tcx, T: Encodable> SpecializedEncoder> for EncodeContext<'a, 'tcx> { fn specialized_encode(&mut self, diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs index 4b2549a1aed2b..409366102bacd 100644 --- a/src/libserialize/opaque.rs +++ b/src/libserialize/opaque.rs @@ -175,11 +175,12 @@ impl<'a> Decoder<'a> { } pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> { - let len = s.len(); + let start = self.position; + let end = start + s.len(); - self.position += len; + s.copy_from_slice(&self.data[start..end]); - s.copy_from_slice(&self.data[0..len]); + self.position = end; Ok(()) }