Skip to content

Commit

Permalink
Move raw bytes handling to Encoder/Decoder.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Mar 11, 2021
1 parent 61365c0 commit 45d2ae4
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 38 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_data_structures/src/fingerprint.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -158,7 +158,7 @@ impl<E: rustc_serialize::Encoder> 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(())
}
}
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
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2073,10 +2073,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
67 changes: 34 additions & 33 deletions compiler/rustc_serialize/src/opaque.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -154,7 +149,13 @@ 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())?;
Ok(())
}

#[inline]
fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
self.data.extend_from_slice(s);
Ok(())
}
}
Expand Down Expand Up @@ -208,11 +209,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.
Expand Down Expand Up @@ -508,6 +504,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)
}
}

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -539,26 +540,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<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 {
Expand Down Expand Up @@ -677,6 +658,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<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
Expand All @@ -689,7 +690,7 @@ impl<'a> serialize::Decoder for Decoder<'a> {
impl serialize::Encodable<Encoder> for [u8] {
fn encode(&self, e: &mut Encoder) -> EncodeResult {
serialize::Encoder::emit_usize(e, self.len())?;
e.emit_raw_bytes(self);
e.emit_raw_bytes(self)?;
Ok(())
}
}
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_serialize/src/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -200,6 +201,14 @@ pub trait Encoder {
{
f(self)
}

#[inline]
fn emit_raw_bytes(&mut self, s: &[u8]) -> Result<(), Self::Error> {
for &c in s.iter() {
self.emit_u8(c)?;
}
Ok(())
}
}

pub trait Decoder {
Expand Down Expand Up @@ -377,6 +386,15 @@ pub trait Decoder {

// Failure
fn error(&mut self, err: &str) -> Self::Error;

#[inline]
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(())
}
}

/// Trait for types that can be serialized
Expand Down

0 comments on commit 45d2ae4

Please sign in to comment.