rustc_serialize: specialize opaque decoding of some u8 sequences
This commit is contained in:
parent
7c6274d464
commit
be79f493fb
5 changed files with 42 additions and 26 deletions
|
@ -807,6 +807,15 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
|
||||||
|
|
||||||
crate::implement_ty_decoder!(CacheDecoder<'a, 'tcx>);
|
crate::implement_ty_decoder!(CacheDecoder<'a, 'tcx>);
|
||||||
|
|
||||||
|
// This ensures that the `Decodable<opaque::Decoder>::decode` specialization for `Vec<u8>` is used
|
||||||
|
// when a `CacheDecoder` is passed to `Decodable::decode`. Unfortunately, we have to manually opt
|
||||||
|
// into specializations this way, given how `CacheDecoder` and the decoding traits currently work.
|
||||||
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Vec<u8> {
|
||||||
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
|
||||||
|
Decodable::decode(&mut d.opaque)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
|
||||||
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
|
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
|
||||||
let syntax_contexts = decoder.syntax_contexts;
|
let syntax_contexts = decoder.syntax_contexts;
|
||||||
|
|
|
@ -295,13 +295,8 @@ impl<E: Encoder, T: Encodable<E>> Encodable<E> for Rc<[T]> {
|
||||||
|
|
||||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<[T]> {
|
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<[T]> {
|
||||||
fn decode(d: &mut D) -> Result<Rc<[T]>, D::Error> {
|
fn decode(d: &mut D) -> Result<Rc<[T]>, D::Error> {
|
||||||
d.read_seq(|d, len| {
|
let vec: Vec<T> = Decodable::decode(d)?;
|
||||||
let mut vec = Vec::with_capacity(len);
|
Ok(vec.into())
|
||||||
for index in 0..len {
|
|
||||||
vec.push(d.read_seq_elt(index, |d| Decodable::decode(d))?);
|
|
||||||
}
|
|
||||||
Ok(vec.into())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,12 +309,7 @@ impl<E: Encoder, T: Encodable<E>> Encodable<E> for Arc<[T]> {
|
||||||
|
|
||||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<[T]> {
|
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<[T]> {
|
||||||
fn decode(d: &mut D) -> Result<Arc<[T]>, D::Error> {
|
fn decode(d: &mut D) -> Result<Arc<[T]>, D::Error> {
|
||||||
d.read_seq(|d, len| {
|
let vec: Vec<T> = Decodable::decode(d)?;
|
||||||
let mut vec = Vec::with_capacity(len);
|
Ok(vec.into())
|
||||||
for index in 0..len {
|
|
||||||
vec.push(d.read_seq_elt(index, |d| Decodable::decode(d))?);
|
|
||||||
}
|
|
||||||
Ok(vec.into())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ Core encoding and decoding interfaces.
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![cfg_attr(bootstrap, feature(min_const_generics))]
|
#![cfg_attr(bootstrap, feature(min_const_generics))]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
|
#![feature(vec_spare_capacity)]
|
||||||
#![cfg_attr(test, feature(test))]
|
#![cfg_attr(test, feature(test))]
|
||||||
#![allow(rustc::internal)]
|
#![allow(rustc::internal)]
|
||||||
|
|
||||||
|
|
|
@ -327,10 +327,13 @@ impl<'a> serialize::Decoder for Decoder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialize encoding byte slices. The default implementation for slices encodes and emits each
|
// Specializations for contiguous byte sequences follow. The default implementations for slices
|
||||||
// element individually. This isn't necessary for `u8` slices encoded with an `opaque::Encoder`,
|
// encode and decode each element individually. This isn't necessary for `u8` slices when using
|
||||||
// because each `u8` is emitted as-is. Therefore, we can use a more efficient implementation. This
|
// opaque encoders and decoders, because each `u8` is unchanged by encoding and decoding.
|
||||||
// specialization applies to encoding `Vec<u8>`s, etc., since they call `encode` on their slices.
|
// Therefore, we can use more efficient implementations that process the entire sequence at once.
|
||||||
|
|
||||||
|
// Specialize encoding byte slices. This specialization also applies to encoding `Vec<u8>`s, etc.,
|
||||||
|
// since the default implementations call `encode` on their slices internally.
|
||||||
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())?;
|
||||||
|
@ -338,3 +341,21 @@ impl serialize::Encodable<Encoder> for [u8] {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Specialize decoding `Vec<u8>`. This specialization also applies to decoding `Box<[u8]>`s, etc.,
|
||||||
|
// since the default implementations call `decode` to produce a `Vec<u8>` internally.
|
||||||
|
impl<'a> serialize::Decodable<Decoder<'a>> for Vec<u8> {
|
||||||
|
fn decode(d: &mut Decoder<'a>) -> Result<Self, String> {
|
||||||
|
let len = serialize::Decoder::read_usize(d)?;
|
||||||
|
|
||||||
|
let mut v = Vec::with_capacity(len);
|
||||||
|
let buf = &mut v.spare_capacity_mut()[..len];
|
||||||
|
d.read_raw_bytes(buf)?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
v.set_len(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -545,7 +545,7 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
|
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
|
||||||
fn decode(d: &mut D) -> Result<Vec<T>, D::Error> {
|
default fn decode(d: &mut D) -> Result<Vec<T>, D::Error> {
|
||||||
d.read_seq(|d, len| {
|
d.read_seq(|d, len| {
|
||||||
let mut v = Vec::with_capacity(len);
|
let mut v = Vec::with_capacity(len);
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
|
@ -591,13 +591,8 @@ where
|
||||||
[T]: ToOwned<Owned = Vec<T>>,
|
[T]: ToOwned<Owned = Vec<T>>,
|
||||||
{
|
{
|
||||||
fn decode(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
|
fn decode(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
|
||||||
d.read_seq(|d, len| {
|
let v: Vec<T> = Decodable::decode(d)?;
|
||||||
let mut v = Vec::with_capacity(len);
|
Ok(Cow::Owned(v))
|
||||||
for i in 0..len {
|
|
||||||
v.push(d.read_seq_elt(i, |d| Decodable::decode(d))?);
|
|
||||||
}
|
|
||||||
Ok(Cow::Owned(v))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue