Skip to content

Commit ae78f17

Browse files
authored
Rollup merge of rust-lang#111086 - nnethercote:rm-MemEncoder, r=cjgillot
Remove `MemEncoder` `MemEncoder` only has one non-test use, and `FileEncoder` would be more appropriate there anyway. r? `@cjgillot`
2 parents 1601bb3 + ebee3f8 commit ae78f17

File tree

9 files changed

+63
-248
lines changed

9 files changed

+63
-248
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4059,6 +4059,7 @@ dependencies = [
40594059
"indexmap",
40604060
"rustc_macros",
40614061
"smallvec",
4062+
"tempfile",
40624063
"thin-vec",
40634064
]
40644065

compiler/rustc_codegen_ssa/src/lib.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ use rustc_middle::dep_graph::WorkProduct;
3131
use rustc_middle::middle::dependency_format::Dependencies;
3232
use rustc_middle::middle::exported_symbols::SymbolExportKind;
3333
use rustc_middle::ty::query::{ExternProviders, Providers};
34-
use rustc_serialize::opaque::{MemDecoder, MemEncoder};
34+
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
3535
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
3636
use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
3737
use rustc_session::cstore::{self, CrateSource};
3838
use rustc_session::utils::NativeLibKind;
3939
use rustc_span::symbol::Symbol;
4040
use rustc_span::DebuggerVisualizerFile;
4141
use std::collections::BTreeSet;
42+
use std::io;
4243
use std::path::{Path, PathBuf};
4344

4445
pub mod back;
@@ -215,8 +216,11 @@ const RLINK_MAGIC: &[u8] = b"rustlink";
215216
const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
216217

217218
impl CodegenResults {
218-
pub fn serialize_rlink(codegen_results: &CodegenResults) -> Vec<u8> {
219-
let mut encoder = MemEncoder::new();
219+
pub fn serialize_rlink(
220+
rlink_file: &Path,
221+
codegen_results: &CodegenResults,
222+
) -> Result<usize, io::Error> {
223+
let mut encoder = FileEncoder::new(rlink_file)?;
220224
encoder.emit_raw_bytes(RLINK_MAGIC);
221225
// `emit_raw_bytes` is used to make sure that the version representation does not depend on
222226
// Encoder's inner representation of `u32`.

compiler/rustc_interface/src/queries.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,8 @@ impl Linker {
368368
}
369369

370370
if sess.opts.unstable_opts.no_link {
371-
let encoded = CodegenResults::serialize_rlink(&codegen_results);
372371
let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
373-
std::fs::write(&rlink_file, encoded)
372+
CodegenResults::serialize_rlink(&rlink_file, &codegen_results)
374373
.map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
375374
return Ok(());
376375
}

compiler/rustc_serialize/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ thin-vec = "0.2.12"
1010

1111
[dev-dependencies]
1212
rustc_macros = { path = "../rustc_macros" }
13+
tempfile = "3.2"

compiler/rustc_serialize/src/opaque.rs

+4-125
Original file line numberDiff line numberDiff line change
@@ -12,118 +12,14 @@ use std::ptr;
1212
// Encoder
1313
// -----------------------------------------------------------------------------
1414

15-
pub struct MemEncoder {
16-
pub data: Vec<u8>,
17-
}
18-
19-
impl MemEncoder {
20-
pub fn new() -> MemEncoder {
21-
MemEncoder { data: vec![] }
22-
}
23-
24-
#[inline]
25-
pub fn position(&self) -> usize {
26-
self.data.len()
27-
}
28-
29-
pub fn finish(self) -> Vec<u8> {
30-
self.data
31-
}
32-
}
33-
34-
macro_rules! write_leb128 {
35-
($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{
36-
const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>();
37-
let old_len = $enc.data.len();
38-
39-
if MAX_ENCODED_LEN > $enc.data.capacity() - old_len {
40-
$enc.data.reserve(MAX_ENCODED_LEN);
41-
}
42-
43-
// SAFETY: The above check and `reserve` ensures that there is enough
44-
// room to write the encoded value to the vector's internal buffer.
45-
unsafe {
46-
let buf = &mut *($enc.data.as_mut_ptr().add(old_len)
47-
as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN]);
48-
let encoded = leb128::$fun(buf, $value);
49-
$enc.data.set_len(old_len + encoded.len());
50-
}
51-
}};
52-
}
53-
54-
impl Encoder for MemEncoder {
55-
#[inline]
56-
fn emit_usize(&mut self, v: usize) {
57-
write_leb128!(self, v, usize, write_usize_leb128)
58-
}
59-
60-
#[inline]
61-
fn emit_u128(&mut self, v: u128) {
62-
write_leb128!(self, v, u128, write_u128_leb128);
63-
}
64-
65-
#[inline]
66-
fn emit_u64(&mut self, v: u64) {
67-
write_leb128!(self, v, u64, write_u64_leb128);
68-
}
69-
70-
#[inline]
71-
fn emit_u32(&mut self, v: u32) {
72-
write_leb128!(self, v, u32, write_u32_leb128);
73-
}
74-
75-
#[inline]
76-
fn emit_u16(&mut self, v: u16) {
77-
self.data.extend_from_slice(&v.to_le_bytes());
78-
}
79-
80-
#[inline]
81-
fn emit_u8(&mut self, v: u8) {
82-
self.data.push(v);
83-
}
84-
85-
#[inline]
86-
fn emit_isize(&mut self, v: isize) {
87-
write_leb128!(self, v, isize, write_isize_leb128)
88-
}
89-
90-
#[inline]
91-
fn emit_i128(&mut self, v: i128) {
92-
write_leb128!(self, v, i128, write_i128_leb128)
93-
}
94-
95-
#[inline]
96-
fn emit_i64(&mut self, v: i64) {
97-
write_leb128!(self, v, i64, write_i64_leb128)
98-
}
99-
100-
#[inline]
101-
fn emit_i32(&mut self, v: i32) {
102-
write_leb128!(self, v, i32, write_i32_leb128)
103-
}
104-
105-
#[inline]
106-
fn emit_i16(&mut self, v: i16) {
107-
self.data.extend_from_slice(&v.to_le_bytes());
108-
}
109-
110-
#[inline]
111-
fn emit_raw_bytes(&mut self, s: &[u8]) {
112-
self.data.extend_from_slice(s);
113-
}
114-
}
115-
11615
pub type FileEncodeResult = Result<usize, io::Error>;
11716

11817
/// `FileEncoder` encodes data to file via fixed-size buffer.
11918
///
120-
/// When encoding large amounts of data to a file, using `FileEncoder` may be
121-
/// preferred over using `MemEncoder` to encode to a `Vec`, and then writing the
122-
/// `Vec` to file, as the latter uses as much memory as there is encoded data,
123-
/// while the former uses the fixed amount of memory allocated to the buffer.
124-
/// `FileEncoder` also has the advantage of not needing to reallocate as data
125-
/// is appended to it, but the disadvantage of requiring more error handling,
126-
/// which has some runtime overhead.
19+
/// There used to be a `MemEncoder` type that encoded all the data into a
20+
/// `Vec`. `FileEncoder` is better because its memory use is determined by the
21+
/// size of the buffer, rather than the full length of the encoded data, and
22+
/// because it doesn't need to reallocate memory along the way.
12723
pub struct FileEncoder {
12824
/// The input buffer. For adequate performance, we need more control over
12925
/// buffering than `BufWriter` offers. If `BufWriter` ever offers a raw
@@ -645,13 +541,6 @@ impl<'a> Decoder for MemDecoder<'a> {
645541

646542
// Specialize encoding byte slices. This specialization also applies to encoding `Vec<u8>`s, etc.,
647543
// since the default implementations call `encode` on their slices internally.
648-
impl Encodable<MemEncoder> for [u8] {
649-
fn encode(&self, e: &mut MemEncoder) {
650-
Encoder::emit_usize(e, self.len());
651-
e.emit_raw_bytes(self);
652-
}
653-
}
654-
655544
impl Encodable<FileEncoder> for [u8] {
656545
fn encode(&self, e: &mut FileEncoder) {
657546
Encoder::emit_usize(e, self.len());
@@ -675,16 +564,6 @@ impl IntEncodedWithFixedSize {
675564
pub const ENCODED_SIZE: usize = 8;
676565
}
677566

678-
impl Encodable<MemEncoder> for IntEncodedWithFixedSize {
679-
#[inline]
680-
fn encode(&self, e: &mut MemEncoder) {
681-
let _start_pos = e.position();
682-
e.emit_raw_bytes(&self.0.to_le_bytes());
683-
let _end_pos = e.position();
684-
debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
685-
}
686-
}
687-
688567
impl Encodable<FileEncoder> for IntEncodedWithFixedSize {
689568
#[inline]
690569
fn encode(&self, e: &mut FileEncoder) {

compiler/rustc_serialize/tests/opaque.rs

+49-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#![allow(rustc::internal)]
22

33
use rustc_macros::{Decodable, Encodable};
4-
use rustc_serialize::opaque::{MemDecoder, MemEncoder};
4+
use rustc_serialize::opaque::{MemDecoder, FileEncoder};
55
use rustc_serialize::{Decodable, Encodable};
66
use std::fmt::Debug;
7+
use std::fs;
78

89
#[derive(PartialEq, Clone, Debug, Encodable, Decodable)]
910
struct Struct {
@@ -27,18 +28,21 @@ struct Struct {
2728
}
2829

2930
fn check_round_trip<
30-
T: Encodable<MemEncoder> + for<'a> Decodable<MemDecoder<'a>> + PartialEq + Debug,
31+
T: Encodable<FileEncoder> + for<'a> Decodable<MemDecoder<'a>> + PartialEq + Debug,
3132
>(
3233
values: Vec<T>,
3334
) {
34-
let mut encoder = MemEncoder::new();
35+
let tmpfile = tempfile::NamedTempFile::new().unwrap();
36+
let tmpfile = tmpfile.path();
37+
38+
let mut encoder = FileEncoder::new(&tmpfile).unwrap();
3539
for value in &values {
3640
Encodable::encode(value, &mut encoder);
3741
}
42+
encoder.finish().unwrap();
3843

39-
let data = encoder.finish();
44+
let data = fs::read(&tmpfile).unwrap();
4045
let mut decoder = MemDecoder::new(&data[..], 0);
41-
4246
for value in values {
4347
let decoded = Decodable::decode(&mut decoder);
4448
assert_eq!(value, decoded);
@@ -61,7 +65,7 @@ fn test_u8() {
6165

6266
#[test]
6367
fn test_u16() {
64-
for i in u16::MIN..u16::MAX {
68+
for i in [u16::MIN, 111, 3333, 55555, u16::MAX] {
6569
check_round_trip(vec![1, 2, 3, i, i, i]);
6670
}
6771
}
@@ -92,7 +96,7 @@ fn test_i8() {
9296

9397
#[test]
9498
fn test_i16() {
95-
for i in i16::MIN..i16::MAX {
99+
for i in [i16::MIN, -100, 0, 101, i16::MAX] {
96100
check_round_trip(vec![-1, 2, -3, i, i, i, 2]);
97101
}
98102
}
@@ -251,3 +255,41 @@ fn test_tuples() {
251255
check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
252256
check_round_trip(vec![(String::new(), "some string".to_string())]);
253257
}
258+
259+
#[test]
260+
fn test_unit_like_struct() {
261+
#[derive(Encodable, Decodable, PartialEq, Debug)]
262+
struct UnitLikeStruct;
263+
264+
check_round_trip(vec![UnitLikeStruct]);
265+
}
266+
267+
#[test]
268+
fn test_box() {
269+
#[derive(Encodable, Decodable, PartialEq, Debug)]
270+
struct A {
271+
foo: Box<[bool]>,
272+
}
273+
274+
let obj = A { foo: Box::new([true, false]) };
275+
check_round_trip(vec![obj]);
276+
}
277+
278+
#[test]
279+
fn test_cell() {
280+
use std::cell::{Cell, RefCell};
281+
282+
#[derive(Encodable, Decodable, PartialEq, Debug)]
283+
struct A {
284+
baz: isize,
285+
}
286+
287+
#[derive(Encodable, Decodable, PartialEq, Debug)]
288+
struct B {
289+
foo: Cell<bool>,
290+
bar: RefCell<A>,
291+
}
292+
293+
let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) };
294+
check_round_trip(vec![obj]);
295+
}

tests/ui-fulldeps/deriving-encodable-decodable-box.rs

-34
This file was deleted.

tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs

-44
This file was deleted.

0 commit comments

Comments
 (0)