Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify encoder and decoder #83273

Merged
merged 4 commits into from
Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -2070,10 +2064,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