Skip to content

Commit

Permalink
Auto merge of rust-lang#83273 - cjgillot:endecode, r=michaelwoerister
Browse files Browse the repository at this point in the history
Simplify encoder and decoder

Extracted from rust-lang#83036 and rust-lang#82780.
  • Loading branch information
bors committed Mar 22, 2021
2 parents 7f82ddb + 11b3409 commit d04c3aa
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 157 deletions.
66 changes: 10 additions & 56 deletions compiler/rustc_data_structures/src/fingerprint.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use crate::stable_hasher;
use rustc_serialize::{
opaque::{self, EncodeResult, FileEncodeResult},
Decodable, Encodable,
};
use rustc_serialize::{Decodable, Encodable};
use std::hash::{Hash, Hasher};
use std::mem::{self, MaybeUninit};

Expand Down Expand Up @@ -63,16 +60,6 @@ impl Fingerprint {
pub fn to_hex(&self) -> String {
format!("{:x}{:x}", self.0, self.1)
}

pub fn decode_opaque(decoder: &mut opaque::Decoder<'_>) -> Result<Fingerprint, String> {
let mut bytes: [MaybeUninit<u8>; 16] = MaybeUninit::uninit_array();

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 {
Expand Down Expand Up @@ -130,55 +117,22 @@ impl stable_hasher::StableHasherResult for Fingerprint {
impl_stable_hash_via_hash!(Fingerprint);

impl<E: rustc_serialize::Encoder> Encodable<E> for Fingerprint {
#[inline]
fn encode(&self, s: &mut E) -> Result<(), E::Error> {
s.encode_fingerprint(self)
let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };
s.emit_raw_bytes(&bytes)?;
Ok(())
}
}

impl<D: rustc_serialize::Decoder> Decodable<D> for Fingerprint {
#[inline]
fn decode(d: &mut D) -> Result<Self, D::Error> {
d.decode_fingerprint()
}
}

pub trait FingerprintEncoder: rustc_serialize::Encoder {
fn encode_fingerprint(&mut self, f: &Fingerprint) -> Result<(), Self::Error>;
}

pub trait FingerprintDecoder: rustc_serialize::Decoder {
fn decode_fingerprint(&mut self) -> Result<Fingerprint, Self::Error>;
}

impl<E: rustc_serialize::Encoder> FingerprintEncoder for E {
default fn encode_fingerprint(&mut self, _: &Fingerprint) -> Result<(), E::Error> {
panic!("Cannot encode `Fingerprint` with `{}`", std::any::type_name::<E>());
}
}

impl FingerprintEncoder for opaque::Encoder {
fn encode_fingerprint(&mut self, f: &Fingerprint) -> EncodeResult {
let bytes: [u8; 16] = unsafe { mem::transmute([f.0.to_le(), f.1.to_le()]) };
self.emit_raw_bytes(&bytes);
Ok(())
}
}

impl FingerprintEncoder for opaque::FileEncoder {
fn encode_fingerprint(&mut self, f: &Fingerprint) -> FileEncodeResult {
let bytes: [u8; 16] = unsafe { mem::transmute([f.0.to_le(), f.1.to_le()]) };
self.emit_raw_bytes(&bytes)
}
}

impl<D: rustc_serialize::Decoder> FingerprintDecoder for D {
default fn decode_fingerprint(&mut self) -> Result<Fingerprint, D::Error> {
panic!("Cannot decode `Fingerprint` with `{}`", std::any::type_name::<D>());
}
}
let mut bytes: [MaybeUninit<u8>; 16] = MaybeUninit::uninit_array();
d.read_raw_bytes(&mut bytes)?;

impl FingerprintDecoder for opaque::Decoder<'_> {
fn decode_fingerprint(&mut self) -> Result<Fingerprint, String> {
Fingerprint::decode_opaque(self)
let [l, r]: [u64; 2] = unsafe { mem::transmute(bytes) };
Ok(Fingerprint(u64::from_le(l), u64::from_le(r)))
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_incremental/src/persist/file_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use std::io::{self, Read};
use std::path::Path;

use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use rustc_serialize::Encoder;

/// The first few bytes of files generated by incremental compilation.
const FILE_MAGIC: &[u8] = b"RSIC";
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::rmeta::*;
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell};
Expand Down Expand Up @@ -351,12 +350,6 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefIndex {
}
}

impl<'a, 'tcx> FingerprintDecoder for DecodeContext<'a, 'tcx> {
fn decode_fingerprint(&mut self) -> Result<Fingerprint, String> {
Fingerprint::decode_opaque(&mut self.opaque)
}
}

impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<SyntaxContext, String> {
let cdata = decoder.cdata();
Expand Down
12 changes: 3 additions & 9 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::rmeta::table::{FixedSizeEncoding, TableBuilder};
use crate::rmeta::*;

use rustc_data_structures::fingerprint::{Fingerprint, FingerprintEncoder};
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
Expand Down Expand Up @@ -116,6 +115,7 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
emit_f32(f32);
emit_char(char);
emit_str(&str);
emit_raw_bytes(&[u8]);
}
}

Expand Down Expand Up @@ -307,12 +307,6 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
}
}

impl<'a, 'tcx> FingerprintEncoder for EncodeContext<'a, 'tcx> {
fn encode_fingerprint(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
self.opaque.encode_fingerprint(f)
}
}

impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
const CLEAR_CROSS_CRATE: bool = true;

Expand Down Expand Up @@ -2064,10 +2058,10 @@ pub(super) fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {

fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
let mut encoder = opaque::Encoder::new(vec![]);
encoder.emit_raw_bytes(METADATA_HEADER);
encoder.emit_raw_bytes(METADATA_HEADER).unwrap();

// Will be filled with the root position after encoding everything.
encoder.emit_raw_bytes(&[0, 0, 0, 0]);
encoder.emit_raw_bytes(&[0, 0, 0, 0]).unwrap();

let source_map_files = tcx.sess.source_map().files();
let source_file_cache = (source_map_files[0].clone(), 0);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_metadata/src/rmeta/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::rmeta::*;

use rustc_index::vec::Idx;
use rustc_serialize::opaque::Encoder;
use rustc_serialize::Encoder as _;
use std::convert::TryInto;
use std::marker::PhantomData;
use std::num::NonZeroUsize;
Expand Down Expand Up @@ -172,7 +173,7 @@ where

pub(crate) fn encode(&self, buf: &mut Encoder) -> Lazy<Table<I, T>> {
let pos = buf.position();
buf.emit_raw_bytes(&self.bytes);
buf.emit_raw_bytes(&self.bytes).unwrap();
Lazy::from_position_and_meta(NonZeroUsize::new(pos as usize).unwrap(), self.bytes.len())
}
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,11 @@ macro_rules! implement_ty_decoder {
read_str -> Cow<'_, str>;
}

#[inline]
fn read_raw_bytes(&mut self, bytes: &mut [std::mem::MaybeUninit<u8>]) -> Result<(), Self::Error> {
self.opaque.read_raw_bytes(bytes)
}

fn error(&mut self, err: &str) -> Self::Error {
self.opaque.error(err)
}
Expand Down
52 changes: 2 additions & 50 deletions compiler/rustc_middle/src/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::mir::{self, interpret};
use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
use crate::ty::context::TyCtxt;
use crate::ty::{self, Ty};
use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder, FingerprintEncoder};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell};
use rustc_data_structures::thin_vec::ThinVec;
Expand All @@ -17,7 +16,7 @@ use rustc_index::vec::{Idx, IndexVec};
use rustc_query_system::dep_graph::DepContext;
use rustc_query_system::query::QueryContext;
use rustc_serialize::{
opaque::{self, FileEncodeResult, FileEncoder},
opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize},
Decodable, Decoder, Encodable, Encoder,
};
use rustc_session::{CrateDisambiguator, Session};
Expand Down Expand Up @@ -913,12 +912,6 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefId {
}
}

impl<'a, 'tcx> FingerprintDecoder for CacheDecoder<'a, 'tcx> {
fn decode_fingerprint(&mut self) -> Result<Fingerprint, Self::Error> {
Fingerprint::decode_opaque(&mut self.opaque)
}
}

impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
RefDecodable::decode(d)
Expand Down Expand Up @@ -1011,12 +1004,6 @@ where
}
}

impl<'a, 'tcx, E: OpaqueEncoder> FingerprintEncoder for CacheEncoder<'a, 'tcx, E> {
fn encode_fingerprint(&mut self, f: &Fingerprint) -> Result<(), E::Error> {
self.encoder.encode_fingerprint(f)
}
}

impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for SyntaxContext
where
E: 'a + OpaqueEncoder,
Expand Down Expand Up @@ -1167,6 +1154,7 @@ where
emit_f32(f32);
emit_char(char);
emit_str(&str);
emit_raw_bytes(&[u8]);
}
}

Expand All @@ -1180,42 +1168,6 @@ impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx, FileEncoder>> for [u8] {
}
}

// An integer that will always encode to 8 bytes.
struct IntEncodedWithFixedSize(u64);

impl IntEncodedWithFixedSize {
pub const ENCODED_SIZE: usize = 8;
}

impl<E: OpaqueEncoder> Encodable<E> for IntEncodedWithFixedSize {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
let start_pos = e.position();
for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE {
((self.0 >> (i * 8)) as u8).encode(e)?;
}
let end_pos = e.position();
assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
Ok(())
}
}

impl<'a> Decodable<opaque::Decoder<'a>> for IntEncodedWithFixedSize {
fn decode(decoder: &mut opaque::Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
let mut value: u64 = 0;
let start_pos = decoder.position();

for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE {
let byte: u8 = Decodable::decode(decoder)?;
value |= (byte as u64) << (i * 8);
}

let end_pos = decoder.position();
assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);

Ok(IntEncodedWithFixedSize(value))
}
}

pub fn encode_query_results<'a, 'tcx, CTX, Q>(
tcx: CTX,
encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>,
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_serialize/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ use std::collections::{BTreeMap, HashMap};
use std::io;
use std::io::prelude::*;
use std::mem::swap;
use std::mem::MaybeUninit;
use std::num::FpCategory as Fp;
use std::ops::Index;
use std::str::FromStr;
Expand Down Expand Up @@ -553,6 +554,12 @@ impl<'a> crate::Encoder for Encoder<'a> {
fn emit_str(&mut self, v: &str) -> EncodeResult {
escape_str(self.writer, v)
}
fn emit_raw_bytes(&mut self, s: &[u8]) -> Result<(), Self::Error> {
for &c in s.iter() {
self.emit_u8(c)?;
}
Ok(())
}

fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult
where
Expand Down Expand Up @@ -879,6 +886,12 @@ impl<'a> crate::Encoder for PrettyEncoder<'a> {
fn emit_str(&mut self, v: &str) -> EncodeResult {
escape_str(self.writer, v)
}
fn emit_raw_bytes(&mut self, s: &[u8]) -> Result<(), Self::Error> {
for &c in s.iter() {
self.emit_u8(c)?;
}
Ok(())
}

fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult
where
Expand Down Expand Up @@ -2354,6 +2367,14 @@ impl crate::Decoder for Decoder {
expect!(self.pop(), String).map(Cow::Owned)
}

fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), Self::Error> {
for c in s.iter_mut() {
let h = self.read_u8()?;
unsafe { *c.as_mut_ptr() = h };
}
Ok(())
}

fn read_enum<T, F>(&mut self, _name: &str, f: F) -> DecodeResult<T>
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_serialize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Core encoding and decoding interfaces.
#![feature(vec_spare_capacity)]
#![feature(core_intrinsics)]
#![feature(int_bits_const)]
#![feature(maybe_uninit_array_assume_init)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_slice)]
#![feature(new_uninit)]
#![cfg_attr(test, feature(test))]
Expand Down
Loading

0 comments on commit d04c3aa

Please sign in to comment.