Move raw bytes handling to Encoder/Decoder.
This commit is contained in:
parent
e5d09fbbe9
commit
09a638820e
9 changed files with 84 additions and 49 deletions
|
@ -1,7 +1,7 @@
|
||||||
use crate::stable_hasher;
|
use crate::stable_hasher;
|
||||||
use rustc_serialize::{
|
use rustc_serialize::{
|
||||||
opaque::{self, EncodeResult, FileEncodeResult},
|
opaque::{self, EncodeResult, FileEncodeResult},
|
||||||
Decodable, Encodable,
|
Decodable, Decoder, Encodable, Encoder,
|
||||||
};
|
};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::mem::{self, MaybeUninit};
|
use std::mem::{self, MaybeUninit};
|
||||||
|
@ -158,7 +158,7 @@ impl<E: rustc_serialize::Encoder> FingerprintEncoder for E {
|
||||||
impl FingerprintEncoder for opaque::Encoder {
|
impl FingerprintEncoder for opaque::Encoder {
|
||||||
fn encode_fingerprint(&mut self, f: &Fingerprint) -> EncodeResult {
|
fn encode_fingerprint(&mut self, f: &Fingerprint) -> EncodeResult {
|
||||||
let bytes: [u8; 16] = unsafe { mem::transmute([f.0.to_le(), f.1.to_le()]) };
|
let bytes: [u8; 16] = unsafe { mem::transmute([f.0.to_le(), f.1.to_le()]) };
|
||||||
self.emit_raw_bytes(&bytes);
|
self.emit_raw_bytes(&bytes)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ use std::io::{self, Read};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
||||||
|
use rustc_serialize::Encoder;
|
||||||
|
|
||||||
/// The first few bytes of files generated by incremental compilation.
|
/// The first few bytes of files generated by incremental compilation.
|
||||||
const FILE_MAGIC: &[u8] = b"RSIC";
|
const FILE_MAGIC: &[u8] = b"RSIC";
|
||||||
|
|
|
@ -116,6 +116,7 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
|
||||||
emit_f32(f32);
|
emit_f32(f32);
|
||||||
emit_char(char);
|
emit_char(char);
|
||||||
emit_str(&str);
|
emit_str(&str);
|
||||||
|
emit_raw_bytes(&[u8]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2070,10 +2071,10 @@ pub(super) fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
|
||||||
|
|
||||||
fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
|
fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
|
||||||
let mut encoder = opaque::Encoder::new(vec![]);
|
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.
|
// 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_map_files = tcx.sess.source_map().files();
|
||||||
let source_file_cache = (source_map_files[0].clone(), 0);
|
let source_file_cache = (source_map_files[0].clone(), 0);
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::rmeta::*;
|
||||||
|
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_serialize::opaque::Encoder;
|
use rustc_serialize::opaque::Encoder;
|
||||||
|
use rustc_serialize::Encoder as _;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
@ -172,7 +173,7 @@ where
|
||||||
|
|
||||||
pub(crate) fn encode(&self, buf: &mut Encoder) -> Lazy<Table<I, T>> {
|
pub(crate) fn encode(&self, buf: &mut Encoder) -> Lazy<Table<I, T>> {
|
||||||
let pos = buf.position();
|
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())
|
Lazy::from_position_and_meta(NonZeroUsize::new(pos as usize).unwrap(), self.bytes.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -472,6 +472,11 @@ macro_rules! implement_ty_decoder {
|
||||||
read_str -> Cow<'_, str>;
|
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 {
|
fn error(&mut self, err: &str) -> Self::Error {
|
||||||
self.opaque.error(err)
|
self.opaque.error(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1167,6 +1167,7 @@ where
|
||||||
emit_f32(f32);
|
emit_f32(f32);
|
||||||
emit_char(char);
|
emit_char(char);
|
||||||
emit_str(&str);
|
emit_str(&str);
|
||||||
|
emit_raw_bytes(&[u8]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,7 @@ use std::collections::{BTreeMap, HashMap};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::mem::swap;
|
use std::mem::swap;
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
use std::num::FpCategory as Fp;
|
use std::num::FpCategory as Fp;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -553,6 +554,12 @@ impl<'a> crate::Encoder for Encoder<'a> {
|
||||||
fn emit_str(&mut self, v: &str) -> EncodeResult {
|
fn emit_str(&mut self, v: &str) -> EncodeResult {
|
||||||
escape_str(self.writer, v)
|
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
|
fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult
|
||||||
where
|
where
|
||||||
|
@ -879,6 +886,12 @@ impl<'a> crate::Encoder for PrettyEncoder<'a> {
|
||||||
fn emit_str(&mut self, v: &str) -> EncodeResult {
|
fn emit_str(&mut self, v: &str) -> EncodeResult {
|
||||||
escape_str(self.writer, v)
|
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
|
fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult
|
||||||
where
|
where
|
||||||
|
@ -2354,6 +2367,14 @@ impl crate::Decoder for Decoder {
|
||||||
expect!(self.pop(), String).map(Cow::Owned)
|
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>
|
fn read_enum<T, F>(&mut self, _name: &str, f: F) -> DecodeResult<T>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::leb128::{self, max_leb128_len};
|
use crate::leb128::{self, max_leb128_len};
|
||||||
use crate::serialize;
|
use crate::serialize::{self, Decoder as _, Encoder as _};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
@ -30,11 +30,6 @@ impl Encoder {
|
||||||
pub fn position(&self) -> usize {
|
pub fn position(&self) -> usize {
|
||||||
self.data.len()
|
self.data.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn emit_raw_bytes(&mut self, s: &[u8]) {
|
|
||||||
self.data.extend_from_slice(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! write_leb128 {
|
macro_rules! write_leb128 {
|
||||||
|
@ -154,7 +149,12 @@ impl serialize::Encoder for Encoder {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn emit_str(&mut self, v: &str) -> EncodeResult {
|
fn emit_str(&mut self, v: &str) -> EncodeResult {
|
||||||
self.emit_usize(v.len())?;
|
self.emit_usize(v.len())?;
|
||||||
self.emit_raw_bytes(v.as_bytes());
|
self.emit_raw_bytes(v.as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
|
||||||
|
self.data.extend_from_slice(s);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,11 +208,6 @@ impl FileEncoder {
|
||||||
self.flushed + self.buffered
|
self.flushed + self.buffered
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn emit_raw_bytes(&mut self, s: &[u8]) -> FileEncodeResult {
|
|
||||||
self.write_all(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn flush(&mut self) -> FileEncodeResult {
|
pub fn flush(&mut self) -> FileEncodeResult {
|
||||||
// This is basically a copy of `BufWriter::flush`. If `BufWriter` ever
|
// This is basically a copy of `BufWriter::flush`. If `BufWriter` ever
|
||||||
// offers a raw buffer access API, we can use it, and remove this.
|
// offers a raw buffer access API, we can use it, and remove this.
|
||||||
|
@ -508,6 +503,11 @@ impl serialize::Encoder for FileEncoder {
|
||||||
self.emit_usize(v.len())?;
|
self.emit_usize(v.len())?;
|
||||||
self.emit_raw_bytes(v.as_bytes())
|
self.emit_raw_bytes(v.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn emit_raw_bytes(&mut self, s: &[u8]) -> FileEncodeResult {
|
||||||
|
self.write_all(s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -539,26 +539,6 @@ impl<'a> Decoder<'a> {
|
||||||
pub fn advance(&mut self, bytes: usize) {
|
pub fn advance(&mut self, bytes: usize) {
|
||||||
self.position += bytes;
|
self.position += bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), String> {
|
|
||||||
let start = self.position;
|
|
||||||
let end = start + s.len();
|
|
||||||
assert!(end <= self.data.len());
|
|
||||||
|
|
||||||
// SAFETY: Both `src` and `dst` point to at least `s.len()` elements:
|
|
||||||
// `src` points to at least `s.len()` elements by above assert, and
|
|
||||||
// `dst` points to `s.len()` elements by derivation from `s`.
|
|
||||||
unsafe {
|
|
||||||
let src = self.data.as_ptr().add(start);
|
|
||||||
let dst = s.as_mut_ptr() as *mut u8;
|
|
||||||
ptr::copy_nonoverlapping(src, dst, s.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.position = end;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! read_leb128 {
|
macro_rules! read_leb128 {
|
||||||
|
@ -677,6 +657,26 @@ impl<'a> serialize::Decoder for Decoder<'a> {
|
||||||
fn error(&mut self, err: &str) -> Self::Error {
|
fn error(&mut self, err: &str) -> Self::Error {
|
||||||
err.to_string()
|
err.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), String> {
|
||||||
|
let start = self.position;
|
||||||
|
let end = start + s.len();
|
||||||
|
assert!(end <= self.data.len());
|
||||||
|
|
||||||
|
// SAFETY: Both `src` and `dst` point to at least `s.len()` elements:
|
||||||
|
// `src` points to at least `s.len()` elements by above assert, and
|
||||||
|
// `dst` points to `s.len()` elements by derivation from `s`.
|
||||||
|
unsafe {
|
||||||
|
let src = self.data.as_ptr().add(start);
|
||||||
|
let dst = s.as_mut_ptr() as *mut u8;
|
||||||
|
ptr::copy_nonoverlapping(src, dst, s.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.position = end;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specializations for contiguous byte sequences follow. The default implementations for slices
|
// Specializations for contiguous byte sequences follow. The default implementations for slices
|
||||||
|
@ -689,8 +689,7 @@ impl<'a> serialize::Decoder for Decoder<'a> {
|
||||||
impl serialize::Encodable<Encoder> for [u8] {
|
impl serialize::Encodable<Encoder> for [u8] {
|
||||||
fn encode(&self, e: &mut Encoder) -> EncodeResult {
|
fn encode(&self, e: &mut Encoder) -> EncodeResult {
|
||||||
serialize::Encoder::emit_usize(e, self.len())?;
|
serialize::Encoder::emit_usize(e, self.len())?;
|
||||||
e.emit_raw_bytes(self);
|
e.emit_raw_bytes(self)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,32 +726,35 @@ impl IntEncodedWithFixedSize {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl serialize::Encodable<Encoder> for IntEncodedWithFixedSize {
|
impl serialize::Encodable<Encoder> for IntEncodedWithFixedSize {
|
||||||
|
#[inline]
|
||||||
fn encode(&self, e: &mut Encoder) -> EncodeResult {
|
fn encode(&self, e: &mut Encoder) -> EncodeResult {
|
||||||
let start_pos = e.position();
|
let _start_pos = e.position();
|
||||||
e.emit_raw_bytes(&self.0.to_le_bytes());
|
e.emit_raw_bytes(&self.0.to_le_bytes())?;
|
||||||
let end_pos = e.position();
|
let _end_pos = e.position();
|
||||||
assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
|
debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl serialize::Encodable<FileEncoder> for IntEncodedWithFixedSize {
|
impl serialize::Encodable<FileEncoder> for IntEncodedWithFixedSize {
|
||||||
|
#[inline]
|
||||||
fn encode(&self, e: &mut FileEncoder) -> FileEncodeResult {
|
fn encode(&self, e: &mut FileEncoder) -> FileEncodeResult {
|
||||||
let start_pos = e.position();
|
let _start_pos = e.position();
|
||||||
e.emit_raw_bytes(&self.0.to_le_bytes())?;
|
e.emit_raw_bytes(&self.0.to_le_bytes())?;
|
||||||
let end_pos = e.position();
|
let _end_pos = e.position();
|
||||||
assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
|
debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serialize::Decodable<Decoder<'a>> for IntEncodedWithFixedSize {
|
impl<'a> serialize::Decodable<Decoder<'a>> for IntEncodedWithFixedSize {
|
||||||
|
#[inline]
|
||||||
fn decode(decoder: &mut Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
|
fn decode(decoder: &mut Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
|
||||||
let mut bytes = MaybeUninit::uninit_array();
|
let mut bytes = MaybeUninit::uninit_array();
|
||||||
let start_pos = decoder.position();
|
let _start_pos = decoder.position();
|
||||||
decoder.read_raw_bytes(&mut bytes)?;
|
decoder.read_raw_bytes(&mut bytes)?;
|
||||||
let end_pos = decoder.position();
|
let _end_pos = decoder.position();
|
||||||
assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
|
debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
|
||||||
|
|
||||||
let value = u64::from_le_bytes(unsafe { MaybeUninit::array_assume_init(bytes) });
|
let value = u64::from_le_bytes(unsafe { MaybeUninit::array_assume_init(bytes) });
|
||||||
Ok(IntEncodedWithFixedSize(value))
|
Ok(IntEncodedWithFixedSize(value))
|
||||||
|
|
|
@ -7,6 +7,7 @@ Core encoding and decoding interfaces.
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
use std::path;
|
use std::path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -33,6 +34,7 @@ pub trait Encoder {
|
||||||
fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error>;
|
fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error>;
|
||||||
fn emit_char(&mut self, v: char) -> Result<(), Self::Error>;
|
fn emit_char(&mut self, v: char) -> Result<(), Self::Error>;
|
||||||
fn emit_str(&mut self, v: &str) -> Result<(), Self::Error>;
|
fn emit_str(&mut self, v: &str) -> Result<(), Self::Error>;
|
||||||
|
fn emit_raw_bytes(&mut self, s: &[u8]) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
// Compound types:
|
// Compound types:
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -224,6 +226,7 @@ pub trait Decoder {
|
||||||
fn read_f32(&mut self) -> Result<f32, Self::Error>;
|
fn read_f32(&mut self) -> Result<f32, Self::Error>;
|
||||||
fn read_char(&mut self) -> Result<char, Self::Error>;
|
fn read_char(&mut self) -> Result<char, Self::Error>;
|
||||||
fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error>;
|
fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error>;
|
||||||
|
fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
// Compound types:
|
// Compound types:
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue