Skip to content

Commit 2f07eb3

Browse files
trans: Internalize symbols at the trans-item level, without relying on LLVM.
1 parent 1ebfab5 commit 2f07eb3

File tree

11 files changed

+383
-265
lines changed

11 files changed

+383
-265
lines changed

src/librustc_trans/back/linker.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::process::Command;
1919
use context::SharedCrateContext;
2020

2121
use back::archive;
22-
use back::symbol_export::{self, ExportedSymbols};
22+
use back::symbol_export::ExportedSymbols;
2323
use rustc::middle::dependency_format::Linkage;
2424
use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
2525
use rustc_back::LinkerFlavor;
@@ -687,10 +687,8 @@ fn exported_symbols(scx: &SharedCrateContext,
687687
exported_symbols: &ExportedSymbols,
688688
crate_type: CrateType)
689689
-> Vec<String> {
690-
let export_threshold = symbol_export::crate_export_threshold(crate_type);
691-
692690
let mut symbols = Vec::new();
693-
exported_symbols.for_each_exported_symbol(LOCAL_CRATE, export_threshold, |name, _| {
691+
exported_symbols.for_each_exported_symbol(LOCAL_CRATE, |name, _, _| {
694692
symbols.push(name.to_owned());
695693
});
696694

@@ -702,7 +700,7 @@ fn exported_symbols(scx: &SharedCrateContext,
702700
// For each dependency that we are linking to statically ...
703701
if *dep_format == Linkage::Static {
704702
// ... we add its symbol list to our export list.
705-
exported_symbols.for_each_exported_symbol(cnum, export_threshold, |name, _| {
703+
exported_symbols.for_each_exported_symbol(cnum, |name, _, _| {
706704
symbols.push(name.to_owned());
707705
})
708706
}

src/librustc_trans/back/lto.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn run(cgcx: &CodegenContext,
6666
let export_threshold =
6767
symbol_export::crates_export_threshold(&cgcx.crate_types);
6868

69-
let symbol_filter = &|&(ref name, level): &(String, _)| {
69+
let symbol_filter = &|&(ref name, _, level): &(String, _, _)| {
7070
if symbol_export::is_below_threshold(level, export_threshold) {
7171
let mut bytes = Vec::with_capacity(name.len() + 1);
7272
bytes.extend(name.bytes());

src/librustc_trans/back/symbol_export.rs

+72-40
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use context::SharedCrateContext;
1211
use monomorphize::Instance;
13-
use rustc::util::nodemap::FxHashMap;
14-
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
12+
use rustc::util::nodemap::{FxHashMap, NodeSet};
13+
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE, INVALID_CRATE, CRATE_DEF_INDEX};
1514
use rustc::session::config;
1615
use rustc::ty::TyCtxt;
1716
use syntax::attr;
@@ -28,59 +27,87 @@ pub enum SymbolExportLevel {
2827
}
2928

3029
/// The set of symbols exported from each crate in the crate graph.
30+
#[derive(Debug)]
3131
pub struct ExportedSymbols {
32-
exports: FxHashMap<CrateNum, Vec<(String, SymbolExportLevel)>>,
32+
pub export_threshold: SymbolExportLevel,
33+
exports: FxHashMap<CrateNum, Vec<(String, DefId, SymbolExportLevel)>>,
34+
local_exports: NodeSet,
3335
}
3436

3537
impl ExportedSymbols {
3638
pub fn empty() -> ExportedSymbols {
3739
ExportedSymbols {
40+
export_threshold: SymbolExportLevel::C,
3841
exports: FxHashMap(),
42+
local_exports: NodeSet(),
3943
}
4044
}
4145

42-
pub fn compute<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>) -> ExportedSymbols {
43-
let mut local_crate: Vec<_> = scx
44-
.exported_symbols()
46+
pub fn compute<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
47+
local_exported_symbols: &NodeSet)
48+
-> ExportedSymbols {
49+
let export_threshold = crates_export_threshold(&tcx.sess.crate_types.borrow());
50+
51+
let mut local_crate: Vec<_> = local_exported_symbols
4552
.iter()
4653
.map(|&node_id| {
47-
scx.tcx().hir.local_def_id(node_id)
54+
tcx.hir.local_def_id(node_id)
4855
})
4956
.map(|def_id| {
50-
let name = scx.tcx().symbol_name(Instance::mono(scx.tcx(), def_id));
51-
let export_level = export_level(scx, def_id);
57+
let name = tcx.symbol_name(Instance::mono(tcx, def_id));
58+
let export_level = export_level(tcx, def_id);
5259
debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level);
53-
(str::to_owned(&name), export_level)
60+
(str::to_owned(&name), def_id, export_level)
5461
})
5562
.collect();
5663

57-
if scx.sess().entry_fn.borrow().is_some() {
58-
local_crate.push(("main".to_string(), SymbolExportLevel::C));
64+
let mut local_exports = local_crate
65+
.iter()
66+
.filter_map(|&(_, def_id, level)| {
67+
if is_below_threshold(level, export_threshold) {
68+
tcx.hir.as_local_node_id(def_id)
69+
} else {
70+
None
71+
}
72+
})
73+
.collect::<NodeSet>();
74+
75+
const INVALID_DEF_ID: DefId = DefId {
76+
krate: INVALID_CRATE,
77+
index: CRATE_DEF_INDEX,
78+
};
79+
80+
if let Some(_) = *tcx.sess.entry_fn.borrow() {
81+
local_crate.push(("main".to_string(),
82+
INVALID_DEF_ID,
83+
SymbolExportLevel::C));
5984
}
6085

61-
if let Some(id) = scx.sess().derive_registrar_fn.get() {
62-
let def_id = scx.tcx().hir.local_def_id(id);
86+
if let Some(id) = tcx.sess.derive_registrar_fn.get() {
87+
let def_id = tcx.hir.local_def_id(id);
6388
let idx = def_id.index;
64-
let disambiguator = scx.sess().local_crate_disambiguator();
65-
let registrar = scx.sess().generate_derive_registrar_symbol(disambiguator, idx);
66-
local_crate.push((registrar, SymbolExportLevel::C));
89+
let disambiguator = tcx.sess.local_crate_disambiguator();
90+
let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator, idx);
91+
local_crate.push((registrar, def_id, SymbolExportLevel::C));
92+
local_exports.insert(id);
6793
}
6894

69-
if scx.sess().crate_types.borrow().contains(&config::CrateTypeDylib) {
70-
local_crate.push((metadata_symbol_name(scx.tcx()),
95+
if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) {
96+
local_crate.push((metadata_symbol_name(tcx),
97+
INVALID_DEF_ID,
7198
SymbolExportLevel::Rust));
7299
}
73100

74101
let mut exports = FxHashMap();
75102
exports.insert(LOCAL_CRATE, local_crate);
76103

77-
for cnum in scx.sess().cstore.crates() {
104+
for cnum in tcx.sess.cstore.crates() {
78105
debug_assert!(cnum != LOCAL_CRATE);
79106

80107
// If this crate is a plugin and/or a custom derive crate, then
81108
// we're not even going to link those in so we skip those crates.
82-
if scx.sess().cstore.plugin_registrar_fn(cnum).is_some() ||
83-
scx.sess().cstore.derive_registrar_fn(cnum).is_some() {
109+
if tcx.sess.cstore.plugin_registrar_fn(cnum).is_some() ||
110+
tcx.sess.cstore.derive_registrar_fn(cnum).is_some() {
84111
continue;
85112
}
86113

@@ -92,16 +119,16 @@ impl ExportedSymbols {
92119
// Down below we'll hardwire all of the symbols to the `Rust` export
93120
// level instead.
94121
let special_runtime_crate =
95-
scx.tcx().is_panic_runtime(cnum.as_def_id()) ||
96-
scx.sess().cstore.is_compiler_builtins(cnum);
122+
tcx.is_panic_runtime(cnum.as_def_id()) ||
123+
tcx.sess.cstore.is_compiler_builtins(cnum);
97124

98-
let crate_exports = scx
99-
.sess()
125+
let crate_exports = tcx
126+
.sess
100127
.cstore
101128
.exported_symbols(cnum)
102129
.iter()
103130
.map(|&def_id| {
104-
let name = scx.tcx().symbol_name(Instance::mono(scx.tcx(), def_id));
131+
let name = tcx.symbol_name(Instance::mono(tcx, def_id));
105132
let export_level = if special_runtime_crate {
106133
// We can probably do better here by just ensuring that
107134
// it has hidden visibility rather than public
@@ -118,35 +145,41 @@ impl ExportedSymbols {
118145
SymbolExportLevel::Rust
119146
}
120147
} else {
121-
export_level(scx, def_id)
148+
export_level(tcx, def_id)
122149
};
123150
debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level);
124-
(str::to_owned(&name), export_level)
151+
(str::to_owned(&name), def_id, export_level)
125152
})
126153
.collect();
127154

128155
exports.insert(cnum, crate_exports);
129156
}
130157

131158
return ExportedSymbols {
132-
exports: exports
159+
export_threshold,
160+
exports,
161+
local_exports,
133162
};
134163

135-
fn export_level(scx: &SharedCrateContext,
164+
fn export_level(tcx: TyCtxt,
136165
sym_def_id: DefId)
137166
-> SymbolExportLevel {
138-
let attrs = scx.tcx().get_attrs(sym_def_id);
139-
if attr::contains_extern_indicator(scx.sess().diagnostic(), &attrs) {
167+
let attrs = tcx.get_attrs(sym_def_id);
168+
if attr::contains_extern_indicator(tcx.sess.diagnostic(), &attrs) {
140169
SymbolExportLevel::C
141170
} else {
142171
SymbolExportLevel::Rust
143172
}
144173
}
145174
}
146175

176+
pub fn local_exports(&self) -> &NodeSet {
177+
&self.local_exports
178+
}
179+
147180
pub fn exported_symbols(&self,
148181
cnum: CrateNum)
149-
-> &[(String, SymbolExportLevel)] {
182+
-> &[(String, DefId, SymbolExportLevel)] {
150183
match self.exports.get(&cnum) {
151184
Some(exports) => exports,
152185
None => &[]
@@ -155,13 +188,12 @@ impl ExportedSymbols {
155188

156189
pub fn for_each_exported_symbol<F>(&self,
157190
cnum: CrateNum,
158-
export_threshold: SymbolExportLevel,
159191
mut f: F)
160-
where F: FnMut(&str, SymbolExportLevel)
192+
where F: FnMut(&str, DefId, SymbolExportLevel)
161193
{
162-
for &(ref name, export_level) in self.exported_symbols(cnum) {
163-
if is_below_threshold(export_level, export_threshold) {
164-
f(&name, export_level)
194+
for &(ref name, def_id, export_level) in self.exported_symbols(cnum) {
195+
if is_below_threshold(export_level, self.export_threshold) {
196+
f(&name, def_id, export_level)
165197
}
166198
}
167199
}

0 commit comments

Comments
 (0)