Skip to content

Commit a8514d3

Browse files
committed
resolve: use arena allocation instead of reference counting for Modules to fix memory leaks from Rc cycles
1 parent 69e1f57 commit a8514d3

File tree

5 files changed

+260
-245
lines changed

5 files changed

+260
-245
lines changed

mk/crates.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ DEPS_rustc_lint := rustc log syntax
103103
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
104104
DEPS_rustc_metadata := rustc rustc_front syntax rbml
105105
DEPS_rustc_mir := rustc rustc_front syntax
106-
DEPS_rustc_resolve := rustc rustc_front log syntax
106+
DEPS_rustc_resolve := arena rustc rustc_front log syntax
107107
DEPS_rustc_platform_intrinsics := rustc rustc_llvm
108108
DEPS_rustc_plugin := rustc rustc_metadata syntax
109109
DEPS_rustc_privacy := rustc rustc_front log syntax

src/librustc_resolve/build_reduced_graph.rs

+54-58
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use Module;
2121
use Namespace::{TypeNS, ValueNS};
2222
use NameBindings;
2323
use {names_to_string, module_to_string};
24-
use ParentLink::{self, ModuleParentLink, BlockParentLink};
24+
use ParentLink::{ModuleParentLink, BlockParentLink};
2525
use Resolver;
2626
use resolve_imports::Shadowable;
2727
use {resolve_error, resolve_struct_error, ResolutionError};
@@ -52,7 +52,6 @@ use rustc_front::intravisit::{self, Visitor};
5252

5353
use std::mem::replace;
5454
use std::ops::{Deref, DerefMut};
55-
use std::rc::Rc;
5655

5756
// Specifies how duplicates should be handled when adding a child item if
5857
// another item exists with the same name in some namespace.
@@ -86,7 +85,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
8685
/// Constructs the reduced graph for the entire crate.
8786
fn build_reduced_graph(self, krate: &hir::Crate) {
8887
let mut visitor = BuildReducedGraphVisitor {
89-
parent: self.graph_root.clone(),
88+
parent: self.graph_root,
9089
builder: self,
9190
};
9291
intravisit::walk_crate(&mut visitor, krate);
@@ -97,12 +96,12 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
9796
/// Returns the child's corresponding name bindings.
9897
fn add_child(&self,
9998
name: Name,
100-
parent: &Rc<Module>,
99+
parent: Module<'b>,
101100
duplicate_checking_mode: DuplicateCheckingMode,
102101
// For printing errors
103102
sp: Span)
104-
-> NameBindings {
105-
self.check_for_conflicts_between_external_crates_and_items(&**parent, name, sp);
103+
-> NameBindings<'b> {
104+
self.check_for_conflicts_between_external_crates_and_items(parent, name, sp);
106105

107106
// Add or reuse the child.
108107
let child = parent.children.borrow().get(&name).cloned();
@@ -178,12 +177,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
178177
return false;
179178
}
180179

181-
fn get_parent_link(&mut self, parent: &Rc<Module>, name: Name) -> ParentLink {
182-
ModuleParentLink(Rc::downgrade(parent), name)
183-
}
184-
185180
/// Constructs the reduced graph for one item.
186-
fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) -> Rc<Module> {
181+
fn build_reduced_graph_for_item(&mut self, item: &Item, parent: Module<'b>) -> Module<'b> {
187182
let name = item.name;
188183
let sp = item.span;
189184
let is_public = item.vis == hir::Public;
@@ -238,7 +233,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
238233
}
239234

240235
let subclass = SingleImport(binding, source_name);
241-
self.build_import_directive(&**parent,
236+
self.build_import_directive(parent,
242237
module_path,
243238
subclass,
244239
view_path.span,
@@ -288,7 +283,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
288283
(module_path.to_vec(), name, rename)
289284
}
290285
};
291-
self.build_import_directive(&**parent,
286+
self.build_import_directive(parent,
292287
module_path,
293288
SingleImport(rename, name),
294289
source_item.span,
@@ -298,7 +293,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
298293
}
299294
}
300295
ViewPathGlob(_) => {
301-
self.build_import_directive(&**parent,
296+
self.build_import_directive(parent,
302297
module_path,
303298
GlobImport,
304299
view_path.span,
@@ -307,7 +302,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
307302
shadowable);
308303
}
309304
}
310-
parent.clone()
305+
parent
311306
}
312307

313308
ItemExternCrate(_) => {
@@ -319,32 +314,32 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
319314
index: CRATE_DEF_INDEX,
320315
};
321316
self.external_exports.insert(def_id);
322-
let parent_link = ModuleParentLink(Rc::downgrade(parent), name);
317+
let parent_link = ModuleParentLink(parent, name);
323318
let def = DefMod(def_id);
324-
let external_module = Module::new(parent_link, Some(def), false, true);
319+
let external_module = self.new_module(parent_link, Some(def), false, true);
325320

326321
debug!("(build reduced graph for item) found extern `{}`",
327322
module_to_string(&*external_module));
328-
self.check_for_conflicts_for_external_crate(&parent, name, sp);
323+
self.check_for_conflicts_for_external_crate(parent, name, sp);
329324
parent.external_module_children
330325
.borrow_mut()
331-
.insert(name, external_module.clone());
326+
.insert(name, external_module);
332327
self.build_reduced_graph_for_external_crate(&external_module);
333328
}
334-
parent.clone()
329+
parent
335330
}
336331

337332
ItemMod(..) => {
338333
let name_bindings = self.add_child(name, parent, ForbidDuplicateTypes, sp);
339334

340-
let parent_link = self.get_parent_link(parent, name);
335+
let parent_link = ModuleParentLink(parent, name);
341336
let def = DefMod(self.ast_map.local_def_id(item.id));
342-
let module = Module::new(parent_link, Some(def), false, is_public);
337+
let module = self.new_module(parent_link, Some(def), false, is_public);
343338
name_bindings.define_module(module.clone(), sp);
344339
module
345340
}
346341

347-
ItemForeignMod(..) => parent.clone(),
342+
ItemForeignMod(..) => parent,
348343

349344
// These items live in the value namespace.
350345
ItemStatic(_, m, _) => {
@@ -354,19 +349,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
354349
name_bindings.define_value(DefStatic(self.ast_map.local_def_id(item.id), mutbl),
355350
sp,
356351
modifiers);
357-
parent.clone()
352+
parent
358353
}
359354
ItemConst(_, _) => {
360355
self.add_child(name, parent, ForbidDuplicateValues, sp)
361356
.define_value(DefConst(self.ast_map.local_def_id(item.id)), sp, modifiers);
362-
parent.clone()
357+
parent
363358
}
364359
ItemFn(_, _, _, _, _, _) => {
365360
let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
366361

367362
let def = DefFn(self.ast_map.local_def_id(item.id), false);
368363
name_bindings.define_value(def, sp, modifiers);
369-
parent.clone()
364+
parent
370365
}
371366

372367
// These items live in the type namespace.
@@ -376,11 +371,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
376371
ForbidDuplicateTypes,
377372
sp);
378373

379-
let parent_link = self.get_parent_link(parent, name);
374+
let parent_link = ModuleParentLink(parent, name);
380375
let def = DefTy(self.ast_map.local_def_id(item.id), false);
381-
let module = Module::new(parent_link, Some(def), false, is_public);
376+
let module = self.new_module(parent_link, Some(def), false, is_public);
382377
name_bindings.define_module(module, sp);
383-
parent.clone()
378+
parent
384379
}
385380

386381
ItemEnum(ref enum_definition, _) => {
@@ -389,9 +384,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
389384
ForbidDuplicateTypes,
390385
sp);
391386

392-
let parent_link = self.get_parent_link(parent, name);
387+
let parent_link = ModuleParentLink(parent, name);
393388
let def = DefTy(self.ast_map.local_def_id(item.id), true);
394-
let module = Module::new(parent_link, Some(def), false, is_public);
389+
let module = self.new_module(parent_link, Some(def), false, is_public);
395390
name_bindings.define_module(module.clone(), sp);
396391

397392
let variant_modifiers = if is_public {
@@ -404,7 +399,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
404399
self.build_reduced_graph_for_variant(variant, item_def_id,
405400
&module, variant_modifiers);
406401
}
407-
parent.clone()
402+
parent
408403
}
409404

410405
// These items live in both the type and value namespaces.
@@ -444,11 +439,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
444439
let item_def_id = self.ast_map.local_def_id(item.id);
445440
self.structs.insert(item_def_id, named_fields);
446441

447-
parent.clone()
442+
parent
448443
}
449444

450445
ItemDefaultImpl(_, _) |
451-
ItemImpl(..) => parent.clone(),
446+
ItemImpl(..) => parent,
452447

453448
ItemTrait(_, _, _, ref items) => {
454449
let name_bindings = self.add_child(name,
@@ -459,9 +454,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
459454
let def_id = self.ast_map.local_def_id(item.id);
460455

461456
// Add all the items within to a new module.
462-
let parent_link = self.get_parent_link(parent, name);
457+
let parent_link = ModuleParentLink(parent, name);
463458
let def = DefTrait(def_id);
464-
let module_parent = Module::new(parent_link, Some(def), false, is_public);
459+
let module_parent = self.new_module(parent_link, Some(def), false, is_public);
465460
name_bindings.define_module(module_parent.clone(), sp);
466461

467462
// Add the names of all the items to the trait info.
@@ -494,7 +489,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
494489
self.trait_item_map.insert((trait_item.name, def_id), trait_item_def_id);
495490
}
496491

497-
parent.clone()
492+
parent
498493
}
499494
}
500495
}
@@ -504,7 +499,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
504499
fn build_reduced_graph_for_variant(&mut self,
505500
variant: &Variant,
506501
item_id: DefId,
507-
parent: &Rc<Module>,
502+
parent: Module<'b>,
508503
variant_modifiers: DefModifiers) {
509504
let name = variant.node.name;
510505
let is_exported = if variant.node.data.is_struct() {
@@ -534,7 +529,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
534529
/// Constructs the reduced graph for one foreign item.
535530
fn build_reduced_graph_for_foreign_item(&mut self,
536531
foreign_item: &ForeignItem,
537-
parent: &Rc<Module>) {
532+
parent: Module<'b>) {
538533
let name = foreign_item.name;
539534
let is_public = foreign_item.vis == hir::Public;
540535
let modifiers = if is_public {
@@ -555,30 +550,30 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
555550
name_bindings.define_value(def, foreign_item.span, modifiers);
556551
}
557552

558-
fn build_reduced_graph_for_block(&mut self, block: &Block, parent: &Rc<Module>) -> Rc<Module> {
553+
fn build_reduced_graph_for_block(&mut self, block: &Block, parent: Module<'b>) -> Module<'b> {
559554
if self.block_needs_anonymous_module(block) {
560555
let block_id = block.id;
561556

562557
debug!("(building reduced graph for block) creating a new anonymous module for block \
563558
{}",
564559
block_id);
565560

566-
let parent_link = BlockParentLink(Rc::downgrade(parent), block_id);
567-
let new_module = Module::new(parent_link, None, false, false);
568-
parent.anonymous_children.borrow_mut().insert(block_id, new_module.clone());
561+
let parent_link = BlockParentLink(parent, block_id);
562+
let new_module = self.new_module(parent_link, None, false, false);
563+
parent.anonymous_children.borrow_mut().insert(block_id, new_module);
569564
new_module
570565
} else {
571-
parent.clone()
566+
parent
572567
}
573568
}
574569

575570
fn handle_external_def(&mut self,
576571
def: Def,
577572
vis: Visibility,
578-
child_name_bindings: &NameBindings,
573+
child_name_bindings: &NameBindings<'b>,
579574
final_ident: &str,
580575
name: Name,
581-
new_parent: &Rc<Module>) {
576+
new_parent: Module<'b>) {
582577
debug!("(building reduced graph for external crate) building external def {}, priv {:?}",
583578
final_ident,
584579
vis);
@@ -609,8 +604,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
609604
debug!("(building reduced graph for external crate) building module {} {}",
610605
final_ident,
611606
is_public);
612-
let parent_link = self.get_parent_link(new_parent, name);
613-
let module = Module::new(parent_link, Some(def), true, is_public);
607+
let parent_link = ModuleParentLink(new_parent, name);
608+
let module = self.new_module(parent_link, Some(def), true, is_public);
614609
child_name_bindings.define_module(module, DUMMY_SP);
615610
}
616611
}
@@ -681,8 +676,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
681676
}
682677

683678
// Define a module if necessary.
684-
let parent_link = self.get_parent_link(new_parent, name);
685-
let module = Module::new(parent_link, Some(def), true, is_public);
679+
let parent_link = ModuleParentLink(new_parent, name);
680+
let module = self.new_module(parent_link, Some(def), true, is_public);
686681
child_name_bindings.define_module(module, DUMMY_SP);
687682
}
688683
DefTy(..) | DefAssociatedTy(..) => {
@@ -728,7 +723,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
728723

729724
/// Builds the reduced graph for a single item in an external crate.
730725
fn build_reduced_graph_for_external_crate_def(&mut self,
731-
root: &Rc<Module>,
726+
root: Module<'b>,
732727
xcdef: ChildItem) {
733728
match xcdef.def {
734729
DlDef(def) => {
@@ -766,9 +761,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
766761
}
767762

768763
/// Builds the reduced graph rooted at the given external module.
769-
fn populate_external_module(&mut self, module: &Rc<Module>) {
764+
fn populate_external_module(&mut self, module: Module<'b>) {
770765
debug!("(populating external module) attempting to populate {}",
771-
module_to_string(&**module));
766+
module_to_string(module));
772767

773768
let def_id = match module.def_id() {
774769
None => {
@@ -788,7 +783,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
788783

789784
/// Ensures that the reduced graph rooted at the given external module
790785
/// is built, building it if it is not.
791-
fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
786+
fn populate_module_if_necessary(&mut self, module: Module<'b>) {
792787
if !module.populated.get() {
793788
self.populate_external_module(module)
794789
}
@@ -797,7 +792,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
797792

798793
/// Builds the reduced graph rooted at the 'use' directive for an external
799794
/// crate.
800-
fn build_reduced_graph_for_external_crate(&mut self, root: &Rc<Module>) {
795+
fn build_reduced_graph_for_external_crate(&mut self, root: Module<'b>) {
801796
let root_cnum = root.def_id().unwrap().krate;
802797
for child in self.session.cstore.crate_top_level_items(root_cnum) {
803798
self.build_reduced_graph_for_external_crate_def(root, child);
@@ -806,7 +801,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
806801

807802
/// Creates and adds an import directive to the given module.
808803
fn build_import_directive(&mut self,
809-
module_: &Module,
804+
module_: Module<'b>,
810805
module_path: Vec<Name>,
811806
subclass: ImportDirectiveSubclass,
812807
span: Span,
@@ -866,7 +861,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
866861

867862
struct BuildReducedGraphVisitor<'a, 'b: 'a, 'tcx: 'b> {
868863
builder: GraphBuilder<'a, 'b, 'tcx>,
869-
parent: Rc<Module>,
864+
parent: Module<'b>,
870865
}
871866

872867
impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
@@ -897,6 +892,7 @@ pub fn build_reduced_graph(resolver: &mut Resolver, krate: &hir::Crate) {
897892
GraphBuilder { resolver: resolver }.build_reduced_graph(krate);
898893
}
899894

900-
pub fn populate_module_if_necessary(resolver: &mut Resolver, module: &Rc<Module>) {
895+
pub fn populate_module_if_necessary<'a, 'tcx>(resolver: &mut Resolver<'a, 'tcx>,
896+
module: Module<'a>) {
901897
GraphBuilder { resolver: resolver }.populate_module_if_necessary(module);
902898
}

0 commit comments

Comments
 (0)