Skip to content

Commit ff7b8d6

Browse files
committed
librustc: Implement lazy module loading.
1 parent 1bbb1e0 commit ff7b8d6

File tree

1 file changed

+80
-32
lines changed

1 file changed

+80
-32
lines changed

src/librustc/middle/resolve.rs

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -471,12 +471,18 @@ pub struct Module {
471471

472472
// The index of the import we're resolving.
473473
resolved_import_count: uint,
474+
475+
// Whether this module is populated. If not populated, any attempt to
476+
// access the children must be preceded with a
477+
// `populate_module_if_necessary` call.
478+
populated: bool,
474479
}
475480

476481
pub fn Module(parent_link: ParentLink,
477482
def_id: Option<def_id>,
478-
kind: ModuleKind)
479-
-> Module {
483+
kind: ModuleKind,
484+
external: bool)
485+
-> Module {
480486
Module {
481487
parent_link: parent_link,
482488
def_id: def_id,
@@ -488,6 +494,7 @@ pub fn Module(parent_link: ParentLink,
488494
import_resolutions: @mut HashMap::new(),
489495
glob_count: 0,
490496
resolved_import_count: 0,
497+
populated: !external,
491498
}
492499
}
493500

@@ -534,9 +541,10 @@ impl NameBindings {
534541
parent_link: ParentLink,
535542
def_id: Option<def_id>,
536543
kind: ModuleKind,
544+
external: bool,
537545
sp: span) {
538546
// Merges the module with the existing type def or creates a new one.
539-
let module_ = @mut Module(parent_link, def_id, kind);
547+
let module_ = @mut Module(parent_link, def_id, kind, external);
540548
match self.type_def {
541549
None => {
542550
self.type_def = Some(TypeNsDef {
@@ -563,10 +571,11 @@ impl NameBindings {
563571
parent_link: ParentLink,
564572
def_id: Option<def_id>,
565573
kind: ModuleKind,
574+
external: bool,
566575
_sp: span) {
567576
match self.type_def {
568577
None => {
569-
let module = @mut Module(parent_link, def_id, kind);
578+
let module = @mut Module(parent_link, def_id, kind, external);
570579
self.type_def = Some(TypeNsDef {
571580
privacy: privacy,
572581
module_def: Some(module),
@@ -577,7 +586,10 @@ impl NameBindings {
577586
Some(type_def) => {
578587
match type_def.module_def {
579588
None => {
580-
let module = @mut Module(parent_link, def_id, kind);
589+
let module = @mut Module(parent_link,
590+
def_id,
591+
kind,
592+
external);
581593
self.type_def = Some(TypeNsDef {
582594
privacy: privacy,
583595
module_def: Some(module),
@@ -799,6 +811,7 @@ pub fn Resolver(session: Session,
799811
NoParentLink,
800812
Some(def_id { crate: 0, node: 0 }),
801813
NormalModuleKind,
814+
false,
802815
crate.span);
803816

804817
let current_module = graph_root.get_module();
@@ -1164,6 +1177,7 @@ impl Resolver {
11641177
parent_link,
11651178
Some(def_id),
11661179
NormalModuleKind,
1180+
false,
11671181
sp);
11681182

11691183
let new_parent =
@@ -1186,6 +1200,7 @@ impl Resolver {
11861200
parent_link,
11871201
Some(def_id),
11881202
ExternModuleKind,
1203+
false,
11891204
sp);
11901205

11911206
ModuleReducedGraphParent(name_bindings.get_module())
@@ -1310,6 +1325,7 @@ impl Resolver {
13101325
parent_link,
13111326
Some(def_id),
13121327
ImplModuleKind,
1328+
false,
13131329
sp);
13141330

13151331
ModuleReducedGraphParent(
@@ -1367,6 +1383,7 @@ impl Resolver {
13671383
parent_link,
13681384
Some(local_def(item.id)),
13691385
TraitModuleKind,
1386+
false,
13701387
sp);
13711388
let module_parent = ModuleReducedGraphParent(name_bindings.
13721389
get_module());
@@ -1556,7 +1573,8 @@ impl Resolver {
15561573
(self.get_module_from_parent(parent), name);
15571574
let external_module = @mut Module(parent_link,
15581575
Some(def_id),
1559-
NormalModuleKind);
1576+
NormalModuleKind,
1577+
false);
15601578

15611579
parent.external_module_children.insert(
15621580
name,
@@ -1620,7 +1638,8 @@ impl Resolver {
16201638
let new_module = @mut Module(
16211639
BlockParentLink(parent_module, block_id),
16221640
None,
1623-
AnonymousModuleKind);
1641+
AnonymousModuleKind,
1642+
false);
16241643
parent_module.anonymous_children.insert(block_id, new_module);
16251644
new_parent = ModuleReducedGraphParent(new_module);
16261645
} else {
@@ -1656,6 +1675,7 @@ impl Resolver {
16561675
parent_link,
16571676
Some(def_id),
16581677
NormalModuleKind,
1678+
true,
16591679
dummy_sp());
16601680
}
16611681
}
@@ -1717,6 +1737,7 @@ impl Resolver {
17171737
parent_link,
17181738
Some(def_id),
17191739
TraitModuleKind,
1740+
true,
17201741
dummy_sp())
17211742
}
17221743
def_ty(_) => {
@@ -1755,8 +1776,19 @@ impl Resolver {
17551776
match def_like {
17561777
dl_def(def) => {
17571778
// Add the new child item, if necessary.
1758-
let optional_module = match def {
1759-
def_foreign_mod(*) => Some(root),
1779+
match def {
1780+
def_foreign_mod(def_id) => {
1781+
// Foreign modules have no names. Recur and populate
1782+
// eagerly.
1783+
do csearch::each_child_of_item(self.session.cstore,
1784+
def_id)
1785+
|def_like, child_ident| {
1786+
self.build_reduced_graph_for_external_crate_def(
1787+
root,
1788+
def_like,
1789+
child_ident)
1790+
}
1791+
}
17601792
_ => {
17611793
let (child_name_bindings, new_parent) =
17621794
self.add_child(ident,
@@ -1770,28 +1802,6 @@ impl Resolver {
17701802
self.session.str_of(ident),
17711803
ident,
17721804
new_parent);
1773-
1774-
/*println(fmt!(">>> child item added: %s",
1775-
self.session.str_of(ident)));*/
1776-
1777-
child_name_bindings.get_module_if_available()
1778-
}
1779-
};
1780-
1781-
match optional_module {
1782-
None => {}
1783-
Some(module) => {
1784-
do csearch::each_child_of_item(self.session.cstore,
1785-
def_id_of_def(def))
1786-
|def_like, child_ident| {
1787-
/*println(fmt!(">>> each_child_of_item: %s %s",
1788-
self.session.str_of(ident),
1789-
self.session.str_of(child_ident)));*/
1790-
self.build_reduced_graph_for_external_crate_def(
1791-
module,
1792-
def_like,
1793-
child_ident)
1794-
}
17951805
}
17961806
}
17971807
}
@@ -1844,6 +1854,7 @@ impl Resolver {
18441854
parent_link,
18451855
Some(def),
18461856
ImplModuleKind,
1857+
true,
18471858
dummy_sp());
18481859
type_module =
18491860
child_name_bindings.
@@ -1890,6 +1901,31 @@ impl Resolver {
18901901
}
18911902
}
18921903

1904+
/// Builds the reduced graph rooted at the given external module.
1905+
fn populate_external_module(@mut self, module: @mut Module) {
1906+
let def_id = match module.def_id {
1907+
None => return,
1908+
Some(def_id) => def_id,
1909+
};
1910+
1911+
do csearch::each_child_of_item(self.session.cstore, def_id)
1912+
|def_like, child_ident| {
1913+
self.build_reduced_graph_for_external_crate_def(module,
1914+
def_like,
1915+
child_ident)
1916+
}
1917+
module.populated = true
1918+
}
1919+
1920+
/// Ensures that the reduced graph rooted at the given external module
1921+
/// is built, building it if it is not.
1922+
fn populate_module_if_necessary(@mut self, module: @mut Module) {
1923+
if !module.populated {
1924+
self.populate_external_module(module)
1925+
}
1926+
assert!(module.populated)
1927+
}
1928+
18931929
/// Builds the reduced graph rooted at the 'use' directive for an external
18941930
/// crate.
18951931
pub fn build_reduced_graph_for_external_crate(@mut self,
@@ -1999,6 +2035,7 @@ impl Resolver {
19992035
self.module_to_str(module_));
20002036
self.resolve_imports_for_module(module_);
20012037

2038+
self.populate_module_if_necessary(module_);
20022039
for (_, &child_node) in module_.children.iter() {
20032040
match child_node.get_module_if_available() {
20042041
None => {
@@ -2224,6 +2261,7 @@ impl Resolver {
22242261
let mut type_result = UnknownResult;
22252262

22262263
// Search for direct children of the containing module.
2264+
self.populate_module_if_necessary(containing_module);
22272265
match containing_module.children.find(&source) {
22282266
None => {
22292267
// Continue.
@@ -2542,6 +2580,7 @@ impl Resolver {
25422580
};
25432581

25442582
// Add all children from the containing module.
2583+
self.populate_module_if_necessary(containing_module);
25452584
for (&ident, name_bindings) in containing_module.children.iter() {
25462585
merge_import_resolution(ident, *name_bindings);
25472586
}
@@ -2775,6 +2814,7 @@ impl Resolver {
27752814

27762815
// The current module node is handled specially. First, check for
27772816
// its immediate children.
2817+
self.populate_module_if_necessary(module_);
27782818
match module_.children.find(&name) {
27792819
Some(name_bindings)
27802820
if name_bindings.defined_in_namespace(namespace) => {
@@ -3029,6 +3069,7 @@ impl Resolver {
30293069
self.module_to_str(module_));
30303070

30313071
// First, check the direct children of the module.
3072+
self.populate_module_if_necessary(module_);
30323073
match module_.children.find(&name) {
30333074
Some(name_bindings)
30343075
if name_bindings.defined_in_namespace(namespace) => {
@@ -3118,6 +3159,7 @@ impl Resolver {
31183159
}
31193160

31203161
// Descend into children and anonymous children.
3162+
self.populate_module_if_necessary(module_);
31213163
for (_, &child_node) in module_.children.iter() {
31223164
match child_node.get_module_if_available() {
31233165
None => {
@@ -3176,6 +3218,7 @@ impl Resolver {
31763218
}
31773219

31783220
self.record_exports_for_module(module_);
3221+
self.populate_module_if_necessary(module_);
31793222

31803223
for (_, &child_name_bindings) in module_.children.iter() {
31813224
match child_name_bindings.get_module_if_available() {
@@ -3289,6 +3332,7 @@ impl Resolver {
32893332
// Nothing to do.
32903333
}
32913334
Some(name) => {
3335+
self.populate_module_if_necessary(orig_module);
32923336
match orig_module.children.find(&name) {
32933337
None => {
32943338
debug!("!!! (with scope) didn't find `%s` in `%s`",
@@ -4569,6 +4613,7 @@ impl Resolver {
45694613
xray: XrayFlag)
45704614
-> NameDefinition {
45714615
// First, search children.
4616+
self.populate_module_if_necessary(containing_module);
45724617
match containing_module.children.find(&name) {
45734618
Some(child_name_bindings) => {
45744619
match (child_name_bindings.def_for_namespace(namespace),
@@ -5233,7 +5278,9 @@ impl Resolver {
52335278
}
52345279

52355280
// Look for trait children.
5236-
for (_, &child_name_bindings) in search_module.children.iter() {
5281+
self.populate_module_if_necessary(search_module);
5282+
for (_, &child_name_bindings) in
5283+
search_module.children.iter() {
52375284
match child_name_bindings.def_for_namespace(TypeNS) {
52385285
Some(def) => {
52395286
match def {
@@ -5432,6 +5479,7 @@ impl Resolver {
54325479
debug!("Dump of module `%s`:", self.module_to_str(module_));
54335480

54345481
debug!("Children:");
5482+
self.populate_module_if_necessary(module_);
54355483
for (&name, _) in module_.children.iter() {
54365484
debug!("* %s", self.session.str_of(name));
54375485
}

0 commit comments

Comments
 (0)