]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #88219 - jyn514:parallel-io, r=GuillaumeGomez
authorbors <bors@rust-lang.org>
Thu, 16 Sep 2021 13:47:55 +0000 (13:47 +0000)
committerbors <bors@rust-lang.org>
Thu, 16 Sep 2021 13:47:55 +0000 (13:47 +0000)
rustdoc: reduce number of copies when using parallel IO

This is Windows-only for now; I was getting really bad slowdowns from this on linux for some reason.

Helps with https://github.com/rust-lang/rust/issues/82741. Follow-up to https://github.com/rust-lang/rust/pull/60971.

src/librustdoc/docfs.rs
src/librustdoc/html/render/context.rs
src/librustdoc/html/render/write_shared.rs
src/librustdoc/html/sources.rs

index 9b740acfcdfd7fe598e0e152e2e430008af5a58d..a5fab1b3d42170c7f7ccdd527dae9dca37820cf6 100644 (file)
@@ -11,7 +11,7 @@
 
 use std::fs;
 use std::io;
-use std::path::Path;
+use std::path::{Path, PathBuf};
 use std::string::ToString;
 use std::sync::mpsc::Sender;
 
@@ -55,17 +55,17 @@ impl DocFS {
         fs::create_dir_all(path)
     }
 
-    crate fn write<P, C, E>(&self, path: P, contents: C) -> Result<(), E>
+    crate fn write<E>(
+        &self,
+        path: PathBuf,
+        contents: impl 'static + Send + AsRef<[u8]>,
+    ) -> Result<(), E>
     where
-        P: AsRef<Path>,
-        C: AsRef<[u8]>,
         E: PathError,
     {
         if !self.sync_only && cfg!(windows) {
             // A possible future enhancement after more detailed profiling would
             // be to create the file sync so errors are reported eagerly.
-            let path = path.as_ref().to_path_buf();
-            let contents = contents.as_ref().to_vec();
             let sender = self.errors.clone().expect("can't write after closing");
             rayon::spawn(move || {
                 fs::write(&path, contents).unwrap_or_else(|e| {
index 34f9c0a8187a659f5602dd580755e5242398adbc..b99d2fe5aa0d17584ca78cbba5e80ddf75f129d2 100644 (file)
@@ -574,7 +574,7 @@ fn after_krate(&mut self) -> Result<(), Error> {
             |buf: &mut Buffer| all.print(buf),
             &self.shared.style_files,
         );
-        self.shared.fs.write(final_file, v.as_bytes())?;
+        self.shared.fs.write(final_file, v)?;
 
         // Generating settings page.
         page.title = "Rustdoc settings";
@@ -596,14 +596,14 @@ fn after_krate(&mut self) -> Result<(), Error> {
             )?,
             &style_files,
         );
-        self.shared.fs.write(&settings_file, v.as_bytes())?;
+        self.shared.fs.write(settings_file, v)?;
         if let Some(ref redirections) = self.shared.redirections {
             if !redirections.borrow().is_empty() {
                 let redirect_map_path =
                     self.dst.join(&*crate_name.as_str()).join("redirect-map.json");
                 let paths = serde_json::to_string(&*redirections.borrow()).unwrap();
                 self.shared.ensure_dir(&self.dst.join(&*crate_name.as_str()))?;
-                self.shared.fs.write(&redirect_map_path, paths.as_bytes())?;
+                self.shared.fs.write(redirect_map_path, paths)?;
             }
         }
 
@@ -641,7 +641,7 @@ fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
         if !buf.is_empty() {
             self.shared.ensure_dir(&self.dst)?;
             let joint_dst = self.dst.join("index.html");
-            scx.fs.write(&joint_dst, buf.as_bytes())?;
+            scx.fs.write(joint_dst, buf)?;
         }
 
         // Render sidebar-items.js used throughout this module.
@@ -653,7 +653,7 @@ fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
             let items = self.build_sidebar_items(module);
             let js_dst = self.dst.join("sidebar-items.js");
             let v = format!("initSidebarItems({});", serde_json::to_string(&items).unwrap());
-            scx.fs.write(&js_dst, &v)?;
+            scx.fs.write(js_dst, v)?;
         }
         Ok(())
     }
@@ -687,7 +687,7 @@ fn item(&mut self, item: clean::Item) -> Result<(), Error> {
             let file_name = &item_path(item_type, &name.as_str());
             self.shared.ensure_dir(&self.dst)?;
             let joint_dst = self.dst.join(file_name);
-            self.shared.fs.write(&joint_dst, buf.as_bytes())?;
+            self.shared.fs.write(joint_dst, buf)?;
 
             if !self.render_redirect_pages {
                 self.shared.all.borrow_mut().append(full_path(self, &item), &item_type);
@@ -705,7 +705,7 @@ fn item(&mut self, item: clean::Item) -> Result<(), Error> {
                 } else {
                     let v = layout::redirect(file_name);
                     let redir_dst = self.dst.join(redir_name);
-                    self.shared.fs.write(&redir_dst, v.as_bytes())?;
+                    self.shared.fs.write(redir_dst, v)?;
                 }
             }
         }
index 99cd98f7eaeb84592f18d3287bc35f85cef10842..1dd0917699bf4bed3444331e85ce5be6fcd97eae 100644 (file)
@@ -105,10 +105,10 @@ fn suffix_path(&self, filename: &str) -> PathBuf {
         self.dst.join(&filename)
     }
 
-    fn write_shared<C: AsRef<[u8]>>(
+    fn write_shared(
         &self,
         resource: SharedResource<'_>,
-        contents: C,
+        contents: impl 'static + Send + AsRef<[u8]>,
         emit: &[EmitType],
     ) -> Result<(), Error> {
         if resource.should_emit(emit) {
@@ -121,25 +121,23 @@ fn write_shared<C: AsRef<[u8]>>(
     fn write_minify(
         &self,
         resource: SharedResource<'_>,
-        contents: &str,
+        contents: impl 'static + Send + AsRef<str> + AsRef<[u8]>,
         minify: bool,
         emit: &[EmitType],
     ) -> Result<(), Error> {
-        let tmp;
-        let contents = if minify {
-            tmp = if resource.extension() == Some(&OsStr::new("css")) {
+        if minify {
+            let contents = contents.as_ref();
+            let contents = if resource.extension() == Some(&OsStr::new("css")) {
                 minifier::css::minify(contents).map_err(|e| {
                     Error::new(format!("failed to minify CSS file: {}", e), resource.path(self))
                 })?
             } else {
                 minifier::js::minify(contents)
             };
-            tmp.as_bytes()
+            self.write_shared(resource, contents, emit)
         } else {
-            contents.as_bytes()
-        };
-
-        self.write_shared(resource, contents, emit)
+            self.write_shared(resource, contents, emit)
+        }
     }
 }
 
@@ -155,15 +153,21 @@ pub(super) fn write_shared(
     let lock_file = cx.dst.join(".lock");
     let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file);
 
-    // The weird `: &_` is to work around a borrowck bug: https://github.com/rust-lang/rust/issues/41078#issuecomment-293646723
-    let write_minify = |p, c: &_| {
+    // Minified resources are usually toolchain resources. If they're not, they should use `cx.write_minify` directly.
+    fn write_minify(
+        basename: &'static str,
+        contents: impl 'static + Send + AsRef<str> + AsRef<[u8]>,
+        cx: &Context<'_>,
+        options: &RenderOptions,
+    ) -> Result<(), Error> {
         cx.write_minify(
-            SharedResource::ToolchainSpecific { basename: p },
-            c,
+            SharedResource::ToolchainSpecific { basename },
+            contents,
             options.enable_minification,
             &options.emit,
         )
-    };
+    }
+
     // Toolchain resources should never be dynamic.
     let write_toolchain = |p: &'static _, c: &'static _| {
         cx.write_shared(SharedResource::ToolchainSpecific { basename: p }, c, &options.emit)
@@ -210,12 +214,12 @@ fn add_background_image_to_css(
         "details.undocumented > summary::before, details.rustdoc-toggle > summary::before",
         "toggle-plus.svg",
     );
-    write_minify("rustdoc.css", &rustdoc_css)?;
+    write_minify("rustdoc.css", rustdoc_css, cx, options)?;
 
     // Add all the static files. These may already exist, but we just
     // overwrite them anyway to make sure that they're fresh and up-to-date.
-    write_minify("settings.css", static_files::SETTINGS_CSS)?;
-    write_minify("noscript.css", static_files::NOSCRIPT_CSS)?;
+    write_minify("settings.css", static_files::SETTINGS_CSS, cx, options)?;
+    write_minify("noscript.css", static_files::NOSCRIPT_CSS, cx, options)?;
 
     // To avoid "light.css" to be overwritten, we'll first run over the received themes and only
     // then we'll run over the "official" styles.
@@ -228,9 +232,9 @@ fn add_background_image_to_css(
 
         // Handle the official themes
         match theme {
-            "light" => write_minify("light.css", static_files::themes::LIGHT)?,
-            "dark" => write_minify("dark.css", static_files::themes::DARK)?,
-            "ayu" => write_minify("ayu.css", static_files::themes::AYU)?,
+            "light" => write_minify("light.css", static_files::themes::LIGHT, cx, options)?,
+            "dark" => write_minify("dark.css", static_files::themes::DARK, cx, options)?,
+            "ayu" => write_minify("ayu.css", static_files::themes::AYU, cx, options)?,
             _ => {
                 // Handle added third-party themes
                 let filename = format!("{}.{}", theme, extension);
@@ -264,26 +268,30 @@ fn add_background_image_to_css(
     // Maybe we can change the representation to move this out of main.js?
     write_minify(
         "main.js",
-        &static_files::MAIN_JS.replace(
+        static_files::MAIN_JS.replace(
             "/* INSERT THEMES HERE */",
             &format!(" = {}", serde_json::to_string(&themes).unwrap()),
         ),
+        cx,
+        options,
     )?;
-    write_minify("search.js", static_files::SEARCH_JS)?;
-    write_minify("settings.js", static_files::SETTINGS_JS)?;
+    write_minify("search.js", static_files::SEARCH_JS, cx, options)?;
+    write_minify("settings.js", static_files::SETTINGS_JS, cx, options)?;
 
     if cx.include_sources {
-        write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT)?;
+        write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT, cx, options)?;
     }
 
     {
         write_minify(
             "storage.js",
-            &format!(
+            format!(
                 "var resourcesSuffix = \"{}\";{}",
                 cx.shared.resource_suffix,
                 static_files::STORAGE_JS
             ),
+            cx,
+            options,
         )?;
     }
 
@@ -292,12 +300,12 @@ fn add_background_image_to_css(
         // This varies based on the invocation, so it can't go through the write_minify wrapper.
         cx.write_minify(
             SharedResource::InvocationSpecific { basename: "theme.css" },
-            &buffer,
+            buffer,
             options.enable_minification,
             &options.emit,
         )?;
     }
-    write_minify("normalize.css", static_files::NORMALIZE_CSS)?;
+    write_minify("normalize.css", static_files::NORMALIZE_CSS, cx, options)?;
     for (name, contents) in &*FILES_UNVERSIONED {
         cx.write_shared(SharedResource::Unversioned { name }, contents, &options.emit)?;
     }
@@ -512,7 +520,7 @@ fn to_json_string(&self) -> String {
                 content,
                 &cx.shared.style_files,
             );
-            cx.shared.fs.write(&dst, v.as_bytes())?;
+            cx.shared.fs.write(dst, v)?;
         }
     }
 
@@ -603,7 +611,7 @@ struct Implementor {
              }",
         );
         v.push_str("})()");
-        cx.shared.fs.write(&mydst, &v)?;
+        cx.shared.fs.write(mydst, v)?;
     }
     Ok(())
 }
index bb90b195ddd4f5547dfc9c19d79a12cac53736ec..71c64231a210eb48e92e2b7739b7bc08362df134 100644 (file)
@@ -208,7 +208,7 @@ fn emit_source(
             },
             &self.cx.shared.style_files,
         );
-        self.cx.shared.fs.write(&cur, v.as_bytes())?;
+        self.cx.shared.fs.write(cur, v)?;
         self.emitted_local_sources.insert(p);
         Ok(())
     }