Skip to content

Commit

Permalink
Auto merge of #51356 - Zoxc:encode-cleanup, r=michaelwoerister
Browse files Browse the repository at this point in the history
Make opaque::Encoder append-only and make it infallible
  • Loading branch information
bors committed Jun 27, 2018
2 parents 142c98d + 14d3c6e commit ed0350e
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 118 deletions.
5 changes: 3 additions & 2 deletions src/librustc/ich/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ impl Fingerprint {
pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };

encoder.emit_raw_bytes(&bytes)
encoder.emit_raw_bytes(&bytes);
Ok(())
}

pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
Expand Down Expand Up @@ -92,7 +93,7 @@ impl serialize::UseSpecializedEncodable for Fingerprint { }

impl serialize::UseSpecializedDecodable for Fingerprint { }

impl<'a> serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder<'a> {
impl serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder {
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
f.encode_opaque(self)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub trait TyEncoder: Encoder {
fn position(&self) -> usize;
}

impl<'buf> TyEncoder for opaque::Encoder<'buf> {
impl TyEncoder for opaque::Encoder {
#[inline]
fn position(&self) -> usize {
self.position()
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 't
}

impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder>
{
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
f.encode_opaque(&mut self.encoder)
Expand Down Expand Up @@ -1057,7 +1057,7 @@ impl IntEncodedWithFixedSize {
impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
impl UseSpecializedDecodable for IntEncodedWithFixedSize {}

impl<'enc> SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder<'enc> {
impl SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder {
fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
let start_pos = self.position();
for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_codegen_llvm/back/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,7 @@ impl WasmEncoder {
}

fn u32(&mut self, val: u32) {
let at = self.data.len();
leb128::write_u32_leb128(&mut self.data, at, val);
leb128::write_u32_leb128(&mut self.data, val);
}

fn byte(&mut self, val: u8) {
Expand Down
15 changes: 7 additions & 8 deletions src/librustc_incremental/persist/file_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use std::fs;
use std::env;

use rustc::session::config::nightly_options;
use rustc_serialize::opaque::Encoder;

/// The first few bytes of files generated by incremental compilation
const FILE_MAGIC: &'static [u8] = b"RSIC";
Expand All @@ -37,17 +38,15 @@ const HEADER_FORMAT_VERSION: u16 = 0;
/// the git commit hash.
const RUSTC_VERSION: Option<&'static str> = option_env!("CFG_VERSION");

pub fn write_file_header<W: io::Write>(stream: &mut W) -> io::Result<()> {
stream.write_all(FILE_MAGIC)?;
stream.write_all(&[(HEADER_FORMAT_VERSION >> 0) as u8,
(HEADER_FORMAT_VERSION >> 8) as u8])?;
pub fn write_file_header(stream: &mut Encoder) {
stream.emit_raw_bytes(FILE_MAGIC);
stream.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8,
(HEADER_FORMAT_VERSION >> 8) as u8]);

let rustc_version = rustc_version();
assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
stream.write_all(&[rustc_version.len() as u8])?;
stream.write_all(rustc_version.as_bytes())?;

Ok(())
stream.emit_raw_bytes(&[rustc_version.len() as u8]);
stream.emit_raw_bytes(rustc_version.as_bytes());
}

/// Reads the contents of a file with a file header as defined in this module.
Expand Down
39 changes: 13 additions & 26 deletions src/librustc_incremental/persist/save.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::join;
use rustc_serialize::Encodable as RustcEncodable;
use rustc_serialize::opaque::Encoder;
use std::io::{self, Cursor};
use std::fs;
use std::path::PathBuf;

Expand Down Expand Up @@ -98,7 +97,7 @@ pub fn save_work_product_index(sess: &Session,
}

fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
where F: FnOnce(&mut Encoder) -> io::Result<()>
where F: FnOnce(&mut Encoder)
{
debug!("save: storing data in {}", path_buf.display());

Expand All @@ -121,20 +120,12 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
}

// generate the data in a memory buffer
let mut wr = Cursor::new(Vec::new());
file_format::write_file_header(&mut wr).unwrap();
match encode(&mut Encoder::new(&mut wr)) {
Ok(()) => {}
Err(err) => {
sess.err(&format!("could not encode dep-graph to `{}`: {}",
path_buf.display(),
err));
return;
}
}
let mut encoder = Encoder::new(Vec::new());
file_format::write_file_header(&mut encoder);
encode(&mut encoder);

// write the data out
let data = wr.into_inner();
let data = encoder.into_inner();
match fs::write(&path_buf, data) {
Ok(_) => {
debug!("save: data written to disk successfully");
Expand All @@ -149,10 +140,9 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
}

fn encode_dep_graph(tcx: TyCtxt,
encoder: &mut Encoder)
-> io::Result<()> {
encoder: &mut Encoder) {
// First encode the commandline arguments hash
tcx.sess.opts.dep_tracking_hash().encode(encoder)?;
tcx.sess.opts.dep_tracking_hash().encode(encoder).unwrap();

// Encode the graph data.
let serialized_graph = time(tcx.sess, "getting serialized graph", || {
Expand Down Expand Up @@ -234,14 +224,12 @@ fn encode_dep_graph(tcx: TyCtxt,
}

time(tcx.sess, "encoding serialized graph", || {
serialized_graph.encode(encoder)
})?;

Ok(())
serialized_graph.encode(encoder).unwrap();
});
}

fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduct>,
encoder: &mut Encoder) -> io::Result<()> {
encoder: &mut Encoder) {
let serialized_products: Vec<_> = work_products
.iter()
.map(|(id, work_product)| {
Expand All @@ -252,13 +240,12 @@ fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduc
})
.collect();

serialized_products.encode(encoder)
serialized_products.encode(encoder).unwrap();
}

fn encode_query_cache(tcx: TyCtxt,
encoder: &mut Encoder)
-> io::Result<()> {
encoder: &mut Encoder) {
time(tcx.sess, "serialize query result cache", || {
tcx.serialize_query_result_cache(encoder)
tcx.serialize_query_result_cache(encoder).unwrap();
})
}
24 changes: 11 additions & 13 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ use rustc_data_structures::stable_hasher::StableHasher;
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};

use std::hash::Hash;
use std::io::prelude::*;
use std::io::Cursor;
use std::path::Path;
use rustc_data_structures::sync::Lrc;
use std::u32;
Expand All @@ -52,7 +50,7 @@ use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::hir::intravisit;

pub struct EncodeContext<'a, 'tcx: 'a> {
opaque: opaque::Encoder<'a>,
opaque: opaque::Encoder,
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &'a LinkMeta,

Expand All @@ -76,7 +74,7 @@ macro_rules! encoder_methods {
}

impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
type Error = <opaque::Encoder<'a> as Encoder>::Error;
type Error = <opaque::Encoder as Encoder>::Error;

fn emit_nil(&mut self) -> Result<(), Self::Error> {
Ok(())
Expand Down Expand Up @@ -480,7 +478,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {

// Index the items
i = self.position();
let index = items.write_index(&mut self.opaque.cursor);
let index = items.write_index(&mut self.opaque);
let index_bytes = self.position() - i;

let attrs = tcx.hir.krate_attrs();
Expand Down Expand Up @@ -537,7 +535,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {

if self.tcx.sess.meta_stats() {
let mut zero_bytes = 0;
for e in self.opaque.cursor.get_ref() {
for e in self.opaque.data.iter() {
if *e == 0 {
zero_bytes += 1;
}
Expand Down Expand Up @@ -1797,15 +1795,15 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta)
-> EncodedMetadata
{
let mut cursor = Cursor::new(vec![]);
cursor.write_all(METADATA_HEADER).unwrap();
let mut encoder = opaque::Encoder::new(vec![]);
encoder.emit_raw_bytes(METADATA_HEADER);

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

let root = {
let (root, mut result) = {
let mut ecx = EncodeContext {
opaque: opaque::Encoder::new(&mut cursor),
opaque: encoder,
tcx,
link_meta,
lazy_state: LazyState::NoNode,
Expand All @@ -1821,9 +1819,9 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

// Encode all the entries and extra information in the crate,
// culminating in the `CrateRoot` which points to all of it.
ecx.encode_crate_root()
let root = ecx.encode_crate_root();
(root, ecx.opaque.into_inner())
};
let mut result = cursor.into_inner();

// Encode the root position.
let header = METADATA_HEADER.len();
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_metadata/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use schema::*;

use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
use std::io::{Cursor, Write};
use rustc_serialize::opaque::Encoder;
use std::slice;
use std::u32;

Expand Down Expand Up @@ -54,15 +54,15 @@ impl Index {
self.positions[space_index][array_index] = position.to_le();
}

pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) -> LazySeq<Index> {
pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Index> {
let pos = buf.position();

// First we write the length of the lower range ...
buf.write_all(words_to_bytes(&[(self.positions[0].len() as u32).to_le()])).unwrap();
buf.emit_raw_bytes(words_to_bytes(&[(self.positions[0].len() as u32).to_le()]));
// ... then the values in the lower range ...
buf.write_all(words_to_bytes(&self.positions[0][..])).unwrap();
buf.emit_raw_bytes(words_to_bytes(&self.positions[0][..]));
// ... then the values in the higher range.
buf.write_all(words_to_bytes(&self.positions[1][..])).unwrap();
buf.emit_raw_bytes(words_to_bytes(&self.positions[1][..]));
LazySeq::with_position_and_length(pos as usize,
self.positions[0].len() + self.positions[1].len() + 1)
}
Expand Down
38 changes: 11 additions & 27 deletions src/libserialize/leb128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@
// except according to those terms.

#[inline]
pub fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) {
if position == vec.len() {
vec.push(byte);
} else {
vec[position] = byte;
}
pub fn write_to_vec(vec: &mut Vec<u8>, byte: u8) {
vec.push(byte);
}

#[cfg(target_pointer_width = "32")]
Expand All @@ -33,24 +29,20 @@ macro_rules! leb128_size {
macro_rules! impl_write_unsigned_leb128 {
($fn_name:ident, $int_ty:ident) => (
#[inline]
pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) -> usize {
let mut position = start_position;
pub fn $fn_name(out: &mut Vec<u8>, mut value: $int_ty) {
for _ in 0 .. leb128_size!($int_ty) {
let mut byte = (value & 0x7F) as u8;
value >>= 7;
if value != 0 {
byte |= 0x80;
}

write_to_vec(out, position, byte);
position += 1;
write_to_vec(out, byte);

if value == 0 {
break;
}
}

position - start_position
}
)
}
Expand Down Expand Up @@ -105,11 +97,9 @@ impl_read_unsigned_leb128!(read_usize_leb128, usize);
/// The callback `write` is called once for each position
/// that is to be written to with the byte to be encoded
/// at that position.
pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
where W: FnMut(usize, u8)
pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W)
where W: FnMut(u8)
{
let mut position = 0;

loop {
let mut byte = (value as u8) & 0x7f;
value >>= 7;
Expand All @@ -120,18 +110,16 @@ pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
byte |= 0x80; // Mark this byte to show that more bytes will follow.
}

write(position, byte);
position += 1;
write(byte);

if !more {
break;
}
}
position
}

pub fn write_signed_leb128(out: &mut Vec<u8>, start_position: usize, value: i128) -> usize {
write_signed_leb128_to(value, |i, v| write_to_vec(out, start_position+i, v))
pub fn write_signed_leb128(out: &mut Vec<u8>, value: i128) {
write_signed_leb128_to(value, |v| write_to_vec(out, v))
}

#[inline]
Expand Down Expand Up @@ -167,9 +155,7 @@ macro_rules! impl_test_unsigned_leb128 {
let mut stream = Vec::new();

for x in 0..62 {
let pos = stream.len();
let bytes_written = $write_fn_name(&mut stream, pos, (3u64 << x) as $int_ty);
assert_eq!(stream.len(), pos + bytes_written);
$write_fn_name(&mut stream, (3u64 << x) as $int_ty);
}

let mut position = 0;
Expand All @@ -195,9 +181,7 @@ fn test_signed_leb128() {
let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect();
let mut stream = Vec::new();
for &x in &values {
let pos = stream.len();
let bytes_written = write_signed_leb128(&mut stream, pos, x);
assert_eq!(stream.len(), pos + bytes_written);
write_signed_leb128(&mut stream, x);
}
let mut pos = 0;
for &x in &values {
Expand Down
1 change: 1 addition & 0 deletions src/libserialize/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Core encoding and decoding interfaces.
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(specialization)]
#![feature(never_type)]
#![cfg_attr(test, feature(test))]

pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
Expand Down
Loading

0 comments on commit ed0350e

Please sign in to comment.