Skip to content

Commit 787f20a

Browse files
committed
Use slice representation for child crate maps
1 parent 1506dac commit 787f20a

File tree

3 files changed

+152
-121
lines changed

3 files changed

+152
-121
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2949,6 +2949,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
29492949

29502950
pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
29512951
llmod: ModuleRef) -> ValueRef {
2952+
29522953
let targ_cfg = sess.targ_cfg;
29532954
let int_type = Type::int(targ_cfg.arch);
29542955
let mut n_subcrates = 1;
@@ -2959,9 +2960,10 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
29592960
} else {
29602961
~"toplevel"
29612962
};
2963+
29622964
let sym_name = ~"_rust_crate_map_" + mapname;
2963-
let arrtype = Type::array(&int_type, n_subcrates as u64);
2964-
let maptype = Type::struct_([Type::i32(), int_type, arrtype], false);
2965+
let vectype = Type::struct_([int_type, int_type], false);
2966+
let maptype = Type::struct_([Type::i32(), int_type, vectype], false);
29652967
let map = do sym_name.with_c_str |buf| {
29662968
unsafe {
29672969
llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
@@ -2996,14 +2998,24 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
29962998
subcrates.push(p2i(ccx, cr));
29972999
i += 1;
29983000
}
2999-
subcrates.push(C_int(ccx, 0));
3000-
30013001
unsafe {
3002+
let maptype = Type::array(&ccx.int_type, subcrates.len() as u64);
3003+
let vec_elements = do "_crate_map_child_vectors".with_c_str |buf| {
3004+
llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
3005+
};
3006+
lib::llvm::SetLinkage(vec_elements, lib::llvm::InternalLinkage);
3007+
3008+
llvm::LLVMSetInitializer(vec_elements, C_array(ccx.int_type, subcrates));
30023009
let mod_map = create_module_map(ccx);
3010+
30033011
llvm::LLVMSetInitializer(map, C_struct(
30043012
[C_i32(1),
30053013
p2i(ccx, mod_map),
3006-
C_array(ccx.int_type, subcrates)]));
3014+
C_struct(
3015+
[p2i(ccx, vec_elements),
3016+
C_int(ccx, (subcrates.len() * 8) as int)
3017+
])
3018+
]));
30073019
}
30083020
}
30093021

src/libstd/rt/crate_map.rs

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

11-
12-
use libc::c_char;
13-
use ptr;
14-
use ptr::RawPtr;
15-
use vec;
16-
use hashmap::HashSet;
11+
use cast::transmute;
1712
use container::MutableSet;
13+
use hashmap::HashSet;
14+
use libc::c_char;
1815

1916
// Need to tell the linker on OS X to not barf on undefined symbols
2017
// and instead look them up at runtime, which we need to resolve
@@ -34,14 +31,15 @@ pub struct ModEntry {
3431
name: *c_char,
3532
log_level: *mut u32
3633
}
34+
3735
struct CrateMapV0 {
38-
entries: *ModEntry,
39-
children: [*CrateMap, ..1]
36+
entries: &static [ModEntry],
37+
children: &'static [&'static CrateMap]
4038
}
4139

4240
struct CrateMap {
4341
version: i32,
44-
entries: *ModEntry,
42+
entries: &static [ModEntry],
4543
/// a dynamically sized struct, where all pointers to children are listed adjacent
4644
/// to the struct, terminated with NULL
4745
children: [*CrateMap, ..1]
@@ -71,153 +69,175 @@ pub fn get_crate_map() -> *CrateMap {
7169
sym as *CrateMap
7270
}
7371

74-
unsafe fn version(crate_map: *CrateMap) -> i32 {
75-
match (*crate_map).version {
72+
fn version(crate_map: &'static CrateMap) -> i32 {
73+
match crate_map.version {
7674
1 => return 1,
7775
_ => return 0
7876
}
7977
}
8078

81-
unsafe fn entries(crate_map: *CrateMap) -> *ModEntry {
79+
#[cfg(not(stage0))]
80+
fn entries(crate_map: &'static CrateMap) -> *ModEntry {
8281
match version(crate_map) {
8382
0 => {
84-
let v0 = crate_map as (*CrateMapV0);
85-
return (*v0).entries;
83+
unsafe {
84+
let v0: &'static CrateMapV0 = transmute(crate_map);
85+
return v0.entries;
86+
}
8687
}
8788
1 => return (*crate_map).entries,
8889
_ => fail2!("Unknown crate map version!")
8990
}
9091
}
9192

92-
unsafe fn iterator(crate_map: *CrateMap) -> **CrateMap {
93+
#[cfg(not(stage0))]
94+
fn iterator(crate_map: &'static CrateMap) -> &'static [&'static CrateMap] {
9395
match version(crate_map) {
9496
0 => {
95-
let v0 = crate_map as (*CrateMapV0);
96-
return vec::raw::to_ptr((*v0).children);
97+
unsafe {
98+
let v0: &'static CrateMapV0 = transmute(crate_map);
99+
return v0.children;
100+
}
97101
}
98102
1 => return vec::raw::to_ptr((*crate_map).children),
99103
_ => fail2!("Unknown crate map version!")
100104
}
101105
}
102106

103-
unsafe fn iter_module_map(mod_entries: *ModEntry, f: &fn(*mut ModEntry)) {
107+
fn iter_module_map(mod_entries: *ModEntry, f: &fn(&mut ModEntry)) {
104108
let mut curr = mod_entries;
105109

106-
while !(*curr).name.is_null() {
107-
f(curr as *mut ModEntry);
108-
curr = curr.offset(1);
110+
unsafe {
111+
while !(*curr).name.is_null() {
112+
f(transmute(curr));
113+
curr = curr.offset(1);
114+
}
109115
}
110116
}
111117

112-
unsafe fn do_iter_crate_map(crate_map: *CrateMap, f: &fn(*mut ModEntry),
118+
119+
120+
#[cfg(not(stage0))]
121+
fn do_iter_crate_map(crate_map: &'static CrateMap, f: &fn(&mut ModEntry),
113122
visited: &mut HashSet<*CrateMap>) {
114-
if visited.insert(crate_map) {
115-
iter_module_map(entries(crate_map), |x| f(x));
123+
if visited.insert(crate_map as *CrateMap) {
124+
iter_module_map(crate_map.entries, |x| f(x));
116125
let child_crates = iterator(crate_map);
117-
do ptr::array_each(child_crates) |child| {
118-
do_iter_crate_map(child, |x| f(x), visited);
126+
127+
let mut i = 0;
128+
while i < child_crates.len() {
129+
do_iter_crate_map(child_crates[i], |x| f(x), visited);
130+
i = i + 1;
119131
}
120132
}
121133
}
122134

135+
#[cfg(stage0)]
123136
/// Iterates recursively over `crate_map` and all child crate maps
124-
pub unsafe fn iter_crate_map(crate_map: *CrateMap, f: &fn(*mut ModEntry)) {
137+
pub fn iter_crate_map(crate_map: *u8, f: &fn(&mut ModEntry)) {
138+
}
139+
140+
#[cfg(not(stage0))]
141+
/// Iterates recursively over `crate_map` and all child crate maps
142+
pub fn iter_crate_map(crate_map: &'static CrateMap, f: &fn(&mut ModEntry)) {
125143
// XXX: use random numbers as keys from the OS-level RNG when there is a nice
126144
// way to do this
127145
let mut v: HashSet<*CrateMap> = HashSet::with_capacity_and_keys(0, 0, 32);
128-
do_iter_crate_map(crate_map, f, &mut v);
129-
}
130-
131-
#[test]
132-
fn iter_crate_map_duplicates() {
133-
use c_str::ToCStr;
134-
use cast::transmute;
135-
136-
struct CrateMapT3 {
137-
version: i32,
138-
entries: *ModEntry,
139-
children: [*CrateMap, ..3]
140-
}
141-
142146
unsafe {
143-
let mod_name1 = "c::m1".to_c_str();
144-
let mut level3: u32 = 3;
145-
146-
let entries: ~[ModEntry] = ~[
147-
ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
148-
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
149-
];
150-
let child_crate = CrateMap {
151-
version: 1,
152-
entries: vec::raw::to_ptr(entries),
153-
children: [ptr::null()]
154-
};
155-
156-
let root_crate = CrateMapT3 {
157-
version: 1,
158-
entries: vec::raw::to_ptr([ModEntry { name: ptr::null(), log_level: ptr::mut_null()}]),
159-
children: [&child_crate as *CrateMap, &child_crate as *CrateMap, ptr::null()]
160-
};
161-
162-
let mut cnt = 0;
163-
do iter_crate_map(transmute(&root_crate)) |entry| {
164-
assert!(*(*entry).log_level == 3);
165-
cnt += 1;
166-
}
167-
assert!(cnt == 1);
147+
do_iter_crate_map(transmute(crate_map), f, &mut v);
168148
}
169149
}
170150

171-
#[test]
172-
fn iter_crate_map_follow_children() {
151+
#[cfg(test)]
152+
mod tests {
173153
use c_str::ToCStr;
174154
use cast::transmute;
155+
use ptr;
156+
use vec;
157+
158+
use rt::crate_map::{ModEntry, iter_crate_map};
175159

176-
struct CrateMapT2 {
160+
struct CrateMap<'self> {
177161
version: i32,
178162
entries: *ModEntry,
179-
children: [*CrateMap, ..2]
163+
/// a dynamically sized struct, where all pointers to children are listed adjacent
164+
/// to the struct, terminated with NULL
165+
children: &'self [&'self CrateMap<'self>]
180166
}
181167

182-
unsafe {
183-
let mod_name1 = "c::m1".to_c_str();
184-
let mod_name2 = "c::m2".to_c_str();
185-
let mut level2: u32 = 2;
186-
let mut level3: u32 = 3;
187-
let child_crate2 = CrateMap {
188-
version: 1,
189-
entries: vec::raw::to_ptr([
190-
ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
191-
ModEntry { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
192-
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
193-
]),
194-
children: [ptr::null()]
195-
};
168+
#[test]
169+
fn iter_crate_map_duplicates() {
170+
unsafe {
171+
let mod_name1 = "c::m1".to_c_str();
172+
let mut level3: u32 = 3;
196173

197-
let child_crate1 = CrateMapT2 {
198-
version: 1,
199-
entries: vec::raw::to_ptr([
200-
ModEntry { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 1},
174+
let entries: ~[ModEntry] = ~[
175+
ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
201176
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
202-
]),
203-
children: [&child_crate2 as *CrateMap, ptr::null()]
204-
};
205-
206-
let child_crate1_ptr: *CrateMap = transmute(&child_crate1);
207-
let root_crate = CrateMapT2 {
208-
version: 1,
209-
entries: vec::raw::to_ptr([
210-
ModEntry { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 0},
211-
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
212-
]),
213-
children: [child_crate1_ptr, ptr::null()]
214-
};
177+
];
178+
179+
let child_crate = CrateMap {
180+
version: 1,
181+
entries: vec::raw::to_ptr(entries),
182+
children: []
183+
};
184+
185+
let root_crate = CrateMap {
186+
version: 1,
187+
entries: vec::raw::to_ptr([ModEntry { name: ptr::null(), log_level: ptr::mut_null()}]),
188+
children: [&child_crate, &child_crate]
189+
};
190+
191+
let mut cnt = 0;
192+
do iter_crate_map(transmute(&root_crate)) |entry| {
193+
assert!(*entry.log_level == 3);
194+
cnt += 1;
195+
}
196+
assert!(cnt == 1);
197+
}
198+
}
215199

216-
let mut cnt = 0;
217-
do iter_crate_map(transmute(&root_crate)) |entry| {
218-
assert!(*(*entry).log_level == cnt);
219-
cnt += 1;
200+
#[test]
201+
fn iter_crate_map_follow_children() {
202+
unsafe {
203+
let mod_name1 = "c::m1".to_c_str();
204+
let mod_name2 = "c::m2".to_c_str();
205+
let mut level2: u32 = 2;
206+
let mut level3: u32 = 3;
207+
let child_crate2 = CrateMap {
208+
version: 1,
209+
entries: vec::raw::to_ptr([
210+
ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
211+
ModEntry { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
212+
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
213+
]),
214+
children: []
215+
};
216+
217+
let child_crate1 = CrateMap {
218+
version: 1,
219+
entries: vec::raw::to_ptr([
220+
ModEntry { name: "t::f1".to_c_str().with_ref(|buf| buf), log_level: &mut 1},
221+
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
222+
]),
223+
children: [&child_crate2]
224+
};
225+
226+
let root_crate = CrateMap {
227+
version: 1,
228+
entries: vec::raw::to_ptr([
229+
ModEntry { name: "t::f1".to_c_str().with_ref(|buf| buf), log_level: &mut 0},
230+
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
231+
]),
232+
children: [&child_crate1]
233+
};
234+
235+
let mut cnt = 0;
236+
do iter_crate_map(transmute(&root_crate)) |entry| {
237+
assert!(*entry.log_level == cnt);
238+
cnt += 1;
239+
}
240+
assert!(cnt == 4);
220241
}
221-
assert!(cnt == 4);
222242
}
223243
}

0 commit comments

Comments
 (0)