diff options
| author | Nicholas Nethercote <nnethercote@mozilla.com> | 2016-10-21 19:25:53 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <nnethercote@mozilla.com> | 2016-10-25 11:48:25 +1100 |
| commit | 3fd90d8aa53d73456b5df476a2bd6cc2caf473c6 (patch) | |
| tree | d36f7cb1f8e1b511f6994c3301f50c350120d665 /src/libsyntax/util/small_vector.rs | |
| parent | 0a16a11c392d227ca845e65905c06599579e2828 (diff) | |
| download | rust-3fd90d8aa53d73456b5df476a2bd6cc2caf473c6.tar.gz rust-3fd90d8aa53d73456b5df476a2bd6cc2caf473c6.zip | |
Use `SmallVector` for `TtReader::stack`.
This avoids 800,000 heap allocations when compiling html5ever. It requires tweaking `SmallVector` a little.
Diffstat (limited to 'src/libsyntax/util/small_vector.rs')
| -rw-r--r-- | src/libsyntax/util/small_vector.rs | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 373dfc4ddfa..57258c76335 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -11,6 +11,7 @@ use self::SmallVectorRepr::*; use self::IntoIterRepr::*; +use core::ops; use std::iter::{IntoIterator, FromIterator}; use std::mem; use std::slice; @@ -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), @@ -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> { @@ -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>; |
