From 09a638820e6a2383b9b84333aa588ced80982d0a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 11 Mar 2021 22:06:45 +0100 Subject: [PATCH] Move raw bytes handling to Encoder/Decoder. --- .../rustc_data_structures/src/fingerprint.rs | 4 +- .../src/persist/file_format.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 5 +- compiler/rustc_metadata/src/rmeta/table.rs | 3 +- compiler/rustc_middle/src/ty/codec.rs | 5 ++ .../src/ty/query/on_disk_cache.rs | 1 + compiler/rustc_serialize/src/json.rs | 21 +++++ compiler/rustc_serialize/src/opaque.rs | 90 ++++++++++--------- compiler/rustc_serialize/src/serialize.rs | 3 + 9 files changed, 84 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index 681b49e2ea9..6b533f9f057 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -1,7 +1,7 @@ use crate::stable_hasher; use rustc_serialize::{ opaque::{self, EncodeResult, FileEncodeResult}, - Decodable, Encodable, + Decodable, Decoder, Encodable, Encoder, }; use std::hash::{Hash, Hasher}; use std::mem::{self, MaybeUninit}; @@ -158,7 +158,7 @@ impl FingerprintEncoder for 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); + self.emit_raw_bytes(&bytes)?; Ok(()) } } diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs index 374a9eb41e5..b821ed6cff9 100644 --- a/compiler/rustc_incremental/src/persist/file_format.rs +++ b/compiler/rustc_incremental/src/persist/file_format.rs @@ -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"; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 06f53bb9282..a07e0476050 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -116,6 +116,7 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> { emit_f32(f32); emit_char(char); 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 { 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); diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 03bd4170ea9..62c0ce15845 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -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; @@ -172,7 +173,7 @@ where pub(crate) fn encode(&self, buf: &mut Encoder) -> Lazy> { 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()) } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index f796534c2e1..ea1caf58d78 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -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]) -> Result<(), Self::Error> { + self.opaque.read_raw_bytes(bytes) + } + fn error(&mut self, err: &str) -> Self::Error { self.opaque.error(err) } diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index 8d2654e2157..e4c5907f5a5 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -1167,6 +1167,7 @@ where emit_f32(f32); emit_char(char); emit_str(&str); + emit_raw_bytes(&[u8]); } } diff --git a/compiler/rustc_serialize/src/json.rs b/compiler/rustc_serialize/src/json.rs index bbbe568f17a..51945ab435e 100644 --- a/compiler/rustc_serialize/src/json.rs +++ b/compiler/rustc_serialize/src/json.rs @@ -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; @@ -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(&mut self, _name: &str, f: F) -> EncodeResult where @@ -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(&mut self, _name: &str, f: F) -> EncodeResult where @@ -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]) -> Result<(), Self::Error> { + for c in s.iter_mut() { + let h = self.read_u8()?; + unsafe { *c.as_mut_ptr() = h }; + } + Ok(()) + } + fn read_enum(&mut self, _name: &str, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 6aad3f498e9..c171593ebdc 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -1,5 +1,5 @@ use crate::leb128::{self, max_leb128_len}; -use crate::serialize; +use crate::serialize::{self, Decoder as _, Encoder as _}; use std::borrow::Cow; use std::fs::File; use std::io::{self, Write}; @@ -30,11 +30,6 @@ impl Encoder { pub fn position(&self) -> usize { self.data.len() } - - #[inline] - pub fn emit_raw_bytes(&mut self, s: &[u8]) { - self.data.extend_from_slice(s); - } } macro_rules! write_leb128 { @@ -154,7 +149,12 @@ impl serialize::Encoder for Encoder { #[inline] fn emit_str(&mut self, v: &str) -> EncodeResult { 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(()) } } @@ -208,11 +208,6 @@ impl FileEncoder { 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 { // This is basically a copy of `BufWriter::flush`. If `BufWriter` ever // 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_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) { self.position += bytes; } - - #[inline] - pub fn read_raw_bytes(&mut self, s: &mut [MaybeUninit]) -> 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 { @@ -677,6 +657,26 @@ impl<'a> serialize::Decoder for Decoder<'a> { fn error(&mut self, err: &str) -> Self::Error { err.to_string() } + + #[inline] + fn read_raw_bytes(&mut self, s: &mut [MaybeUninit]) -> 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 @@ -689,8 +689,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { impl serialize::Encodable for [u8] { fn encode(&self, e: &mut Encoder) -> EncodeResult { serialize::Encoder::emit_usize(e, self.len())?; - e.emit_raw_bytes(self); - Ok(()) + e.emit_raw_bytes(self) } } @@ -727,32 +726,35 @@ impl IntEncodedWithFixedSize { } impl serialize::Encodable for IntEncodedWithFixedSize { + #[inline] fn encode(&self, e: &mut Encoder) -> EncodeResult { - let start_pos = e.position(); - e.emit_raw_bytes(&self.0.to_le_bytes()); - let end_pos = e.position(); - assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE); + let _start_pos = e.position(); + e.emit_raw_bytes(&self.0.to_le_bytes())?; + let _end_pos = e.position(); + debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE); Ok(()) } } impl serialize::Encodable for IntEncodedWithFixedSize { + #[inline] 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())?; - let end_pos = e.position(); - assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE); + let _end_pos = e.position(); + debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE); Ok(()) } } impl<'a> serialize::Decodable> for IntEncodedWithFixedSize { + #[inline] fn decode(decoder: &mut Decoder<'a>) -> Result { let mut bytes = MaybeUninit::uninit_array(); - let start_pos = decoder.position(); + let _start_pos = decoder.position(); decoder.read_raw_bytes(&mut bytes)?; - let end_pos = decoder.position(); - assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE); + let _end_pos = decoder.position(); + debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE); let value = u64::from_le_bytes(unsafe { MaybeUninit::array_assume_init(bytes) }); Ok(IntEncodedWithFixedSize(value)) diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index 47aad5b88c6..a3b02b7c34a 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -7,6 +7,7 @@ Core encoding and decoding interfaces. use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::marker::PhantomData; +use std::mem::MaybeUninit; use std::path; use std::rc::Rc; use std::sync::Arc; @@ -33,6 +34,7 @@ pub trait Encoder { fn emit_f32(&mut self, v: f32) -> 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_raw_bytes(&mut self, s: &[u8]) -> Result<(), Self::Error>; // Compound types: #[inline] @@ -224,6 +226,7 @@ pub trait Decoder { fn read_f32(&mut self) -> Result; fn read_char(&mut self) -> Result; fn read_str(&mut self) -> Result, Self::Error>; + fn read_raw_bytes(&mut self, s: &mut [MaybeUninit]) -> Result<(), Self::Error>; // Compound types: #[inline]