1
Fork 0

Remove more needless leb128 coding for enum variants

This removes emit_enum_variant and the emit_usize calls that resulted
in. In libcore this eliminates 17% of leb128, taking us from 8964488 to
7383842 leb128's serialized.
This commit is contained in:
Mark Rousskov 2024-01-09 19:51:18 -05:00
parent 5e8f67bbc9
commit 1d2005be71
3 changed files with 36 additions and 35 deletions

View file

@ -70,14 +70,6 @@ pub trait Encoder {
} }
fn emit_raw_bytes(&mut self, s: &[u8]); fn emit_raw_bytes(&mut self, s: &[u8]);
fn emit_enum_variant<F>(&mut self, v_id: usize, f: F)
where
F: FnOnce(&mut Self),
{
self.emit_usize(v_id);
f(self);
}
} }
// Note: all the methods in this trait are infallible, which may be surprising. // Note: all the methods in this trait are infallible, which may be surprising.
@ -132,10 +124,6 @@ pub trait Decoder {
fn read_raw_bytes(&mut self, len: usize) -> &[u8]; fn read_raw_bytes(&mut self, len: usize) -> &[u8];
// Although there is an `emit_enum_variant` method in `Encoder`, the code
// patterns in decoding are different enough to encoding that there is no
// need for a corresponding `read_enum_variant` method here.
fn peek_byte(&self) -> u8; fn peek_byte(&self) -> u8;
fn position(&self) -> usize; fn position(&self) -> usize;
} }
@ -372,15 +360,18 @@ impl<'a, D: Decoder> Decodable<D> for Cow<'a, str> {
impl<S: Encoder, T: Encodable<S>> Encodable<S> for Option<T> { impl<S: Encoder, T: Encodable<S>> Encodable<S> for Option<T> {
fn encode(&self, s: &mut S) { fn encode(&self, s: &mut S) {
match *self { match *self {
None => s.emit_enum_variant(0, |_| {}), None => s.emit_u8(0),
Some(ref v) => s.emit_enum_variant(1, |s| v.encode(s)), Some(ref v) => {
s.emit_u8(1);
v.encode(s);
}
} }
} }
} }
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Option<T> { impl<D: Decoder, T: Decodable<D>> Decodable<D> for Option<T> {
fn decode(d: &mut D) -> Option<T> { fn decode(d: &mut D) -> Option<T> {
match d.read_usize() { match d.read_u8() {
0 => None, 0 => None,
1 => Some(Decodable::decode(d)), 1 => Some(Decodable::decode(d)),
_ => panic!("Encountered invalid discriminant while decoding `Option`."), _ => panic!("Encountered invalid discriminant while decoding `Option`."),
@ -391,15 +382,21 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for Option<T> {
impl<S: Encoder, T1: Encodable<S>, T2: Encodable<S>> Encodable<S> for Result<T1, T2> { impl<S: Encoder, T1: Encodable<S>, T2: Encodable<S>> Encodable<S> for Result<T1, T2> {
fn encode(&self, s: &mut S) { fn encode(&self, s: &mut S) {
match *self { match *self {
Ok(ref v) => s.emit_enum_variant(0, |s| v.encode(s)), Ok(ref v) => {
Err(ref v) => s.emit_enum_variant(1, |s| v.encode(s)), s.emit_u8(0);
v.encode(s);
}
Err(ref v) => {
s.emit_u8(1);
v.encode(s);
}
} }
} }
} }
impl<D: Decoder, T1: Decodable<D>, T2: Decodable<D>> Decodable<D> for Result<T1, T2> { impl<D: Decoder, T1: Decodable<D>, T2: Decodable<D>> Decodable<D> for Result<T1, T2> {
fn decode(d: &mut D) -> Result<T1, T2> { fn decode(d: &mut D) -> Result<T1, T2> {
match d.read_usize() { match d.read_u8() {
0 => Ok(T1::decode(d)), 0 => Ok(T1::decode(d)),
1 => Err(T2::decode(d)), 1 => Err(T2::decode(d)),
_ => panic!("Encountered invalid discriminant while decoding `Result`."), _ => panic!("Encountered invalid discriminant while decoding `Result`."),

View file

@ -203,18 +203,19 @@ impl Hash for RealFileName {
impl<S: Encoder> Encodable<S> for RealFileName { impl<S: Encoder> Encodable<S> for RealFileName {
fn encode(&self, encoder: &mut S) { fn encode(&self, encoder: &mut S) {
match *self { match *self {
RealFileName::LocalPath(ref local_path) => encoder.emit_enum_variant(0, |encoder| { RealFileName::LocalPath(ref local_path) => {
encoder.emit_u8(0);
local_path.encode(encoder); local_path.encode(encoder);
}), }
RealFileName::Remapped { ref local_path, ref virtual_name } => encoder RealFileName::Remapped { ref local_path, ref virtual_name } => {
.emit_enum_variant(1, |encoder| { encoder.emit_u8(1);
// For privacy and build reproducibility, we must not embed host-dependant path // For privacy and build reproducibility, we must not embed host-dependant path
// in artifacts if they have been remapped by --remap-path-prefix // in artifacts if they have been remapped by --remap-path-prefix
assert!(local_path.is_none()); assert!(local_path.is_none());
local_path.encode(encoder); local_path.encode(encoder);
virtual_name.encode(encoder); virtual_name.encode(encoder);
}), }
} }
} }
} }

View file

@ -3396,19 +3396,22 @@ impl Hash for TargetTriple {
impl<S: Encoder> Encodable<S> for TargetTriple { impl<S: Encoder> Encodable<S> for TargetTriple {
fn encode(&self, s: &mut S) { fn encode(&self, s: &mut S) {
match self { match self {
TargetTriple::TargetTriple(triple) => s.emit_enum_variant(0, |s| s.emit_str(triple)), TargetTriple::TargetTriple(triple) => {
TargetTriple::TargetJson { path_for_rustdoc: _, triple, contents } => s s.emit_u8(0);
.emit_enum_variant(1, |s| {
s.emit_str(triple); s.emit_str(triple);
s.emit_str(contents) }
}), TargetTriple::TargetJson { path_for_rustdoc: _, triple, contents } => {
s.emit_u8(1);
s.emit_str(triple);
s.emit_str(contents);
}
} }
} }
} }
impl<D: Decoder> Decodable<D> for TargetTriple { impl<D: Decoder> Decodable<D> for TargetTriple {
fn decode(d: &mut D) -> Self { fn decode(d: &mut D) -> Self {
match d.read_usize() { match d.read_u8() {
0 => TargetTriple::TargetTriple(d.read_str().to_owned()), 0 => TargetTriple::TargetTriple(d.read_str().to_owned()),
1 => TargetTriple::TargetJson { 1 => TargetTriple::TargetJson {
path_for_rustdoc: PathBuf::new(), path_for_rustdoc: PathBuf::new(),