]> git.lizzy.rs Git - rust.git/commitdiff
Make `Directory::path` a `Cow`.
authorNicholas Nethercote <nnethercote@mozilla.com>
Fri, 18 May 2018 06:19:35 +0000 (16:19 +1000)
committerNicholas Nethercote <nnethercote@mozilla.com>
Fri, 18 May 2018 12:20:33 +0000 (22:20 +1000)
Because we create a lot of these in the macro parser, but only very
rarely modify them.

This speeds up some html5ever runs by 2--3%.

src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/tokenstream.rs

index ffe68289d5224be79aa5cb086791919d07b08abc..416634c2960ae21341671b73d5a3449daa7b810e 100644 (file)
@@ -26,6 +26,7 @@
 use symbol::Symbol;
 use tokenstream::{TokenStream, TokenTree};
 
+use std::borrow::Cow;
 use std::collections::HashMap;
 use std::collections::hash_map::Entry;
 
@@ -141,7 +142,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
                 }
 
                 let directory = Directory {
-                    path: cx.current_expansion.module.directory.clone(),
+                    path: Cow::from(cx.current_expansion.module.directory.as_path()),
                     ownership: cx.current_expansion.directory_ownership,
                 };
                 let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false);
index f26a6a5307401cb8645517e69e6dda98862f0b22..0abedb99bd0376564ac2daac7f27c2253616167e 100644 (file)
@@ -23,6 +23,7 @@
 use tokenstream::{TokenStream, TokenTree};
 use diagnostics::plugin::ErrorMap;
 
+use std::borrow::Cow;
 use std::collections::HashSet;
 use std::iter;
 use std::path::{Path, PathBuf};
@@ -89,8 +90,8 @@ pub fn codemap(&self) -> &CodeMap {
 }
 
 #[derive(Clone)]
-pub struct Directory {
-    pub path: PathBuf,
+pub struct Directory<'a> {
+    pub path: Cow<'a, Path>,
     pub ownership: DirectoryOwnership,
 }
 
index 49b30c6f460fe61ac544148ebc6ed7af03dfc5e9..3a53665a032832375007b1a5f7c9e6430c745806 100644 (file)
@@ -57,6 +57,7 @@
 use symbol::{Symbol, keywords};
 use util::ThinVec;
 
+use std::borrow::Cow;
 use std::cmp;
 use std::mem;
 use std::path::{self, Path, PathBuf};
@@ -228,7 +229,7 @@ pub struct Parser<'a> {
     prev_token_kind: PrevTokenKind,
     pub restrictions: Restrictions,
     /// Used to determine the path to externally loaded source files
-    pub directory: Directory,
+    pub directory: Directory<'a>,
     /// Whether to parse sub-modules in other files.
     pub recurse_into_file_modules: bool,
     /// Name of the root module this parser originated from. If `None`, then the
@@ -535,7 +536,7 @@ enum TokenExpectType {
 impl<'a> Parser<'a> {
     pub fn new(sess: &'a ParseSess,
                tokens: TokenStream,
-               directory: Option<Directory>,
+               directory: Option<Directory<'a>>,
                recurse_into_file_modules: bool,
                desugar_doc_comments: bool)
                -> Self {
@@ -549,7 +550,7 @@ pub fn new(sess: &'a ParseSess,
             restrictions: Restrictions::empty(),
             recurse_into_file_modules,
             directory: Directory {
-                path: PathBuf::new(),
+                path: Cow::from(PathBuf::new()),
                 ownership: DirectoryOwnership::Owned { relative: None }
             },
             root_module_name: None,
@@ -572,9 +573,9 @@ pub fn new(sess: &'a ParseSess,
         if let Some(directory) = directory {
             parser.directory = directory;
         } else if !parser.span.source_equal(&DUMMY_SP) {
-            if let FileName::Real(path) = sess.codemap().span_to_unmapped_path(parser.span) {
-                parser.directory.path = path;
-                parser.directory.path.pop();
+            if let FileName::Real(mut path) = sess.codemap().span_to_unmapped_path(parser.span) {
+                path.pop();
+                parser.directory.path = Cow::from(path);
             }
         }
 
@@ -6000,10 +6001,10 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
 
     fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
         if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") {
-            self.directory.path.push(&path.as_str());
+            self.directory.path.to_mut().push(&path.as_str());
             self.directory.ownership = DirectoryOwnership::Owned { relative: None };
         } else {
-            self.directory.path.push(&id.name.as_str());
+            self.directory.path.to_mut().push(&id.name.as_str());
         }
     }
 
index e2b5c4e1adfdbc59c8e1247db5f7d045dc237e54..455cc4391dd3b535877d8b79d03a926859833a95 100644 (file)
@@ -31,6 +31,7 @@
 use serialize::{Decoder, Decodable, Encoder, Encodable};
 use util::RcSlice;
 
+use std::borrow::Cow;
 use std::{fmt, iter, mem};
 use std::hash::{self, Hash};
 
@@ -106,7 +107,7 @@ pub fn parse(cx: &base::ExtCtxt, mtch: &[quoted::TokenTree], tts: TokenStream)
                  -> macro_parser::NamedParseResult {
         // `None` is because we're not interpolating
         let directory = Directory {
-            path: cx.current_expansion.module.directory.clone(),
+            path: Cow::from(cx.current_expansion.module.directory.as_path()),
             ownership: cx.current_expansion.directory_ownership,
         };
         macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory), true)