Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2536302

Browse files
committedMar 16, 2017
Allocate numerical values of DefIndexes from two seperate ranges.
This way we can have all item-likes occupy a dense range of DefIndexes, which is good for making fast, array-based dictionaries.
1 parent 2efd813 commit 2536302

File tree

7 files changed

+237
-72
lines changed

7 files changed

+237
-72
lines changed
 

‎src/librustc/hir/def_id.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,33 +78,86 @@ impl serialize::UseSpecializedDecodable for CrateNum {
7878
/// A DefIndex is an index into the hir-map for a crate, identifying a
7979
/// particular definition. It should really be considered an interned
8080
/// shorthand for a particular DefPath.
81+
///
82+
/// At the moment we are allocating the numerical values of DefIndexes into two
83+
/// ranges: the "low" range (starting at zero) and the "high" range (starting at
84+
/// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
85+
/// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
86+
/// consequently use a simple array for lookup tables keyed by DefIndex and
87+
/// known to be densely populated. This is especially important for the HIR map.
88+
///
89+
/// Since the DefIndex is mostly treated as an opaque ID, you probably don't
90+
/// have to care about these ranges.
8191
#[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
8292
RustcDecodable, Hash, Copy)]
8393
pub struct DefIndex(u32);
8494

8595
impl DefIndex {
96+
#[inline]
8697
pub fn new(x: usize) -> DefIndex {
8798
assert!(x < (u32::MAX as usize));
8899
DefIndex(x as u32)
89100
}
90101

102+
#[inline]
91103
pub fn from_u32(x: u32) -> DefIndex {
92104
DefIndex(x)
93105
}
94106

107+
#[inline]
95108
pub fn as_usize(&self) -> usize {
96109
self.0 as usize
97110
}
98111

112+
#[inline]
99113
pub fn as_u32(&self) -> u32 {
100114
self.0
101115
}
116+
117+
#[inline]
118+
pub fn address_space(&self) -> DefIndexAddressSpace {
119+
if self.0 < DEF_INDEX_HI_START.0 {
120+
DefIndexAddressSpace::Low
121+
} else {
122+
DefIndexAddressSpace::High
123+
}
124+
}
125+
126+
/// Converts this DefIndex into a zero-based array index.
127+
/// This index is the offset within the given "range" of the DefIndex,
128+
/// that is, if the DefIndex is part of the "high" range, the resulting
129+
/// index will be (DefIndex - DEF_INDEX_HI_START).
130+
#[inline]
131+
pub fn as_array_index(&self) -> usize {
132+
(self.0 & !DEF_INDEX_HI_START.0) as usize
133+
}
102134
}
103135

136+
/// The start of the "high" range of DefIndexes.
137+
const DEF_INDEX_HI_START: DefIndex = DefIndex(1 << 31);
138+
104139
/// The crate root is always assigned index 0 by the AST Map code,
105140
/// thanks to `NodeCollector::new`.
106141
pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);
107142

143+
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
144+
pub enum DefIndexAddressSpace {
145+
Low = 0,
146+
High = 1,
147+
}
148+
149+
impl DefIndexAddressSpace {
150+
#[inline]
151+
pub fn index(&self) -> usize {
152+
*self as usize
153+
}
154+
155+
#[inline]
156+
pub fn start(&self) -> usize {
157+
self.index() * DEF_INDEX_HI_START.as_usize()
158+
}
159+
}
160+
108161
/// A DefId identifies a particular *definition*, by combining a crate
109162
/// index and a def index.
110163
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)]

‎src/librustc/hir/lowering.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
// in the HIR, especially for multiple identifiers.
4242

4343
use hir;
44-
use hir::map::{Definitions, DefKey};
44+
use hir::map::{Definitions, DefKey, REGULAR_SPACE};
4545
use hir::map::definitions::DefPathData;
4646
use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX};
4747
use hir::def::{Def, PathResolution};
@@ -2689,7 +2689,10 @@ impl<'a> LoweringContext<'a> {
26892689
let def_id = {
26902690
let defs = self.resolver.definitions();
26912691
let def_path_data = DefPathData::Binding(name.as_str());
2692-
let def_index = defs.create_def_with_parent(parent_def, id, def_path_data);
2692+
let def_index = defs.create_def_with_parent(parent_def,
2693+
id,
2694+
def_path_data,
2695+
REGULAR_SPACE);
26932696
DefId::local(def_index)
26942697
};
26952698

‎src/librustc/hir/map/def_collector.rs

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
// except according to those terms.
1010

1111
use hir::map::definitions::*;
12-
use hir::def_id::{CRATE_DEF_INDEX, DefIndex};
12+
use hir::def_id::{CRATE_DEF_INDEX, DefIndex, DefIndexAddressSpace};
1313

1414
use syntax::ast::*;
1515
use syntax::ext::hygiene::Mark;
1616
use syntax::visit;
1717
use syntax::symbol::{Symbol, keywords};
1818

19+
use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE};
20+
1921
/// Creates def ids for nodes in the AST.
2022
pub struct DefCollector<'a> {
2123
definitions: &'a mut Definitions,
@@ -39,23 +41,31 @@ impl<'a> DefCollector<'a> {
3941
}
4042

4143
pub fn collect_root(&mut self) {
42-
let root = self.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot);
44+
let root = self.create_def_with_parent(None,
45+
CRATE_NODE_ID,
46+
DefPathData::CrateRoot,
47+
ITEM_LIKE_SPACE);
4348
assert_eq!(root, CRATE_DEF_INDEX);
4449
self.parent_def = Some(root);
4550
}
4651

47-
fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex {
52+
fn create_def(&mut self,
53+
node_id: NodeId,
54+
data: DefPathData,
55+
address_space: DefIndexAddressSpace)
56+
-> DefIndex {
4857
let parent_def = self.parent_def;
4958
debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
50-
self.definitions.create_def_with_parent(parent_def, node_id, data)
59+
self.definitions.create_def_with_parent(parent_def, node_id, data, address_space)
5160
}
5261

5362
fn create_def_with_parent(&mut self,
5463
parent: Option<DefIndex>,
5564
node_id: NodeId,
56-
data: DefPathData)
65+
data: DefPathData,
66+
address_space: DefIndexAddressSpace)
5767
-> DefIndex {
58-
self.definitions.create_def_with_parent(parent, node_id, data)
68+
self.definitions.create_def_with_parent(parent, node_id, data, address_space)
5969
}
6070

6171
pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
@@ -76,7 +86,7 @@ impl<'a> DefCollector<'a> {
7686
_ => {}
7787
}
7888

79-
self.create_def(expr.id, DefPathData::Initializer);
89+
self.create_def(expr.id, DefPathData::Initializer, REGULAR_SPACE);
8090
}
8191

8292
fn visit_macro_invoc(&mut self, id: NodeId, const_expr: bool) {
@@ -118,27 +128,32 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
118128
ViewPathSimple(..) => {}
119129
ViewPathList(_, ref imports) => {
120130
for import in imports {
121-
self.create_def(import.node.id, DefPathData::Misc);
131+
self.create_def(import.node.id,
132+
DefPathData::Misc,
133+
ITEM_LIKE_SPACE);
122134
}
123135
}
124136
}
125137
DefPathData::Misc
126138
}
127139
};
128-
let def = self.create_def(i.id, def_data);
140+
let def = self.create_def(i.id, def_data, ITEM_LIKE_SPACE);
129141

130142
self.with_parent(def, |this| {
131143
match i.node {
132144
ItemKind::Enum(ref enum_definition, _) => {
133145
for v in &enum_definition.variants {
134146
let variant_def_index =
135147
this.create_def(v.node.data.id(),
136-
DefPathData::EnumVariant(v.node.name.name.as_str()));
148+
DefPathData::EnumVariant(v.node.name.name.as_str()),
149+
REGULAR_SPACE);
137150
this.with_parent(variant_def_index, |this| {
138151
for (index, field) in v.node.data.fields().iter().enumerate() {
139152
let name = field.ident.map(|ident| ident.name)
140153
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
141-
this.create_def(field.id, DefPathData::Field(name.as_str()));
154+
this.create_def(field.id,
155+
DefPathData::Field(name.as_str()),
156+
REGULAR_SPACE);
142157
}
143158

144159
if let Some(ref expr) = v.node.disr_expr {
@@ -151,13 +166,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
151166
// If this is a tuple-like struct, register the constructor.
152167
if !struct_def.is_struct() {
153168
this.create_def(struct_def.id(),
154-
DefPathData::StructCtor);
169+
DefPathData::StructCtor,
170+
REGULAR_SPACE);
155171
}
156172

157173
for (index, field) in struct_def.fields().iter().enumerate() {
158174
let name = field.ident.map(|ident| ident.name.as_str())
159175
.unwrap_or(Symbol::intern(&index.to_string()).as_str());
160-
this.create_def(field.id, DefPathData::Field(name));
176+
this.create_def(field.id, DefPathData::Field(name), REGULAR_SPACE);
161177
}
162178
}
163179
_ => {}
@@ -168,7 +184,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
168184

169185
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
170186
let def = self.create_def(foreign_item.id,
171-
DefPathData::ValueNs(foreign_item.ident.name.as_str()));
187+
DefPathData::ValueNs(foreign_item.ident.name.as_str()),
188+
REGULAR_SPACE);
172189

173190
self.with_parent(def, |this| {
174191
visit::walk_foreign_item(this, foreign_item);
@@ -177,7 +194,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
177194

178195
fn visit_generics(&mut self, generics: &'a Generics) {
179196
for ty_param in generics.ty_params.iter() {
180-
self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.ident.name.as_str()));
197+
self.create_def(ty_param.id,
198+
DefPathData::TypeParam(ty_param.ident.name.as_str()),
199+
REGULAR_SPACE);
181200
}
182201

183202
visit::walk_generics(self, generics);
@@ -191,7 +210,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
191210
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
192211
};
193212

194-
let def = self.create_def(ti.id, def_data);
213+
let def = self.create_def(ti.id, def_data, ITEM_LIKE_SPACE);
195214
self.with_parent(def, |this| {
196215
if let TraitItemKind::Const(_, Some(ref expr)) = ti.node {
197216
this.visit_const_expr(expr);
@@ -209,7 +228,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
209228
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
210229
};
211230

212-
let def = self.create_def(ii.id, def_data);
231+
let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE);
213232
self.with_parent(def, |this| {
214233
if let ImplItemKind::Const(_, ref expr) = ii.node {
215234
this.visit_const_expr(expr);
@@ -225,7 +244,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
225244
match pat.node {
226245
PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false),
227246
PatKind::Ident(_, id, _) => {
228-
let def = self.create_def(pat.id, DefPathData::Binding(id.node.name.as_str()));
247+
let def = self.create_def(pat.id,
248+
DefPathData::Binding(id.node.name.as_str()),
249+
REGULAR_SPACE);
229250
self.parent_def = Some(def);
230251
}
231252
_ => {}
@@ -242,7 +263,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
242263
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, false),
243264
ExprKind::Repeat(_, ref count) => self.visit_const_expr(count),
244265
ExprKind::Closure(..) => {
245-
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
266+
let def = self.create_def(expr.id,
267+
DefPathData::ClosureExpr,
268+
REGULAR_SPACE);
246269
self.parent_def = Some(def);
247270
}
248271
_ => {}
@@ -257,7 +280,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
257280
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
258281
TyKind::Array(_, ref length) => self.visit_const_expr(length),
259282
TyKind::ImplTrait(..) => {
260-
self.create_def(ty.id, DefPathData::ImplTrait);
283+
self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE);
261284
}
262285
TyKind::Typeof(ref expr) => self.visit_const_expr(expr),
263286
_ => {}
@@ -266,7 +289,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
266289
}
267290

268291
fn visit_lifetime_def(&mut self, def: &'a LifetimeDef) {
269-
self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name.as_str()));
292+
self.create_def(def.lifetime.id,
293+
DefPathData::LifetimeDef(def.lifetime.name.as_str()),
294+
REGULAR_SPACE);
270295
}
271296

272297
fn visit_stmt(&mut self, stmt: &'a Stmt) {

‎src/librustc/hir/map/definitions.rs

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//! expressions) that are mostly just leftovers.
1616
1717
use hir;
18-
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
18+
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace};
1919
use rustc_data_structures::fx::FxHashMap;
2020
use rustc_data_structures::indexed_vec::IndexVec;
2121
use rustc_data_structures::stable_hasher::StableHasher;
@@ -31,24 +31,44 @@ use util::nodemap::NodeMap;
3131
/// Internally the DefPathTable holds a tree of DefKeys, where each DefKey
3232
/// stores the DefIndex of its parent.
3333
/// There is one DefPathTable for each crate.
34-
#[derive(Clone)]
3534
pub struct DefPathTable {
36-
index_to_key: Vec<DefKey>,
35+
index_to_key: [Vec<DefKey>; 2],
3736
key_to_index: FxHashMap<DefKey, DefIndex>,
3837
}
3938

39+
// Unfortunately we have to provide a manual impl of Clone because of the
40+
// fixed-sized array field.
41+
impl Clone for DefPathTable {
42+
fn clone(&self) -> Self {
43+
DefPathTable {
44+
index_to_key: [self.index_to_key[0].clone(),
45+
self.index_to_key[1].clone()],
46+
key_to_index: self.key_to_index.clone(),
47+
}
48+
}
49+
}
50+
4051
impl DefPathTable {
41-
fn insert(&mut self, key: DefKey) -> DefIndex {
42-
let index = DefIndex::new(self.index_to_key.len());
43-
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
44-
self.index_to_key.push(key.clone());
52+
53+
fn allocate(&mut self,
54+
key: DefKey,
55+
address_space: DefIndexAddressSpace)
56+
-> DefIndex {
57+
let index = {
58+
let index_to_key = &mut self.index_to_key[address_space.index()];
59+
let index = DefIndex::new(index_to_key.len() + address_space.start());
60+
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
61+
index_to_key.push(key.clone());
62+
index
63+
};
4564
self.key_to_index.insert(key, index);
4665
index
4766
}
4867

4968
#[inline(always)]
5069
pub fn def_key(&self, index: DefIndex) -> DefKey {
51-
self.index_to_key[index.as_usize()].clone()
70+
self.index_to_key[index.address_space().index()]
71+
[index.as_array_index()].clone()
5272
}
5373

5474
#[inline(always)]
@@ -96,17 +116,28 @@ impl DefPathTable {
96116

97117
impl Encodable for DefPathTable {
98118
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
99-
self.index_to_key.encode(s)
119+
self.index_to_key[DefIndexAddressSpace::Low.index()].encode(s)?;
120+
self.index_to_key[DefIndexAddressSpace::High.index()].encode(s)
100121
}
101122
}
102123

103124
impl Decodable for DefPathTable {
104125
fn decode<D: Decoder>(d: &mut D) -> Result<DefPathTable, D::Error> {
105-
let index_to_key: Vec<DefKey> = Decodable::decode(d)?;
106-
let key_to_index = index_to_key.iter()
107-
.enumerate()
108-
.map(|(index, key)| (key.clone(), DefIndex::new(index)))
109-
.collect();
126+
let index_to_key_lo: Vec<DefKey> = Decodable::decode(d)?;
127+
let index_to_key_high: Vec<DefKey> = Decodable::decode(d)?;
128+
129+
let index_to_key = [index_to_key_lo, index_to_key_high];
130+
131+
let mut key_to_index = FxHashMap();
132+
133+
for space in &[DefIndexAddressSpace::Low, DefIndexAddressSpace::High] {
134+
key_to_index.extend(index_to_key[space.index()]
135+
.iter()
136+
.enumerate()
137+
.map(|(index, key)| (key.clone(),
138+
DefIndex::new(index + space.start()))))
139+
}
140+
110141
Ok(DefPathTable {
111142
index_to_key: index_to_key,
112143
key_to_index: key_to_index,
@@ -118,14 +149,29 @@ impl Decodable for DefPathTable {
118149
/// The definition table containing node definitions.
119150
/// It holds the DefPathTable for local DefIds/DefPaths and it also stores a
120151
/// mapping from NodeIds to local DefIds.
121-
#[derive(Clone)]
122152
pub struct Definitions {
123153
table: DefPathTable,
124154
node_to_def_index: NodeMap<DefIndex>,
125-
def_index_to_node: Vec<ast::NodeId>,
155+
def_index_to_node: [Vec<ast::NodeId>; 2],
126156
pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
127157
}
128158

159+
// Unfortunately we have to provide a manual impl of Clone because of the
160+
// fixed-sized array field.
161+
impl Clone for Definitions {
162+
fn clone(&self) -> Self {
163+
Definitions {
164+
table: self.table.clone(),
165+
node_to_def_index: self.node_to_def_index.clone(),
166+
def_index_to_node: [
167+
self.def_index_to_node[0].clone(),
168+
self.def_index_to_node[1].clone(),
169+
],
170+
node_to_hir_id: self.node_to_hir_id.clone(),
171+
}
172+
}
173+
}
174+
129175
/// A unique identifier that we can use to lookup a definition
130176
/// precisely. It combines the index of the definition's parent (if
131177
/// any) with a `DisambiguatedDefPathData`.
@@ -290,11 +336,11 @@ impl Definitions {
290336
pub fn new() -> Definitions {
291337
Definitions {
292338
table: DefPathTable {
293-
index_to_key: vec![],
339+
index_to_key: [vec![], vec![]],
294340
key_to_index: FxHashMap(),
295341
},
296342
node_to_def_index: NodeMap(),
297-
def_index_to_node: vec![],
343+
def_index_to_node: [vec![], vec![]],
298344
node_to_hir_id: IndexVec::new(),
299345
}
300346
}
@@ -304,8 +350,9 @@ impl Definitions {
304350
}
305351

306352
/// Get the number of definitions.
307-
pub fn len(&self) -> usize {
308-
self.def_index_to_node.len()
353+
pub fn def_index_counts_lo_hi(&self) -> (usize, usize) {
354+
(self.def_index_to_node[DefIndexAddressSpace::Low.index()].len(),
355+
self.def_index_to_node[DefIndexAddressSpace::High.index()].len())
309356
}
310357

311358
pub fn def_key(&self, index: DefIndex) -> DefKey {
@@ -339,8 +386,9 @@ impl Definitions {
339386

340387
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
341388
if def_id.krate == LOCAL_CRATE {
342-
assert!(def_id.index.as_usize() < self.def_index_to_node.len());
343-
Some(self.def_index_to_node[def_id.index.as_usize()])
389+
let space_index = def_id.index.address_space().index();
390+
let array_index = def_id.index.as_array_index();
391+
Some(self.def_index_to_node[space_index][array_index])
344392
} else {
345393
None
346394
}
@@ -350,7 +398,9 @@ impl Definitions {
350398
pub fn create_def_with_parent(&mut self,
351399
parent: Option<DefIndex>,
352400
node_id: ast::NodeId,
353-
data: DefPathData)
401+
data: DefPathData,
402+
// is_owner: bool)
403+
address_space: DefIndexAddressSpace)
354404
-> DefIndex {
355405
debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
356406
parent, node_id, data);
@@ -380,11 +430,13 @@ impl Definitions {
380430
debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
381431

382432
// Create the definition.
383-
let index = self.table.insert(key);
433+
let index = self.table.allocate(key, address_space);
434+
assert_eq!(index.as_array_index(),
435+
self.def_index_to_node[address_space.index()].len());
436+
self.def_index_to_node[address_space.index()].push(node_id);
437+
384438
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
385439
self.node_to_def_index.insert(node_id, index);
386-
assert_eq!(index.as_usize(), self.def_index_to_node.len());
387-
self.def_index_to_node.push(node_id);
388440

389441
index
390442
}

‎src/librustc/hir/map/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
1717

1818
use dep_graph::{DepGraph, DepNode};
1919

20-
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
20+
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex, DefIndexAddressSpace};
2121

2222
use syntax::abi::Abi;
2323
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
@@ -38,6 +38,9 @@ mod def_collector;
3838
pub mod definitions;
3939
mod hir_id_validator;
4040

41+
pub const ITEM_LIKE_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::Low;
42+
pub const REGULAR_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::High;
43+
4144
#[derive(Copy, Clone, Debug)]
4245
pub enum Node<'hir> {
4346
NodeItem(&'hir Item),
@@ -347,10 +350,6 @@ impl<'hir> Map<'hir> {
347350
}
348351
}
349352

350-
pub fn num_local_def_ids(&self) -> usize {
351-
self.definitions.len()
352-
}
353-
354353
pub fn definitions(&self) -> &Definitions {
355354
&self.definitions
356355
}

‎src/librustc_metadata/index.rs

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use schema::*;
1212

13-
use rustc::hir::def_id::{DefId, DefIndex};
13+
use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
1414
use std::io::{Cursor, Write};
1515
use std::slice;
1616
use std::u32;
@@ -23,12 +23,15 @@ use std::u32;
2323
/// appropriate spot by calling `record_position`. We should never
2424
/// visit the same index twice.
2525
pub struct Index {
26-
positions: Vec<u32>,
26+
positions: [Vec<u32>; 2]
2727
}
2828

2929
impl Index {
30-
pub fn new(max_index: usize) -> Index {
31-
Index { positions: vec![u32::MAX; max_index] }
30+
pub fn new((max_index_lo, max_index_hi): (usize, usize)) -> Index {
31+
Index {
32+
positions: [vec![u32::MAX; max_index_lo],
33+
vec![u32::MAX; max_index_hi]],
34+
}
3235
}
3336

3437
pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry>) {
@@ -37,24 +40,31 @@ impl Index {
3740
}
3841

3942
pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry>) {
40-
let item = item.as_usize();
41-
4243
assert!(entry.position < (u32::MAX as usize));
4344
let position = entry.position as u32;
45+
let space_index = item.address_space().index();
46+
let array_index = item.as_array_index();
4447

45-
assert!(self.positions[item] == u32::MAX,
48+
assert!(self.positions[space_index][array_index] == u32::MAX,
4649
"recorded position for item {:?} twice, first at {:?} and now at {:?}",
4750
item,
48-
self.positions[item],
51+
self.positions[space_index][array_index],
4952
position);
5053

51-
self.positions[item] = position.to_le();
54+
self.positions[space_index][array_index] = position.to_le();
5255
}
5356

5457
pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) -> LazySeq<Index> {
5558
let pos = buf.position();
56-
buf.write_all(words_to_bytes(&self.positions)).unwrap();
57-
LazySeq::with_position_and_length(pos as usize, self.positions.len())
59+
60+
// First we write the length of the lower range ...
61+
buf.write_all(words_to_bytes(&[self.positions[0].len() as u32])).unwrap();
62+
// ... then the values in the lower range ...
63+
buf.write_all(words_to_bytes(&self.positions[0][..])).unwrap();
64+
// ... then the values in the higher range.
65+
buf.write_all(words_to_bytes(&self.positions[1][..])).unwrap();
66+
LazySeq::with_position_and_length(pos as usize,
67+
self.positions[0].len() + self.positions[1].len() + 1)
5868
}
5969
}
6070

@@ -70,7 +80,18 @@ impl<'tcx> LazySeq<Index> {
7080
index,
7181
words.len());
7282

73-
let position = u32::from_le(words[index].get());
83+
let positions = match def_index.address_space() {
84+
DefIndexAddressSpace::Low => &words[1..],
85+
DefIndexAddressSpace::High => {
86+
// This is a DefIndex in the higher range, so find out where
87+
// that starts:
88+
let lo_count = u32::from_le(words[0].get()) as usize;
89+
&words[lo_count + 1 .. ]
90+
}
91+
};
92+
93+
let array_index = def_index.as_array_index();
94+
let position = u32::from_le(positions[array_index].get());
7495
if position == u32::MAX {
7596
debug!("Index::lookup: position=u32::MAX");
7697
None
@@ -84,14 +105,26 @@ impl<'tcx> LazySeq<Index> {
84105
bytes: &'a [u8])
85106
-> impl Iterator<Item = (DefIndex, Lazy<Entry<'tcx>>)> + 'a {
86107
let words = &bytes_to_words(&bytes[self.position..])[..self.len];
87-
words.iter().map(|word| word.get()).enumerate().filter_map(|(index, position)| {
88-
if position == u32::MAX {
108+
let lo_count = u32::from_le(words[0].get()) as usize;
109+
let lo = &words[1 .. lo_count + 1];
110+
let hi = &words[1 + lo_count ..];
111+
112+
lo.iter().map(|word| word.get()).enumerate().filter_map(|(index, pos)| {
113+
if pos == u32::MAX {
114+
None
115+
} else {
116+
let pos = u32::from_le(pos) as usize;
117+
Some((DefIndex::new(index), Lazy::with_position(pos)))
118+
}
119+
}).chain(hi.iter().map(|word| word.get()).enumerate().filter_map(|(index, pos)| {
120+
if pos == u32::MAX {
89121
None
90122
} else {
91-
let position = u32::from_le(position) as usize;
92-
Some((DefIndex::new(index), Lazy::with_position(position)))
123+
let pos = u32::from_le(pos) as usize;
124+
Some((DefIndex::new(index + DefIndexAddressSpace::High.start()),
125+
Lazy::with_position(pos)))
93126
}
94-
})
127+
}))
95128
}
96129
}
97130

‎src/librustc_metadata/index_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<'a, 'b, 'tcx> DerefMut for IndexBuilder<'a, 'b, 'tcx> {
9090
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
9191
pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self {
9292
IndexBuilder {
93-
items: Index::new(ecx.tcx.hir.num_local_def_ids()),
93+
items: Index::new(ecx.tcx.hir.definitions().def_index_counts_lo_hi()),
9494
ecx: ecx,
9595
}
9696
}

0 commit comments

Comments
 (0)
Please sign in to comment.