Skip to content

Commit

Permalink
Auto merge of #37373 - nnethercote:html5ever-more-more, r=nrc
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Oct 29, 2016
2 parents f0ab4a4 + c440a7a commit e9b2fcb
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 21 deletions.
14 changes: 6 additions & 8 deletions src/libsyntax/ext/tt/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ use parse::token;
use print::pprust;
use ptr::P;
use tokenstream::{self, TokenTree};
use util::small_vector::SmallVector;

use std::mem;
use std::rc::Rc;
Expand All @@ -104,7 +105,7 @@ use std::collections::hash_map::Entry::{Vacant, Occupied};
#[derive(Clone)]
enum TokenTreeOrTokenTreeVec {
Tt(tokenstream::TokenTree),
TtSeq(Rc<Vec<tokenstream::TokenTree>>),
TtSeq(Vec<tokenstream::TokenTree>),
}

impl TokenTreeOrTokenTreeVec {
Expand Down Expand Up @@ -161,7 +162,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize {
})
}

pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: BytePos)
pub fn initial_matcher_pos(ms: Vec<TokenTree>, sep: Option<Token>, lo: BytePos)
-> Box<MatcherPos> {
let match_idx_hi = count_names(&ms[..]);
let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect();
Expand Down Expand Up @@ -284,12 +285,9 @@ pub fn parse(sess: &ParseSess,
mut rdr: TtReader,
ms: &[TokenTree])
-> NamedParseResult {
let mut cur_eis = Vec::new();
cur_eis.push(initial_matcher_pos(Rc::new(ms.iter()
.cloned()
.collect()),
None,
rdr.peek().sp.lo));
let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(),
None,
rdr.peek().sp.lo));

loop {
let mut bb_eis = Vec::new(); // black-box parsed by parser.rs
Expand Down
7 changes: 4 additions & 3 deletions src/libsyntax/ext/tt/transcribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
use self::LockstepIterSize::*;

use ast::Ident;
use syntax_pos::{Span, DUMMY_SP};
use errors::{Handler, DiagnosticBuilder};
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
use parse::token::{DocComment, MatchNt, SubstNt};
use parse::token::{Token, Interpolated, NtIdent, NtTT};
use parse::token;
use parse::lexer::TokenAndSpan;
use syntax_pos::{Span, DUMMY_SP};
use tokenstream::{self, TokenTree};
use util::small_vector::SmallVector;

use std::rc::Rc;
use std::ops::Add;
Expand All @@ -36,7 +37,7 @@ struct TtFrame {
pub struct TtReader<'a> {
pub sp_diag: &'a Handler,
/// the unzipped tree:
stack: Vec<TtFrame>,
stack: SmallVector<TtFrame>,
/* for MBE-style macro transcription */
interpolations: HashMap<Ident, Rc<NamedMatch>>,

Expand Down Expand Up @@ -74,7 +75,7 @@ pub fn new_tt_reader_with_doc_flag(sp_diag: &Handler,
-> TtReader {
let mut r = TtReader {
sp_diag: sp_diag,
stack: vec!(TtFrame {
stack: SmallVector::one(TtFrame {
forest: TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition {
tts: src,
// doesn't matter. This merely holds the root unzipping.
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#![feature(specialization)]
#![feature(dotdot_in_tuple_patterns)]

extern crate core;
extern crate serialize;
extern crate term;
extern crate libc;
Expand Down
50 changes: 40 additions & 10 deletions src/libsyntax/util/small_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use self::SmallVectorRepr::*;
use self::IntoIterRepr::*;

use core::ops;
use std::iter::{IntoIterator, FromIterator};
use std::mem;
use std::slice;
Expand All @@ -19,10 +20,12 @@ use std::vec;
use util::move_map::MoveMap;

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

#[derive(Clone)]
enum SmallVectorRepr<T> {
Zero,
One(T),
Expand Down Expand Up @@ -75,16 +78,11 @@ impl<T> SmallVector<T> {
}

pub fn as_slice(&self) -> &[T] {
match self.repr {
Zero => {
let result: &[T] = &[];
result
}
One(ref v) => {
unsafe { slice::from_raw_parts(v, 1) }
}
Many(ref vs) => vs
}
self
}

pub fn as_mut_slice(&mut self) -> &mut [T] {
self
}

pub fn pop(&mut self) -> Option<T> {
Expand Down Expand Up @@ -163,6 +161,38 @@ impl<T> SmallVector<T> {
}
}

impl<T> ops::Deref for SmallVector<T> {
type Target = [T];

fn deref(&self) -> &[T] {
match self.repr {
Zero => {
let result: &[T] = &[];
result
}
One(ref v) => {
unsafe { slice::from_raw_parts(v, 1) }
}
Many(ref vs) => vs
}
}
}

impl<T> ops::DerefMut for SmallVector<T> {
fn deref_mut(&mut self) -> &mut [T] {
match self.repr {
Zero => {
let result: &mut [T] = &mut [];
result
}
One(ref mut v) => {
unsafe { slice::from_raw_parts_mut(v, 1) }
}
Many(ref mut vs) => vs
}
}
}

impl<T> IntoIterator for SmallVector<T> {
type Item = T;
type IntoIter = IntoIter<T>;
Expand Down

0 comments on commit e9b2fcb

Please sign in to comment.