about summary refs log tree commit diff
path: root/src/libsyntax
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/libsyntax
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/libsyntax')
-rw-r--r--src/libsyntax/ext/expand.rs24
-rw-r--r--src/libsyntax/fold.rs4
-rw-r--r--src/libsyntax/parse/mod.rs4
-rw-r--r--src/libsyntax/parse/parser.rs4
-rwxr-xr-xsrc/libsyntax/syntaxbin0 -> 8435744 bytes
-rw-r--r--src/libsyntax/util/parser_testing.rs4
6 files changed, 20 insertions, 20 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index c62ebb9254e..0ca4f4fa1cd 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1143,8 +1143,8 @@ impl ast_fold for Injector {
 // program (ick). This should run before cfg stripping.
 pub fn inject_std_macros(parse_sess: @mut parse::ParseSess,
                          cfg: ast::CrateConfig,
-                         c: @Crate)
-                         -> @Crate {
+                         c: Crate)
+                         -> Crate {
     let sm = match parse_item_from_source_str(@"<std-macros>",
                                               std_macros(),
                                               cfg.clone(),
@@ -1157,7 +1157,7 @@ pub fn inject_std_macros(parse_sess: @mut parse::ParseSess,
     let injector = @Injector {
         sm: sm,
     } as @ast_fold;
-    @injector.fold_crate(c)
+    injector.fold_crate(c)
 }
 
 struct NoOpFolder {
@@ -1214,7 +1214,7 @@ impl ast_fold for MacroExpander {
 
 pub fn expand_crate(parse_sess: @mut parse::ParseSess,
                     cfg: ast::CrateConfig,
-                    c: &Crate) -> @Crate {
+                    c: Crate) -> Crate {
     // adding *another* layer of indirection here so that the block
     // visitor can swap out one exts table for another for the duration
     // of the block.  The cleaner alternative would be to thread the
@@ -1227,7 +1227,7 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess,
         cx: cx,
     } as @ast_fold;
 
-    let ret = @expander.fold_crate(c);
+    let ret = expander.fold_crate(c);
     parse_sess.span_diagnostic.handler().abort_if_errors();
     return ret;
 }
@@ -1534,7 +1534,7 @@ mod test {
         let a2_name = gensym("a2");
         let renamer = new_rename_folder(ast::Ident{name:a_name,ctxt:EMPTY_CTXT},
                                         a2_name);
-        let renamed_ast = renamer.fold_crate(item_ast);
+        let renamed_ast = renamer.fold_crate(item_ast.clone());
         let varrefs = @mut ~[];
         visit::walk_crate(&mut new_path_finder(varrefs), &renamed_ast, ());
         match varrefs {
@@ -1557,12 +1557,12 @@ mod test {
         }
     }
 
-    fn fake_print_crate(crate: @ast::Crate) {
+    fn fake_print_crate(crate: &ast::Crate) {
         let s = pprust::rust_printer(std::io::stderr(),get_ident_interner());
         pprust::print_crate_(s, crate);
     }
 
-    fn expand_crate_str(crate_str: @str) -> @ast::Crate {
+    fn expand_crate_str(crate_str: @str) -> ast::Crate {
         let (crate_ast,ps) = string_to_crate_and_sess(crate_str);
         // the cfg argument actually does matter, here...
         expand_crate(ps,~[],crate_ast)
@@ -1658,10 +1658,10 @@ mod test {
         let cr = expand_crate_str(teststr.to_managed());
         // find the bindings:
         let bindings = @mut ~[];
-        visit::walk_crate(&mut new_name_finder(bindings),cr,());
+        visit::walk_crate(&mut new_name_finder(bindings),&cr,());
         // find the varrefs:
         let varrefs = @mut ~[];
-        visit::walk_crate(&mut new_path_finder(varrefs),cr,());
+        visit::walk_crate(&mut new_path_finder(varrefs),&cr,());
         // must be one check clause for each binding:
         assert_eq!(bindings.len(),bound_connections.len());
         for (binding_idx,shouldmatch) in bound_connections.iter().enumerate() {
@@ -1721,7 +1721,7 @@ foo_module!()
         let cr = expand_crate_str(crate_str);
         // find the xx binding
         let bindings = @mut ~[];
-        visit::walk_crate(&mut new_name_finder(bindings), cr, ());
+        visit::walk_crate(&mut new_name_finder(bindings), &cr, ());
         let cxbinds : ~[&ast::Ident] =
             bindings.iter().filter(|b|{@"xx" == (ident_to_str(*b))}).collect();
         let cxbind = match cxbinds {
@@ -1731,7 +1731,7 @@ foo_module!()
         let resolved_binding = mtwt_resolve(*cxbind);
         // find all the xx varrefs:
         let varrefs = @mut ~[];
-        visit::walk_crate(&mut new_path_finder(varrefs), cr, ());
+        visit::walk_crate(&mut new_path_finder(varrefs), &cr, ());
         // the xx binding should bind all of the xx varrefs:
         for (idx,v) in varrefs.iter().filter(|p|{ p.segments.len() == 1
                                           && (@"xx" == (ident_to_str(&p.segments[0].identifier)))
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index a25f267c458..b823ff726ac 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -16,7 +16,7 @@ use opt_vec::OptVec;
 
 // We may eventually want to be able to fold over type parameters, too.
 pub trait ast_fold {
-    fn fold_crate(&self, c: &Crate) -> Crate {
+    fn fold_crate(&self, c: Crate) -> Crate {
         noop_fold_crate(c, self)
     }
 
@@ -691,7 +691,7 @@ pub fn noop_fold_mod<T:ast_fold>(m: &_mod, folder: &T) -> _mod {
     }
 }
 
-pub fn noop_fold_crate<T:ast_fold>(c: &Crate, folder: &T) -> Crate {
+pub fn noop_fold_crate<T:ast_fold>(c: Crate, folder: &T) -> Crate {
     let fold_meta_item = |x| fold_meta_item_(x, folder);
     let fold_attribute = |x| fold_attribute_(x, folder);
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 37f2f8345cd..a492a2283e3 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -73,7 +73,7 @@ pub fn parse_crate_from_file(
     input: &Path,
     cfg: ast::CrateConfig,
     sess: @mut ParseSess
-) -> @ast::Crate {
+) -> ast::Crate {
     new_parser_from_file(sess, /*bad*/ cfg.clone(), input).parse_crate_mod()
     // why is there no p.abort_if_errors here?
 }
@@ -83,7 +83,7 @@ pub fn parse_crate_from_source_str(
     source: @str,
     cfg: ast::CrateConfig,
     sess: @mut ParseSess
-) -> @ast::Crate {
+) -> ast::Crate {
     let p = new_parser_from_source_str(sess,
                                        /*bad*/ cfg.clone(),
                                        name,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 6c905c252c1..5a68e32a533 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5140,7 +5140,7 @@ impl Parser {
 
     // Parses a source module as a crate. This is the main
     // entry point for the parser.
-    pub fn parse_crate_mod(&self) -> @Crate {
+    pub fn parse_crate_mod(&self) -> Crate {
         let lo = self.span.lo;
         // parse the crate's inner attrs, maybe (oops) one
         // of the attrs of an item:
@@ -5149,7 +5149,7 @@ impl Parser {
         // parse the items inside the crate:
         let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
 
-        @ast::Crate {
+        ast::Crate {
             module: m,
             attrs: inner,
             config: self.cfg.clone(),
diff --git a/src/libsyntax/syntax b/src/libsyntax/syntax
new file mode 100755
index 00000000000..942ee88bd0e
--- /dev/null
+++ b/src/libsyntax/syntax
Binary files differdiff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index 23396c06a9a..59a6f0adeb4 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -47,14 +47,14 @@ fn with_error_checking_parse<T>(s: @str, f: &fn(&mut Parser) -> T) -> T {
 }
 
 // parse a string, return a crate.
-pub fn string_to_crate (source_str : @str) -> @ast::Crate {
+pub fn string_to_crate (source_str : @str) -> ast::Crate {
     do with_error_checking_parse(source_str) |p| {
         p.parse_crate_mod()
     }
 }
 
 // parse a string, return a crate and the ParseSess
-pub fn string_to_crate_and_sess (source_str : @str) -> (@ast::Crate,@mut ParseSess) {
+pub fn string_to_crate_and_sess (source_str : @str) -> (ast::Crate,@mut ParseSess) {
     let (p,ps) = string_to_parser_and_sess(source_str);
     (p.parse_crate_mod(),ps)
 }