Skip to content

Commit e9b2fcb

Browse files
authored
Auto merge of #37373 - nnethercote:html5ever-more-more, r=nrc
Avoid more allocations when compiling html5ever These three commits reduce the number of allocations performed when compiling html5ever from 13.2M to 10.8M, which speeds up compilation by about 2%. r? @nrc
2 parents f0ab4a4 + c440a7a commit e9b2fcb

File tree

4 files changed

+51
-21
lines changed

4 files changed

+51
-21
lines changed

src/libsyntax/ext/tt/macro_parser.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ use parse::token;
9292
use print::pprust;
9393
use ptr::P;
9494
use tokenstream::{self, TokenTree};
95+
use util::small_vector::SmallVector;
9596

9697
use std::mem;
9798
use std::rc::Rc;
@@ -104,7 +105,7 @@ use std::collections::hash_map::Entry::{Vacant, Occupied};
104105
#[derive(Clone)]
105106
enum TokenTreeOrTokenTreeVec {
106107
Tt(tokenstream::TokenTree),
107-
TtSeq(Rc<Vec<tokenstream::TokenTree>>),
108+
TtSeq(Vec<tokenstream::TokenTree>),
108109
}
109110

110111
impl TokenTreeOrTokenTreeVec {
@@ -161,7 +162,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize {
161162
})
162163
}
163164

164-
pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: BytePos)
165+
pub fn initial_matcher_pos(ms: Vec<TokenTree>, sep: Option<Token>, lo: BytePos)
165166
-> Box<MatcherPos> {
166167
let match_idx_hi = count_names(&ms[..]);
167168
let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect();
@@ -284,12 +285,9 @@ pub fn parse(sess: &ParseSess,
284285
mut rdr: TtReader,
285286
ms: &[TokenTree])
286287
-> NamedParseResult {
287-
let mut cur_eis = Vec::new();
288-
cur_eis.push(initial_matcher_pos(Rc::new(ms.iter()
289-
.cloned()
290-
.collect()),
291-
None,
292-
rdr.peek().sp.lo));
288+
let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(),
289+
None,
290+
rdr.peek().sp.lo));
293291

294292
loop {
295293
let mut bb_eis = Vec::new(); // black-box parsed by parser.rs

src/libsyntax/ext/tt/transcribe.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
use self::LockstepIterSize::*;
1111

1212
use ast::Ident;
13-
use syntax_pos::{Span, DUMMY_SP};
1413
use errors::{Handler, DiagnosticBuilder};
1514
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
1615
use parse::token::{DocComment, MatchNt, SubstNt};
1716
use parse::token::{Token, Interpolated, NtIdent, NtTT};
1817
use parse::token;
1918
use parse::lexer::TokenAndSpan;
19+
use syntax_pos::{Span, DUMMY_SP};
2020
use tokenstream::{self, TokenTree};
21+
use util::small_vector::SmallVector;
2122

2223
use std::rc::Rc;
2324
use std::ops::Add;
@@ -36,7 +37,7 @@ struct TtFrame {
3637
pub struct TtReader<'a> {
3738
pub sp_diag: &'a Handler,
3839
/// the unzipped tree:
39-
stack: Vec<TtFrame>,
40+
stack: SmallVector<TtFrame>,
4041
/* for MBE-style macro transcription */
4142
interpolations: HashMap<Ident, Rc<NamedMatch>>,
4243

@@ -74,7 +75,7 @@ pub fn new_tt_reader_with_doc_flag(sp_diag: &Handler,
7475
-> TtReader {
7576
let mut r = TtReader {
7677
sp_diag: sp_diag,
77-
stack: vec!(TtFrame {
78+
stack: SmallVector::one(TtFrame {
7879
forest: TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition {
7980
tts: src,
8081
// doesn't matter. This merely holds the root unzipping.

src/libsyntax/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#![feature(specialization)]
3737
#![feature(dotdot_in_tuple_patterns)]
3838

39+
extern crate core;
3940
extern crate serialize;
4041
extern crate term;
4142
extern crate libc;

src/libsyntax/util/small_vector.rs

+40-10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use self::SmallVectorRepr::*;
1212
use self::IntoIterRepr::*;
1313

14+
use core::ops;
1415
use std::iter::{IntoIterator, FromIterator};
1516
use std::mem;
1617
use std::slice;
@@ -19,10 +20,12 @@ use std::vec;
1920
use util::move_map::MoveMap;
2021

2122
/// A vector type optimized for cases where the size is almost always 0 or 1
23+
#[derive(Clone)]
2224
pub struct SmallVector<T> {
2325
repr: SmallVectorRepr<T>,
2426
}
2527

28+
#[derive(Clone)]
2629
enum SmallVectorRepr<T> {
2730
Zero,
2831
One(T),
@@ -75,16 +78,11 @@ impl<T> SmallVector<T> {
7578
}
7679

7780
pub fn as_slice(&self) -> &[T] {
78-
match self.repr {
79-
Zero => {
80-
let result: &[T] = &[];
81-
result
82-
}
83-
One(ref v) => {
84-
unsafe { slice::from_raw_parts(v, 1) }
85-
}
86-
Many(ref vs) => vs
87-
}
81+
self
82+
}
83+
84+
pub fn as_mut_slice(&mut self) -> &mut [T] {
85+
self
8886
}
8987

9088
pub fn pop(&mut self) -> Option<T> {
@@ -163,6 +161,38 @@ impl<T> SmallVector<T> {
163161
}
164162
}
165163

164+
impl<T> ops::Deref for SmallVector<T> {
165+
type Target = [T];
166+
167+
fn deref(&self) -> &[T] {
168+
match self.repr {
169+
Zero => {
170+
let result: &[T] = &[];
171+
result
172+
}
173+
One(ref v) => {
174+
unsafe { slice::from_raw_parts(v, 1) }
175+
}
176+
Many(ref vs) => vs
177+
}
178+
}
179+
}
180+
181+
impl<T> ops::DerefMut for SmallVector<T> {
182+
fn deref_mut(&mut self) -> &mut [T] {
183+
match self.repr {
184+
Zero => {
185+
let result: &mut [T] = &mut [];
186+
result
187+
}
188+
One(ref mut v) => {
189+
unsafe { slice::from_raw_parts_mut(v, 1) }
190+
}
191+
Many(ref mut vs) => vs
192+
}
193+
}
194+
}
195+
166196
impl<T> IntoIterator for SmallVector<T> {
167197
type Item = T;
168198
type IntoIter = IntoIter<T>;

0 commit comments

Comments
 (0)