Skip to content

Commit 8e34a8e

Browse files
Definitions: Extract DefPath interning into its own data structure.
1 parent 87b4071 commit 8e34a8e

File tree

1 file changed

+85
-23
lines changed

1 file changed

+85
-23
lines changed

src/librustc/hir/map/definitions.rs

Lines changed: 85 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,92 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
12+
//! For each definition, we track the following data. A definition
13+
//! here is defined somewhat circularly as "something with a def-id",
14+
//! but it generally corresponds to things like structs, enums, etc.
15+
//! There are also some rather random cases (like const initializer
16+
//! expressions) that are mostly just leftovers.
17+
18+
19+
1120
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
1221
use rustc_data_structures::fx::FxHashMap;
1322
use rustc_data_structures::stable_hasher::StableHasher;
23+
use serialize::{Encodable, Decodable, Encoder, Decoder};
1424
use std::fmt::Write;
1525
use std::hash::{Hash, Hasher};
1626
use syntax::ast;
1727
use syntax::symbol::{Symbol, InternedString};
1828
use ty::TyCtxt;
1929
use util::nodemap::NodeMap;
2030

21-
//! For each definition, we track the following data. A definition
22-
//! here is defined somewhat circularly as "something with a def-id",
23-
//! but it generally corresponds to things like structs, enums, etc.
24-
//! There are also some rather random cases (like const initializer
25-
//! expressions) that are mostly just leftovers.
31+
#[derive(Clone)]
32+
pub struct DefPathTable {
33+
index_to_key: Vec<DefKey>,
34+
key_to_index: FxHashMap<DefKey, DefIndex>,
35+
}
36+
37+
impl DefPathTable {
38+
fn insert(&mut self, key: DefKey) -> DefIndex {
39+
let index = DefIndex::new(self.index_to_key.len());
40+
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
41+
self.index_to_key.push(key.clone());
42+
self.key_to_index.insert(key, index);
43+
index
44+
}
45+
46+
#[inline(always)]
47+
pub fn def_key(&self, index: DefIndex) -> DefKey {
48+
self.index_to_key[index.as_usize()].clone()
49+
}
50+
51+
#[inline(always)]
52+
pub fn def_index_for_def_key(&self, key: &DefKey) -> Option<DefIndex> {
53+
self.key_to_index.get(key).cloned()
54+
}
55+
56+
#[inline(always)]
57+
pub fn contains_key(&self, key: &DefKey) -> bool {
58+
self.key_to_index.contains_key(key)
59+
}
60+
61+
/// Returns the path from the crate root to `index`. The root
62+
/// nodes are not included in the path (i.e., this will be an
63+
/// empty vector for the crate root). For an inlined item, this
64+
/// will be the path of the item in the external crate (but the
65+
/// path will begin with the path to the external crate).
66+
pub fn def_path(&self, index: DefIndex) -> DefPath {
67+
DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p))
68+
}
69+
}
70+
71+
72+
impl Encodable for DefPathTable {
73+
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
74+
self.index_to_key.encode(s)
75+
}
76+
}
77+
78+
impl Decodable for DefPathTable {
79+
fn decode<D: Decoder>(d: &mut D) -> Result<DefPathTable, D::Error> {
80+
let index_to_key: Vec<DefKey> = Decodable::decode(d)?;
81+
let key_to_index = index_to_key.iter()
82+
.enumerate()
83+
.map(|(index, key)| (key.clone(), DefIndex::new(index)))
84+
.collect();
85+
Ok(DefPathTable {
86+
index_to_key: index_to_key,
87+
key_to_index: key_to_index,
88+
})
89+
}
90+
}
2691

2792

2893
/// The definition table containing node definitions
2994
#[derive(Clone)]
3095
pub struct Definitions {
31-
data: Vec<DefKey>,
32-
key_map: FxHashMap<DefKey, DefIndex>,
96+
table: DefPathTable,
3397
node_to_def_index: NodeMap<DefIndex>,
3498
def_index_to_node: Vec<ast::NodeId>,
3599
}
@@ -214,24 +278,26 @@ impl Definitions {
214278
/// Create new empty definition map.
215279
pub fn new() -> Definitions {
216280
Definitions {
217-
data: vec![],
218-
key_map: FxHashMap(),
281+
table: DefPathTable {
282+
index_to_key: vec![],
283+
key_to_index: FxHashMap(),
284+
},
219285
node_to_def_index: NodeMap(),
220286
def_index_to_node: vec![],
221287
}
222288
}
223289

224290
/// Get the number of definitions.
225291
pub fn len(&self) -> usize {
226-
self.data.len()
292+
self.def_index_to_node.len()
227293
}
228294

229295
pub fn def_key(&self, index: DefIndex) -> DefKey {
230-
self.data[index.as_usize()].key.clone()
296+
self.table.def_key(index)
231297
}
232298

233299
pub fn def_index_for_def_key(&self, key: DefKey) -> Option<DefIndex> {
234-
self.key_map.get(&key).cloned()
300+
self.table.def_index_for_def_key(&key)
235301
}
236302

237303
/// Returns the path from the crate root to `index`. The root
@@ -257,8 +323,7 @@ impl Definitions {
257323

258324
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
259325
if def_id.krate == LOCAL_CRATE {
260-
assert!(def_id.index.as_usize() < self.data.len());
261-
// Some(self.data[def_id.index.as_usize()].node_id)
326+
assert!(def_id.index.as_usize() < self.def_index_to_node.len());
262327
Some(self.def_index_to_node[def_id.index.as_usize()])
263328
} else {
264329
None
@@ -278,7 +343,7 @@ impl Definitions {
278343
"adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
279344
node_id,
280345
data,
281-
self.data[self.node_to_def_index[&node_id].as_usize()]);
346+
self.table.def_key(self.node_to_def_index[&node_id]));
282347

283348
assert!(parent.is_some() ^ match data {
284349
DefPathData::CrateRoot | DefPathData::InlinedRoot(_) => true,
@@ -295,21 +360,18 @@ impl Definitions {
295360
}
296361
};
297362

298-
while self.key_map.contains_key(&key) {
363+
while self.table.contains_key(&key) {
299364
key.disambiguated_data.disambiguator += 1;
300365
}
301366

302367
debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
303368

304369
// Create the definition.
305-
let index = DefIndex::new(self.data.len());
306-
self.data.push(DefData { key: key.clone() });
307-
self.def_index_to_node.push(node_id);
308-
debug!("create_def_with_parent: node_to_def_index[{:?}] = {:?}", node_id, index);
370+
let index = self.table.insert(key);
371+
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
309372
self.node_to_def_index.insert(node_id, index);
310-
debug!("create_def_with_parent: key_map[{:?}] = {:?}", key, index);
311-
self.key_map.insert(key, index);
312-
373+
assert_eq!(index.as_usize(), self.def_index_to_node.len());
374+
self.def_index_to_node.push(node_id);
313375

314376
index
315377
}

0 commit comments

Comments
 (0)