Use slice representation for module entries in CrateMap
Relaxe lifetime of CrateMap as well.
This commit is contained in:
parent
787f20a255
commit
9ef4463b2a
3 changed files with 60 additions and 100 deletions
|
|
@ -2911,9 +2911,9 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
|
||||
pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint) {
|
||||
let elttype = Type::struct_([ccx.int_type, ccx.int_type], false);
|
||||
let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64);
|
||||
let maptype = Type::array(&elttype, ccx.module_data.len() as u64);
|
||||
let map = do "_rust_mod_map".with_c_str |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
|
||||
|
|
@ -2938,18 +2938,15 @@ pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
|
|||
let elt = C_struct([s_ptr, v_ptr]);
|
||||
elts.push(elt);
|
||||
}
|
||||
let term = C_struct([C_int(ccx, 0), C_int(ccx, 0)]);
|
||||
elts.push(term);
|
||||
unsafe {
|
||||
llvm::LLVMSetInitializer(map, C_array(elttype, elts));
|
||||
}
|
||||
return map;
|
||||
return (map, keys.len());
|
||||
}
|
||||
|
||||
|
||||
pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
|
||||
llmod: ModuleRef) -> ValueRef {
|
||||
|
||||
let targ_cfg = sess.targ_cfg;
|
||||
let int_type = Type::int(targ_cfg.arch);
|
||||
let mut n_subcrates = 1;
|
||||
|
|
@ -2962,8 +2959,8 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
|
|||
};
|
||||
|
||||
let sym_name = ~"_rust_crate_map_" + mapname;
|
||||
let vectype = Type::struct_([int_type, int_type], false);
|
||||
let maptype = Type::struct_([Type::i32(), int_type, vectype], false);
|
||||
let slicetype = Type::struct_([int_type, int_type], false);
|
||||
let maptype = Type::struct_([Type::i32(), slicetype, slicetype], false);
|
||||
let map = do sym_name.with_c_str |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
|
||||
|
|
@ -3006,14 +3003,17 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
|
|||
lib::llvm::SetLinkage(vec_elements, lib::llvm::InternalLinkage);
|
||||
|
||||
llvm::LLVMSetInitializer(vec_elements, C_array(ccx.int_type, subcrates));
|
||||
let mod_map = create_module_map(ccx);
|
||||
let (mod_map, mod_count) = create_module_map(ccx);
|
||||
|
||||
llvm::LLVMSetInitializer(map, C_struct(
|
||||
[C_i32(1),
|
||||
p2i(ccx, mod_map),
|
||||
C_struct(
|
||||
[p2i(ccx, vec_elements),
|
||||
C_int(ccx, (subcrates.len() * 8) as int)
|
||||
C_struct([
|
||||
p2i(ccx, mod_map),
|
||||
C_int(ccx, (mod_count * 16) as int)
|
||||
]),
|
||||
C_struct([
|
||||
p2i(ccx, vec_elements),
|
||||
C_int(ccx, (subcrates.len() * 8) as int)
|
||||
])
|
||||
]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use cast::transmute;
|
||||
#[cfg(not(stage0))] use cast::transmute;
|
||||
use container::MutableSet;
|
||||
use hashmap::HashSet;
|
||||
use libc::c_char;
|
||||
use option::{Some, None};
|
||||
use vec::ImmutableVector;
|
||||
|
||||
// Need to tell the linker on OS X to not barf on undefined symbols
|
||||
// and instead look them up at runtime, which we need to resolve
|
||||
|
|
@ -24,7 +26,7 @@ extern {}
|
|||
extern {
|
||||
#[weak_linkage]
|
||||
#[link_name = "_rust_crate_map_toplevel"]
|
||||
static CRATE_MAP: CrateMap;
|
||||
static CRATE_MAP: CrateMap<'static>;
|
||||
}
|
||||
|
||||
pub struct ModEntry {
|
||||
|
|
@ -32,28 +34,28 @@ pub struct ModEntry {
|
|||
log_level: *mut u32
|
||||
}
|
||||
|
||||
struct CrateMapV0 {
|
||||
entries: &static [ModEntry],
|
||||
children: &'static [&'static CrateMap]
|
||||
pub struct CrateMapV0<'self> {
|
||||
entries: &'self [ModEntry],
|
||||
children: &'self [&'self CrateMap<'self>]
|
||||
}
|
||||
|
||||
struct CrateMap {
|
||||
pub struct CrateMap<'self> {
|
||||
version: i32,
|
||||
entries: &static [ModEntry],
|
||||
entries: &'self [ModEntry],
|
||||
/// a dynamically sized struct, where all pointers to children are listed adjacent
|
||||
/// to the struct, terminated with NULL
|
||||
children: [*CrateMap, ..1]
|
||||
children: &'self [&'self CrateMap<'self>]
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn get_crate_map() -> *CrateMap {
|
||||
&'static CRATE_MAP as *CrateMap
|
||||
pub fn get_crate_map() -> &'static CrateMap<'static> {
|
||||
&'static CRATE_MAP
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[fixed_stack_segment]
|
||||
#[inline(never)]
|
||||
pub fn get_crate_map() -> *CrateMap {
|
||||
pub fn get_crate_map() -> &'static CrateMap<'static> {
|
||||
use c_str::ToCStr;
|
||||
use unstable::dynamic_lib::dl;
|
||||
|
||||
|
|
@ -65,11 +67,10 @@ pub fn get_crate_map() -> *CrateMap {
|
|||
dl::close(module);
|
||||
sym
|
||||
};
|
||||
|
||||
sym as *CrateMap
|
||||
sym
|
||||
}
|
||||
|
||||
fn version(crate_map: &'static CrateMap) -> i32 {
|
||||
fn version(crate_map: &CrateMap) -> i32 {
|
||||
match crate_map.version {
|
||||
1 => return 1,
|
||||
_ => return 0
|
||||
|
|
@ -77,12 +78,13 @@ fn version(crate_map: &'static CrateMap) -> i32 {
|
|||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
fn entries(crate_map: &'static CrateMap) -> *ModEntry {
|
||||
fn get_entries_and_children<'a>(crate_map: &'a CrateMap<'a>) ->
|
||||
(&'a [ModEntry], &'a [&'a CrateMap<'a>]) {
|
||||
match version(crate_map) {
|
||||
0 => {
|
||||
unsafe {
|
||||
let v0: &'static CrateMapV0 = transmute(crate_map);
|
||||
return v0.entries;
|
||||
let v0: &'a CrateMapV0<'a> = transmute(crate_map);
|
||||
return (v0.entries, v0.children);
|
||||
}
|
||||
}
|
||||
1 => return (*crate_map).entries,
|
||||
|
|
@ -91,79 +93,43 @@ fn entries(crate_map: &'static CrateMap) -> *ModEntry {
|
|||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
fn iterator(crate_map: &'static CrateMap) -> &'static [&'static CrateMap] {
|
||||
match version(crate_map) {
|
||||
0 => {
|
||||
unsafe {
|
||||
let v0: &'static CrateMapV0 = transmute(crate_map);
|
||||
return v0.children;
|
||||
}
|
||||
}
|
||||
1 => return vec::raw::to_ptr((*crate_map).children),
|
||||
_ => fail2!("Unknown crate map version!")
|
||||
fn iter_module_map(mod_entries: &[ModEntry], f: &fn(&ModEntry)) {
|
||||
for entry in mod_entries.iter() {
|
||||
f(entry);
|
||||
}
|
||||
}
|
||||
|
||||
fn iter_module_map(mod_entries: *ModEntry, f: &fn(&mut ModEntry)) {
|
||||
let mut curr = mod_entries;
|
||||
|
||||
unsafe {
|
||||
while !(*curr).name.is_null() {
|
||||
f(transmute(curr));
|
||||
curr = curr.offset(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
fn do_iter_crate_map(crate_map: &'static CrateMap, f: &fn(&mut ModEntry),
|
||||
visited: &mut HashSet<*CrateMap>) {
|
||||
fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
|
||||
visited: &mut HashSet<*CrateMap<'a>>) {
|
||||
if visited.insert(crate_map as *CrateMap) {
|
||||
iter_module_map(crate_map.entries, |x| f(x));
|
||||
let child_crates = iterator(crate_map);
|
||||
|
||||
let mut i = 0;
|
||||
while i < child_crates.len() {
|
||||
do_iter_crate_map(child_crates[i], |x| f(x), visited);
|
||||
i = i + 1;
|
||||
let (entries, children) = get_entries_and_children(crate_map);
|
||||
iter_module_map(entries, |x| f(x));
|
||||
for child in children.iter() {
|
||||
do_iter_crate_map(*child, |x| f(x), visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
/// Iterates recursively over `crate_map` and all child crate maps
|
||||
pub fn iter_crate_map(crate_map: *u8, f: &fn(&mut ModEntry)) {
|
||||
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
/// Iterates recursively over `crate_map` and all child crate maps
|
||||
pub fn iter_crate_map(crate_map: &'static CrateMap, f: &fn(&mut ModEntry)) {
|
||||
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
|
||||
// XXX: use random numbers as keys from the OS-level RNG when there is a nice
|
||||
// way to do this
|
||||
let mut v: HashSet<*CrateMap> = HashSet::with_capacity_and_keys(0, 0, 32);
|
||||
unsafe {
|
||||
do_iter_crate_map(transmute(crate_map), f, &mut v);
|
||||
}
|
||||
let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
|
||||
do_iter_crate_map(crate_map, f, &mut v);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use c_str::ToCStr;
|
||||
use cast::transmute;
|
||||
use ptr;
|
||||
use vec;
|
||||
|
||||
use rt::crate_map::{ModEntry, iter_crate_map};
|
||||
|
||||
struct CrateMap<'self> {
|
||||
version: i32,
|
||||
entries: *ModEntry,
|
||||
/// a dynamically sized struct, where all pointers to children are listed adjacent
|
||||
/// to the struct, terminated with NULL
|
||||
children: &'self [&'self CrateMap<'self>]
|
||||
}
|
||||
use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};
|
||||
|
||||
#[test]
|
||||
fn iter_crate_map_duplicates() {
|
||||
|
|
@ -171,20 +137,19 @@ mod tests {
|
|||
let mod_name1 = "c::m1".to_c_str();
|
||||
let mut level3: u32 = 3;
|
||||
|
||||
let entries: ~[ModEntry] = ~[
|
||||
let entries = [
|
||||
ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
|
||||
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
|
||||
];
|
||||
|
||||
let child_crate = CrateMap {
|
||||
version: 1,
|
||||
entries: vec::raw::to_ptr(entries),
|
||||
entries: entries,
|
||||
children: []
|
||||
};
|
||||
|
||||
let root_crate = CrateMap {
|
||||
version: 1,
|
||||
entries: vec::raw::to_ptr([ModEntry { name: ptr::null(), log_level: ptr::mut_null()}]),
|
||||
entries: [],
|
||||
children: [&child_crate, &child_crate]
|
||||
};
|
||||
|
||||
|
|
@ -206,29 +171,26 @@ mod tests {
|
|||
let mut level3: u32 = 3;
|
||||
let child_crate2 = CrateMap {
|
||||
version: 1,
|
||||
entries: vec::raw::to_ptr([
|
||||
entries: [
|
||||
ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
|
||||
ModEntry { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
|
||||
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
|
||||
]),
|
||||
],
|
||||
children: []
|
||||
};
|
||||
|
||||
let child_crate1 = CrateMap {
|
||||
version: 1,
|
||||
entries: vec::raw::to_ptr([
|
||||
entries: [
|
||||
ModEntry { name: "t::f1".to_c_str().with_ref(|buf| buf), log_level: &mut 1},
|
||||
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
|
||||
]),
|
||||
],
|
||||
children: [&child_crate2]
|
||||
};
|
||||
|
||||
let root_crate = CrateMap {
|
||||
version: 1,
|
||||
entries: vec::raw::to_ptr([
|
||||
entries: [
|
||||
ModEntry { name: "t::f1".to_c_str().with_ref(|buf| buf), log_level: &mut 0},
|
||||
ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
|
||||
]),
|
||||
],
|
||||
children: [&child_crate1]
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -14,14 +14,12 @@ use libc::{uintptr_t, exit};
|
|||
use option::{Some, None, Option};
|
||||
use rt;
|
||||
use rt::util::dumb_println;
|
||||
use rt::crate_map::{ModEntry, iter_crate_map};
|
||||
use rt::crate_map::get_crate_map;
|
||||
use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
|
||||
use str::StrSlice;
|
||||
use str::raw::from_c_str;
|
||||
use u32;
|
||||
use vec::ImmutableVector;
|
||||
use send_str::{SendStr, SendStrOwned, SendStrStatic};
|
||||
use cast::transmute;
|
||||
#[cfg(test)] use cast::transmute;
|
||||
|
||||
struct LogDirective {
|
||||
name: Option<~str>,
|
||||
|
|
@ -111,7 +109,7 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
|
|||
|
||||
/// Set the log level of an entry in the crate map depending on the vector
|
||||
/// of log directives
|
||||
fn update_entry(dirs: &[LogDirective], entry: &mut ModEntry) -> u32 {
|
||||
fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {
|
||||
let mut new_lvl: u32 = DEFAULT_LOG_LEVEL;
|
||||
let mut longest_match = -1i;
|
||||
unsafe {
|
||||
|
|
@ -142,7 +140,7 @@ fn update_entry(dirs: &[LogDirective], entry: &mut ModEntry) -> u32 {
|
|||
#[fixed_stack_segment] #[inline(never)]
|
||||
/// Set log level for every entry in crate_map according to the sepecification
|
||||
/// in settings
|
||||
fn update_log_settings(crate_map: *u8, settings: ~str) {
|
||||
fn update_log_settings(crate_map: &CrateMap, settings: ~str) {
|
||||
let mut dirs = ~[];
|
||||
if settings.len() > 0 {
|
||||
if settings == ~"::help" || settings == ~"?" {
|
||||
|
|
@ -206,7 +204,7 @@ impl rt::io::Writer for StdErrLogger {
|
|||
pub fn init() {
|
||||
use os;
|
||||
|
||||
let crate_map = get_crate_map() as *u8;
|
||||
let crate_map = get_crate_map();
|
||||
|
||||
let log_spec = os::getenv("RUST_LOG");
|
||||
match log_spec {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue