about summary refs log tree commit diff
path: root/src/librustpkg
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-29 20:06:13 -0700
committerbors <bors@rust-lang.org>2013-09-29 20:06:13 -0700
commit80b6056f5d4ae6b527b36c502cc074c2518a3f7d (patch)
treeb67d74eca80fc1a56a42aab154f3fff431f66c97 /src/librustpkg
parent0fd8cb07c1fb1547ae50b5d3732e643286aff419 (diff)
parent7b18976f085a741322c735f0a4279816547d7eaf (diff)
downloadrust-80b6056f5d4ae6b527b36c502cc074c2518a3f7d.tar.gz
rust-80b6056f5d4ae6b527b36c502cc074c2518a3f7d.zip
auto merge of #9612 : alexcrichton/rust/rc-crate2, r=huonw
This patch exposes actual ownership of an `ast::Crate` structure so it's not implicitly copied and reference counted via `@`.

The main purpose for this patch was to get rid of the massive spike in memory during the start of the compiler (this can be seen on isrustfastyet). The reason that this spike exists is that during `phase_2` we're creating many copies of the crate by folding. Because these are reference counted, all instances of the old crates aren't dropped until the end of the function, which is why so much memory is accumulated.

This patch exposes true ownership of the crate, meaning that it will be destroyed ASAP when requested. There are no code changes except for dealing with actual ownership of the crate. The large spike is then avoided: http://i.imgur.com/IO3NENy.png

This shouldn't help our overall memory usage (that still is the highest at the end), but if we ever manage to bring that down it should help us not have a 1GB spike at the beginning of compilation.

(This was to un-stuck bors (hopefully).)
Diffstat (limited to 'src/librustpkg')
-rw-r--r--src/librustpkg/rustpkg.rs17
-rw-r--r--src/librustpkg/util.rs17
2 files changed, 15 insertions, 19 deletions
diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs
index e4f88081239..2945b75128e 100644
--- a/src/librustpkg/rustpkg.rs
+++ b/src/librustpkg/rustpkg.rs
@@ -85,7 +85,7 @@ struct PkgScript<'self> {
     /// The config for compiling the custom build script
     cfg: ast::CrateConfig,
     /// The crate for the custom build script
-    crate: @ast::Crate,
+    crate: Option<ast::Crate>,
     /// Directory in which to store build output
     build_dir: Path
 }
@@ -125,7 +125,7 @@ impl<'self> PkgScript<'self> {
             input: script,
             sess: sess,
             cfg: cfg,
-            crate: crate,
+            crate: Some(crate),
             build_dir: work_dir
         }
     }
@@ -134,12 +134,13 @@ impl<'self> PkgScript<'self> {
     /// is the command to pass to it (e.g., "build", "clean", "install")
     /// Returns a pair of an exit code and list of configs (obtained by
     /// calling the package script's configs() function if it exists
-    fn run_custom(&self, exec: &mut workcache::Exec, sysroot: &Path) -> (~[~str], ExitCode) {
+    fn run_custom(&mut self, exec: &mut workcache::Exec,
+                  sysroot: &Path) -> (~[~str], ExitCode) {
         let sess = self.sess;
 
         debug!("Working directory = %s", self.build_dir.to_str());
         // Collect together any user-defined commands in the package script
-        let crate = util::ready_crate(sess, self.crate);
+        let crate = util::ready_crate(sess, self.crate.take_unwrap());
         debug!("Building output filenames with script name %s",
                driver::source_name(&driver::file_input(self.input.clone())));
         let exe = self.build_dir.push(~"pkg" + util::exe_suffix());
@@ -419,10 +420,10 @@ impl CtxMethods for BuildContext {
                     let sub_id = pkgid.clone();
                     declare_package_script_dependency(prep, &*pkg_src);
                     do prep.exec |exec| {
-                        let pscript = PkgScript::parse(@sub_sysroot.clone(),
-                                                       package_script_path_clone.clone(),
-                                                       &sub_ws,
-                                                       &sub_id);
+                        let mut pscript = PkgScript::parse(@sub_sysroot.clone(),
+                                                          package_script_path_clone.clone(),
+                                                          &sub_ws,
+                                                          &sub_id);
 
                         pscript.run_custom(exec, &sub_sysroot)
                     }
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index b30ad6f2c92..af80abdac38 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -68,7 +68,6 @@ struct ListenerFn {
 
 struct ReadyCtx {
     sess: session::Session,
-    crate: @ast::Crate,
     ext_cx: @ExtCtxt,
     path: ~[ast::Ident],
     fns: ~[ListenerFn]
@@ -151,10 +150,9 @@ impl fold::ast_fold for CrateSetup {
 
 /// Generate/filter main function, add the list of commands, etc.
 pub fn ready_crate(sess: session::Session,
-                   crate: @ast::Crate) -> @ast::Crate {
+                   crate: ast::Crate) -> ast::Crate {
     let ctx = @mut ReadyCtx {
         sess: sess,
-        crate: crate,
         ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone()),
         path: ~[],
         fns: ~[]
@@ -162,7 +160,7 @@ pub fn ready_crate(sess: session::Session,
     let fold = CrateSetup {
         ctx: ctx,
     };
-    @fold.fold_crate(crate)
+    fold.fold_crate(crate)
 }
 
 pub fn compile_input(context: &BuildContext,
@@ -262,7 +260,7 @@ pub fn compile_input(context: &BuildContext,
     let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
     crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
 
-    find_and_install_dependencies(context, pkg_id, sess, exec, crate,
+    find_and_install_dependencies(context, pkg_id, sess, exec, &crate,
                                   |p| {
                                       debug!("a dependency: %s", p.to_str());
                                       // Pass the directory containing a dependency
@@ -289,10 +287,7 @@ pub fn compile_input(context: &BuildContext,
                                            pkg_id.path.to_str().to_managed())];
 
         debug!("link options: %?", link_options);
-        crate = @ast::Crate {
-            attrs: ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))],
-            .. (*crate).clone()
-        }
+        crate.attrs = ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))];
     }
 
     debug!("calling compile_crate_from_input, workspace = %s,
@@ -334,7 +329,7 @@ pub fn compile_crate_from_input(input: &Path,
                                 sess: session::Session,
 // Returns None if one of the flags that suppresses compilation output was
 // given
-                                crate: @ast::Crate) -> Option<Path> {
+                                crate: ast::Crate) -> Option<Path> {
     debug!("Calling build_output_filenames with %s, building library? %?",
            out_dir.to_str(), sess.building_library);
 
@@ -352,7 +347,7 @@ pub fn compile_crate_from_input(input: &Path,
     for lib in sess.opts.addl_lib_search_paths.iter() {
         debug!("an additional library: %s", lib.to_str());
     }
-    let analysis = driver::phase_3_run_analysis_passes(sess, crate);
+    let analysis = driver::phase_3_run_analysis_passes(sess, &crate);
     if driver::stop_after_phase_3(sess) { return None; }
     let translation = driver::phase_4_translate_to_llvm(sess, crate,
                                                         &analysis,