提交 5862c0c2 编写于 作者: B bors

auto merge of #12635 : alexcrichton/rust/speedy-hash, r=brson

This leverages the new hashing framework and hashmap implementation to provide a
much speedier hashing algorithm for node ids and def ids. The hash algorithm
used is currentl FNV hashing, but it's quite easy to swap out.

I originally implemented hashing as the identity function, but this actually
ended up in slowing down rustc compiling libstd from 8s to 13s. I would suspect
that this is a result of a large number of collisions.

With FNV hashing, we get these timings (compiling with --no-trans, in seconds):

|           |  before  |  after  |
|-----------|---------:|--------:|
| libstd    |   8.324  |  6.703  |
| stdtest   |  47.674  | 46.857  |
| libsyntax |   9.918  |  8.400  |
......@@ -27,6 +27,7 @@
use middle;
use util::common::time;
use util::ppaux;
use util::nodemap::NodeSet;
use serialize::{json, Encodable};
......@@ -38,7 +39,7 @@
use std::vec;
use std::vec_ng::Vec;
use std::vec_ng;
use collections::{HashMap, HashSet};
use collections::HashMap;
use getopts::{optopt, optmulti, optflag, optflagopt, opt};
use MaybeHasArg = getopts::Maybe;
use OccurOptional = getopts::Optional;
......@@ -223,8 +224,12 @@ pub fn phase_2_configure_and_expand(sess: Session,
front::config::strip_unconfigured_items(krate));
krate = time(time_passes, "expansion", krate, |krate| {
let cfg = syntax::ext::expand::ExpansionConfig {
loader: loader,
deriving_hash_type_parameter: sess.features.default_type_params.get()
};
syntax::ext::expand::expand_crate(sess.parse_sess,
loader,
cfg,
krate)
});
// dump the syntax-time crates
......@@ -258,7 +263,7 @@ pub struct CrateAnalysis {
public_items: middle::privacy::PublicItems,
ty_cx: ty::ctxt,
maps: astencode::Maps,
reachable: @RefCell<HashSet<ast::NodeId>>
reachable: @RefCell<NodeSet>,
}
/// Run the resolution, typechecking, region checking and other
......
......@@ -28,6 +28,7 @@
use syntax::codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
use syntax::codemap;
use syntax::ext::base::ExtCtxt;
use syntax::ext::expand::ExpansionConfig;
use syntax::fold::Folder;
use syntax::fold;
use syntax::opt_vec;
......@@ -165,7 +166,11 @@ fn generate_test_harness(sess: session::Session, krate: ast::Crate)
let loader = &mut Loader::new(sess);
let mut cx: TestCtxt = TestCtxt {
sess: sess,
ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone(), loader),
ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone(),
ExpansionConfig {
loader: loader,
deriving_hash_type_parameter: false,
}),
path: RefCell::new(~[]),
testfns: RefCell::new(~[]),
is_test_crate: is_test_crate(&krate),
......
......@@ -29,7 +29,7 @@
#[allow(deprecated)];
#[feature(macro_rules, globs, struct_variant, managed_boxes)];
#[feature(quote)];
#[feature(quote, default_type_params)];
extern crate extra;
extern crate flate;
......@@ -125,6 +125,7 @@ pub mod util {
pub mod common;
pub mod ppaux;
pub mod sha2;
pub mod nodemap;
}
pub mod lib {
......
......@@ -23,6 +23,7 @@
use middle::ty;
use middle::typeck;
use middle;
use util::nodemap::{NodeMap, NodeSet};
use serialize::Encodable;
use std::cast;
......@@ -31,7 +32,7 @@
use std::hash::Hash;
use std::io::MemWriter;
use std::str;
use collections::{HashMap, HashSet};
use collections::HashMap;
use syntax::abi::AbiSet;
use syntax::ast::*;
use syntax::ast;
......@@ -69,8 +70,8 @@ pub struct EncodeParams<'a> {
diag: @SpanHandler,
tcx: ty::ctxt,
reexports2: middle::resolve::ExportMap2,
item_symbols: &'a RefCell<HashMap<ast::NodeId, ~str>>,
non_inlineable_statics: &'a RefCell<HashSet<ast::NodeId>>,
item_symbols: &'a RefCell<NodeMap<~str>>,
non_inlineable_statics: &'a RefCell<NodeSet>,
link_meta: &'a LinkMeta,
cstore: @cstore::CStore,
encode_inlined_item: EncodeInlinedItem<'a>,
......@@ -97,8 +98,8 @@ pub struct EncodeContext<'a> {
tcx: ty::ctxt,
stats: @Stats,
reexports2: middle::resolve::ExportMap2,
item_symbols: &'a RefCell<HashMap<ast::NodeId, ~str>>,
non_inlineable_statics: &'a RefCell<HashSet<ast::NodeId>>,
item_symbols: &'a RefCell<NodeMap<~str>>,
non_inlineable_statics: &'a RefCell<NodeSet>,
link_meta: &'a LinkMeta,
cstore: &'a cstore::CStore,
encode_inlined_item: EncodeInlinedItem<'a>,
......
......@@ -12,15 +12,15 @@
use middle::graph;
use middle::typeck;
use middle::ty;
use collections::HashMap;
use syntax::ast;
use syntax::ast_util;
use syntax::opt_vec;
use util::nodemap::NodeMap;
struct CFGBuilder {
tcx: ty::ctxt,
method_map: typeck::MethodMap,
exit_map: HashMap<ast::NodeId, CFGIndex>,
exit_map: NodeMap<CFGIndex>,
graph: CFGGraph,
loop_scopes: ~[LoopScope],
}
......@@ -35,7 +35,7 @@ pub fn construct(tcx: ty::ctxt,
method_map: typeck::MethodMap,
blk: &ast::Block) -> CFG {
let mut cfg_builder = CFGBuilder {
exit_map: HashMap::new(),
exit_map: NodeMap::new(),
graph: graph::Graph::new(),
tcx: tcx,
method_map: method_map,
......
......@@ -18,14 +18,14 @@
use middle::graph;
use middle::ty;
use middle::typeck;
use collections::HashMap;
use syntax::ast;
use syntax::opt_vec::OptVec;
use util::nodemap::NodeMap;
mod construct;
pub struct CFG {
exit_map: HashMap<ast::NodeId, CFGIndex>,
exit_map: NodeMap<CFGIndex>,
graph: CFGGraph,
entry: CFGIndex,
exit: CFGIndex,
......
......@@ -16,6 +16,7 @@
use middle::ty;
use middle::typeck::astconv;
use middle;
use util::nodemap::{DefIdMap, NodeMap};
use syntax::ast::*;
use syntax::parse::token::InternedString;
......@@ -66,7 +67,7 @@ pub enum constness {
non_const
}
type constness_cache = HashMap<ast::DefId, constness>;
type constness_cache = DefIdMap<constness>;
pub fn join(a: constness, b: constness) -> constness {
match (a, b) {
......@@ -134,9 +135,9 @@ fn variant_expr(variants: &[ast::P<ast::Variant>], id: ast::NodeId) -> Option<@E
}
let maps = astencode::Maps {
root_map: @RefCell::new(HashMap::new()),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
capture_map: @RefCell::new(HashMap::new())
method_map: @RefCell::new(NodeMap::new()),
vtable_map: @RefCell::new(NodeMap::new()),
capture_map: @RefCell::new(NodeMap::new())
};
let e = match csearch::maybe_get_item_ast(tcx, enum_def,
|a, b, c, d| astencode::decode_inlined_item(a, b,
......@@ -184,9 +185,9 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::DefId)
}
let maps = astencode::Maps {
root_map: @RefCell::new(HashMap::new()),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
capture_map: @RefCell::new(HashMap::new())
method_map: @RefCell::new(NodeMap::new()),
vtable_map: @RefCell::new(NodeMap::new()),
capture_map: @RefCell::new(NodeMap::new())
};
let e = match csearch::maybe_get_item_ast(tcx, def_id,
|a, b, c, d| astencode::decode_inlined_item(a, b, maps, c, d)) {
......@@ -305,7 +306,7 @@ pub fn process_crate(krate: &ast::Crate,
tcx: ty::ctxt) {
let mut v = ConstEvalVisitor {
tcx: tcx,
ccache: HashMap::new(),
ccache: DefIdMap::new(),
};
visit::walk_crate(&mut v, krate, ());
tcx.sess.abort_if_errors();
......
......@@ -20,7 +20,6 @@
use std::io;
use std::uint;
use std::vec;
use collections::HashMap;
use syntax::ast;
use syntax::ast_util;
use syntax::ast_util::IdRange;
......@@ -28,6 +27,7 @@
use middle::ty;
use middle::typeck;
use util::ppaux::Repr;
use util::nodemap::NodeMap;
#[deriving(Clone)]
pub struct DataFlowContext<O> {
......@@ -45,7 +45,7 @@ pub struct DataFlowContext<O> {
priv words_per_id: uint,
// mapping from node to bitset index.
priv nodeid_to_bitset: HashMap<ast::NodeId,uint>,
priv nodeid_to_bitset: NodeMap<uint>,
// Bit sets per id. The following three fields (`gens`, `kills`,
// and `on_entry`) all have the same structure. For each id in
......@@ -139,7 +139,7 @@ pub fn new(tcx: ty::ctxt,
tcx: tcx,
method_map: method_map,
words_per_id: words_per_id,
nodeid_to_bitset: HashMap::new(),
nodeid_to_bitset: NodeMap::new(),
bits_per_id: bits_per_id,
oper: oper,
gens: gens,
......
......@@ -16,6 +16,7 @@
use middle::privacy;
use middle::ty;
use middle::typeck;
use util::nodemap::NodeSet;
use collections::HashSet;
use syntax::ast;
......@@ -252,7 +253,7 @@ fn visit_fn(&mut self, fk: &visit::FnKind,
fn create_and_seed_worklist(tcx: ty::ctxt,
exported_items: &privacy::ExportedItems,
reachable_symbols: &HashSet<ast::NodeId>,
reachable_symbols: &NodeSet,
krate: &ast::Crate) -> ~[ast::NodeId] {
let mut worklist = ~[];
......@@ -286,7 +287,7 @@ fn create_and_seed_worklist(tcx: ty::ctxt,
fn find_live(tcx: ty::ctxt,
method_map: typeck::MethodMap,
exported_items: &privacy::ExportedItems,
reachable_symbols: &HashSet<ast::NodeId>,
reachable_symbols: &NodeSet,
krate: &ast::Crate)
-> ~HashSet<ast::NodeId> {
let worklist = create_and_seed_worklist(tcx, exported_items,
......@@ -409,7 +410,7 @@ fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
pub fn check_crate(tcx: ty::ctxt,
method_map: typeck::MethodMap,
exported_items: &privacy::ExportedItems,
reachable_symbols: &HashSet<ast::NodeId>,
reachable_symbols: &NodeSet,
krate: &ast::Crate) {
let live_symbols = find_live(tcx, method_map, exported_items,
reachable_symbols, krate);
......
......@@ -15,8 +15,8 @@
use middle::resolve;
use middle::ty;
use util::nodemap::{NodeMap, NodeSet};
use collections::HashMap;
use syntax::codemap::Span;
use syntax::{ast, ast_util};
use syntax::visit;
......@@ -30,10 +30,10 @@ pub struct freevar_entry {
span: Span //< First span where it is accessed (there can be multiple)
}
pub type freevar_info = @~[@freevar_entry];
pub type freevar_map = HashMap<ast::NodeId, freevar_info>;
pub type freevar_map = NodeMap<freevar_info>;
struct CollectFreevarsVisitor {
seen: HashMap<ast::NodeId, ()>,
seen: NodeSet,
refs: ~[@freevar_entry],
def_map: resolve::DefMap,
}
......@@ -65,12 +65,12 @@ fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
}
if i == depth { // Made it to end of loop
let dnum = ast_util::def_id_of_def(def).node;
if !self.seen.contains_key(&dnum) {
if !self.seen.contains(&dnum) {
self.refs.push(@freevar_entry {
def: def,
span: expr.span,
});
self.seen.insert(dnum, ());
self.seen.insert(dnum);
}
}
}
......@@ -89,7 +89,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
// of the AST, we take a walker function that we invoke with a visitor
// in order to start the search.
fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block) -> freevar_info {
let seen = HashMap::new();
let seen = NodeSet::new();
let refs = ~[];
let mut v = CollectFreevarsVisitor {
......@@ -129,7 +129,7 @@ pub fn annotate_freevars(def_map: resolve::DefMap, krate: &ast::Crate) ->
freevar_map {
let mut visitor = AnnotateFreevarsVisitor {
def_map: def_map,
freevars: HashMap::new(),
freevars: NodeMap::new(),
};
visit::walk_crate(&mut visitor, krate, ());
......
......@@ -108,6 +108,7 @@
use middle::ty;
use middle::typeck;
use middle::moves;
use util::nodemap::NodeMap;
use std::cast::transmute;
use std::cell::{Cell, RefCell};
......@@ -116,7 +117,6 @@
use std::str;
use std::uint;
use std::vec;
use collections::HashMap;
use syntax::ast::*;
use syntax::codemap::Span;
use syntax::parse::token::special_idents;
......@@ -258,9 +258,9 @@ pub struct IrMaps {
num_live_nodes: Cell<uint>,
num_vars: Cell<uint>,
live_node_map: RefCell<HashMap<NodeId, LiveNode>>,
variable_map: RefCell<HashMap<NodeId, Variable>>,
capture_info_map: RefCell<HashMap<NodeId, @~[CaptureInfo]>>,
live_node_map: RefCell<NodeMap<LiveNode>>,
variable_map: RefCell<NodeMap<Variable>>,
capture_info_map: RefCell<NodeMap<@~[CaptureInfo]>>,
var_kinds: RefCell<~[VarKind]>,
lnks: RefCell<~[LiveNodeKind]>,
}
......@@ -275,9 +275,9 @@ fn IrMaps(tcx: ty::ctxt,
capture_map: capture_map,
num_live_nodes: Cell::new(0),
num_vars: Cell::new(0),
live_node_map: RefCell::new(HashMap::new()),
variable_map: RefCell::new(HashMap::new()),
capture_info_map: RefCell::new(HashMap::new()),
live_node_map: RefCell::new(NodeMap::new()),
variable_map: RefCell::new(NodeMap::new()),
capture_info_map: RefCell::new(NodeMap::new()),
var_kinds: RefCell::new(~[]),
lnks: RefCell::new(~[]),
}
......@@ -584,7 +584,7 @@ pub struct Specials {
static ACC_WRITE: uint = 2u;
static ACC_USE: uint = 4u;
pub type LiveNodeMap = @RefCell<HashMap<NodeId, LiveNode>>;
pub type LiveNodeMap = @RefCell<NodeMap<LiveNode>>;
pub struct Liveness {
tcx: ty::ctxt,
......@@ -613,8 +613,8 @@ fn Liveness(ir: @IrMaps, specials: Specials) -> Liveness {
ir.num_vars.get(),
invalid_users())),
loop_scope: @RefCell::new(~[]),
break_ln: @RefCell::new(HashMap::new()),
cont_ln: @RefCell::new(HashMap::new()),
break_ln: @RefCell::new(NodeMap::new()),
cont_ln: @RefCell::new(NodeMap::new()),
}
}
......
......@@ -135,10 +135,10 @@ struct Foo { a: int, b: ~int }
use util::ppaux::Repr;
use util::common::indenter;
use util::ppaux::UserString;
use util::nodemap::{NodeMap, NodeSet};
use std::cell::RefCell;
use std::rc::Rc;
use collections::{HashSet, HashMap};
use syntax::ast::*;
use syntax::ast_util;
use syntax::visit;
......@@ -159,9 +159,9 @@ pub struct CaptureVar {
mode: CaptureMode // How variable is being accessed
}
pub type CaptureMap = @RefCell<HashMap<NodeId, Rc<~[CaptureVar]>>>;
pub type CaptureMap = @RefCell<NodeMap<Rc<~[CaptureVar]>>>;
pub type MovesMap = @RefCell<HashSet<NodeId>>;
pub type MovesMap = @RefCell<NodeSet>;
/**
* Set of variable node-ids that are moved.
......@@ -169,7 +169,7 @@ pub struct CaptureVar {
* Note: The `VariableMovesMap` stores expression ids that
* are moves, whereas this set stores the ids of the variables
* that are moved at some point */
pub type MovedVariablesSet = @RefCell<HashSet<NodeId>>;
pub type MovedVariablesSet = @RefCell<NodeSet>;
/** See the section Output on the module comment for explanation. */
#[deriving(Clone)]
......@@ -215,9 +215,9 @@ pub fn compute_moves(tcx: ty::ctxt,
tcx: tcx,
method_map: method_map,
move_maps: MoveMaps {
moves_map: @RefCell::new(HashSet::new()),
capture_map: @RefCell::new(HashMap::new()),
moved_variables_set: @RefCell::new(HashSet::new())
moves_map: @RefCell::new(NodeSet::new()),
capture_map: @RefCell::new(NodeMap::new()),
moved_variables_set: @RefCell::new(NodeSet::new())
}
};
let visit_cx = &mut visit_cx;
......
......@@ -13,7 +13,6 @@
//! which are available for use externally when compiled as a library.
use std::mem::replace;
use collections::{HashSet, HashMap};
use metadata::csearch;
use middle::lint;
......@@ -21,6 +20,7 @@
use middle::ty;
use middle::typeck::{MethodMap, MethodOrigin, MethodParam};
use middle::typeck::{MethodStatic, MethodObject};
use util::nodemap::{NodeMap, NodeSet};
use syntax::ast;
use syntax::ast_map;
......@@ -35,12 +35,12 @@
type Context<'a> = (&'a MethodMap, &'a resolve::ExportMap2);
/// A set of AST nodes exported by the crate.
pub type ExportedItems = HashSet<ast::NodeId>;
pub type ExportedItems = NodeSet;
/// A set of AST nodes that are fully public in the crate. This map is used for
/// documentation purposes (reexporting a private struct inlines the doc,
/// reexporting a public struct doesn't inline the doc).
pub type PublicItems = HashSet<ast::NodeId>;
pub type PublicItems = NodeSet;
/// Result of a checking operation - None => no errors were found. Some => an
/// error and contains the span and message for reporting that error and
......@@ -52,7 +52,7 @@
////////////////////////////////////////////////////////////////////////////////
struct ParentVisitor {
parents: HashMap<ast::NodeId, ast::NodeId>,
parents: NodeMap<ast::NodeId>,
curparent: ast::NodeId,
}
......@@ -161,7 +161,7 @@ struct EmbargoVisitor<'a> {
// all nodes which are reexported *and* reachable from external crates. This
// means that the destination of the reexport is exported, and hence the
// destination must also be exported.
reexports: HashSet<ast::NodeId>,
reexports: NodeSet,
// These two fields are closely related to one another in that they are only
// used for generation of the 'PublicItems' set, not for privacy checking at
......@@ -349,7 +349,7 @@ struct PrivacyVisitor<'a> {
in_fn: bool,
in_foreign: bool,
method_map: &'a MethodMap,
parents: HashMap<ast::NodeId, ast::NodeId>,
parents: NodeMap<ast::NodeId>,
external_exports: resolve::ExternalExports,
last_private_map: resolve::LastPrivateMap,
}
......@@ -1424,7 +1424,7 @@ pub fn check_crate(tcx: ty::ctxt,
krate: &ast::Crate) -> (ExportedItems, PublicItems) {
// Figure out who everyone's parent is
let mut visitor = ParentVisitor {
parents: HashMap::new(),
parents: NodeMap::new(),
curparent: ast::DUMMY_NODE_ID,
};
visit::walk_crate(&mut visitor, krate, ());
......@@ -1456,9 +1456,9 @@ pub fn check_crate(tcx: ty::ctxt,
// items which are reachable from external crates based on visibility.
let mut visitor = EmbargoVisitor {
tcx: tcx,
exported_items: HashSet::new(),
public_items: HashSet::new(),
reexports: HashSet::new(),
exported_items: NodeSet::new(),
public_items: NodeSet::new(),
reexports: NodeSet::new(),
exp_map2: exp_map2,
prev_exported: true,
prev_public: true,
......
......@@ -18,6 +18,7 @@
use middle::ty;
use middle::typeck;
use middle::privacy;
use util::nodemap::NodeSet;
use std::cell::RefCell;
use collections::HashSet;
......@@ -88,7 +89,7 @@ struct ReachableContext {
// methods they've been resolved to.
method_map: typeck::MethodMap,
// The set of items which must be exported in the linkage sense.
reachable_symbols: @RefCell<HashSet<ast::NodeId>>,
reachable_symbols: @RefCell<NodeSet>,
// A worklist of item IDs. Each item ID in this worklist will be inlined
// and will be scanned for further references.
worklist: @RefCell<~[ast::NodeId]>,
......@@ -98,7 +99,7 @@ struct MarkSymbolVisitor {
worklist: @RefCell<~[ast::NodeId]>,
method_map: typeck::MethodMap,
tcx: ty::ctxt,
reachable_symbols: @RefCell<HashSet<ast::NodeId>>,
reachable_symbols: @RefCell<NodeSet>,
}
impl Visitor<()> for MarkSymbolVisitor {
......@@ -188,7 +189,7 @@ fn new(tcx: ty::ctxt, method_map: typeck::MethodMap) -> ReachableContext {
ReachableContext {
tcx: tcx,
method_map: method_map,
reachable_symbols: @RefCell::new(HashSet::new()),
reachable_symbols: @RefCell::new(NodeSet::new()),
worklist: @RefCell::new(~[]),
}
}
......@@ -395,7 +396,7 @@ fn mark_destructors_reachable(&self) {
pub fn find_reachable(tcx: ty::ctxt,
method_map: typeck::MethodMap,
exported_items: &privacy::ExportedItems)
-> @RefCell<HashSet<ast::NodeId>> {
-> @RefCell<NodeSet> {
let reachable_context = ReachableContext::new(tcx, method_map);
// Step 1: Seed the worklist with all nodes which were found to be public as
......
......@@ -24,6 +24,7 @@
use driver::session::Session;
use middle::ty::{FreeRegion};
use middle::ty;
use util::nodemap::NodeMap;
use std::cell::RefCell;
use collections::{HashMap, HashSet};
......@@ -74,10 +75,10 @@
for dynamic checks and/or arbitrary amounts of stack space.
*/
pub struct RegionMaps {
priv scope_map: RefCell<HashMap<ast::NodeId, ast::NodeId>>,
priv var_map: RefCell<HashMap<ast::NodeId, ast::NodeId>>,
priv scope_map: RefCell<NodeMap<ast::NodeId>>,
priv var_map: RefCell<NodeMap<ast::NodeId>>,
priv free_region_map: RefCell<HashMap<FreeRegion, ~[FreeRegion]>>,
priv rvalue_scopes: RefCell<HashMap<ast::NodeId, ast::NodeId>>,
priv rvalue_scopes: RefCell<NodeMap<ast::NodeId>>,
priv terminating_scopes: RefCell<HashSet<ast::NodeId>>,
}
......@@ -910,10 +911,10 @@ fn visit_local(&mut self, l: &Local, cx: Context) {
pub fn resolve_crate(sess: Session, krate: &ast::Crate) -> RegionMaps {
let maps = RegionMaps {
scope_map: RefCell::new(HashMap::new()),
var_map: RefCell::new(HashMap::new()),
scope_map: RefCell::new(NodeMap::new()),
var_map: RefCell::new(NodeMap::new()),
free_region_map: RefCell::new(HashMap::new()),
rvalue_scopes: RefCell::new(HashMap::new()),
rvalue_scopes: RefCell::new(NodeMap::new()),
terminating_scopes: RefCell::new(HashSet::new()),
};
{
......
......@@ -16,6 +16,7 @@
use middle::lang_items::LanguageItems;
use middle::lint::{UnnecessaryQualification, UnusedImports};
use middle::pat_util::pat_bindings;
use util::nodemap::{NodeMap, DefIdSet};
use syntax::ast::*;
use syntax::ast;
......@@ -36,7 +37,7 @@
use collections::{HashMap, HashSet};
// Definition mapping
pub type DefMap = @RefCell<HashMap<NodeId,Def>>;
pub type DefMap = @RefCell<NodeMap<Def>>;
struct binding_info {
span: Span,
......@@ -47,11 +48,11 @@ struct binding_info {
type BindingMap = HashMap<Name,binding_info>;
// Trait method resolution
pub type TraitMap = HashMap<NodeId, ~[DefId]>;
pub type TraitMap = NodeMap<~[DefId]>;
// This is the replacement export map. It maps a module to all of the exports
// within.
pub type ExportMap2 = @RefCell<HashMap<NodeId, ~[Export2]>>;
pub type ExportMap2 = @RefCell<NodeMap<~[Export2]>>;
pub struct Export2 {
name: ~str, // The name of the target.
......@@ -60,10 +61,10 @@ pub struct Export2 {
// This set contains all exported definitions from external crates. The set does
// not contain any entries from local crates.
pub type ExternalExports = HashSet<DefId>;
pub type ExternalExports = DefIdSet;
// FIXME: dox
pub type LastPrivateMap = HashMap<NodeId, LastPrivate>;
pub type LastPrivateMap = NodeMap<LastPrivate>;
pub enum LastPrivate {
LastMod(PrivateDep),
......@@ -457,7 +458,7 @@ struct Module {
//
// There will be an anonymous module created around `g` with the ID of the
// entry block for `f`.
anonymous_children: RefCell<HashMap<NodeId,@Module>>,
anonymous_children: RefCell<NodeMap<@Module>>,
// The status of resolving each import in this module.
import_resolutions: RefCell<HashMap<Name, @ImportResolution>>,
......@@ -489,7 +490,7 @@ fn new(parent_link: ParentLink,
children: RefCell::new(HashMap::new()),
imports: RefCell::new(~[]),
external_module_children: RefCell::new(HashMap::new()),
anonymous_children: RefCell::new(HashMap::new()),
anonymous_children: RefCell::new(NodeMap::new()),
import_resolutions: RefCell::new(HashMap::new()),
glob_count: Cell::new(0),
resolved_import_count: Cell::new(0),
......@@ -827,12 +828,12 @@ fn Resolver(session: Session,
namespaces: ~[ TypeNS, ValueNS ],
def_map: @RefCell::new(HashMap::new()),
export_map2: @RefCell::new(HashMap::new()),
trait_map: HashMap::new(),
def_map: @RefCell::new(NodeMap::new()),
export_map2: @RefCell::new(NodeMap::new()),
trait_map: NodeMap::new(),
used_imports: HashSet::new(),
external_exports: HashSet::new(),
last_private: HashMap::new(),
external_exports: DefIdSet::new(),
last_private: NodeMap::new(),
emit_errors: true,
};
......
......@@ -19,7 +19,7 @@
use driver::session;
use std::cell::RefCell;
use collections::HashMap;
use util::nodemap::NodeMap;
use syntax::ast;
use syntax::codemap::Span;
use syntax::opt_vec::OptVec;
......@@ -31,7 +31,7 @@
// maps the id of each lifetime reference to the lifetime decl
// that it corresponds to
pub type NamedRegionMap = HashMap<ast::NodeId, ast::DefRegion>;
pub type NamedRegionMap = NodeMap<ast::DefRegion>;
struct LifetimeContext {
sess: session::Session,
......@@ -49,7 +49,7 @@ pub fn krate(sess: session::Session, krate: &ast::Crate)
-> @RefCell<NamedRegionMap> {
let mut ctxt = LifetimeContext {
sess: sess,
named_region_map: @RefCell::new(HashMap::new())
named_region_map: @RefCell::new(NodeMap::new())
};
visit::walk_crate(&mut ctxt, krate, &RootScope);
sess.abort_if_errors();
......
......@@ -70,6 +70,7 @@
use util::common::indenter;
use util::ppaux::{Repr, ty_to_str};
use util::sha2::Sha256;
use util::nodemap::NodeMap;
use arena::TypedArena;
use std::c_str::ToCStr;
......@@ -1245,9 +1246,9 @@ pub fn new_fn_ctxt<'a>(ccx: @CrateContext,
llreturn: Cell::new(None),
personality: Cell::new(None),
caller_expects_out_pointer: uses_outptr,
llargs: RefCell::new(HashMap::new()),
lllocals: RefCell::new(HashMap::new()),
llupvars: RefCell::new(HashMap::new()),
llargs: RefCell::new(NodeMap::new()),
lllocals: RefCell::new(NodeMap::new()),
llupvars: RefCell::new(NodeMap::new()),
id: id,
param_substs: param_substs,
span: sp,
......
......@@ -29,6 +29,7 @@
use middle::ty;
use middle::typeck;
use util::ppaux::Repr;
use util::nodemap::NodeMap;
use arena::TypedArena;
use std::c_str::ToCStr;
......@@ -253,14 +254,14 @@ pub struct FunctionContext<'a> {
caller_expects_out_pointer: bool,
// Maps arguments to allocas created for them in llallocas.
llargs: RefCell<HashMap<ast::NodeId, LvalueDatum>>,
llargs: RefCell<NodeMap<LvalueDatum>>,
// Maps the def_ids for local variables to the allocas created for
// them in llallocas.
lllocals: RefCell<HashMap<ast::NodeId, LvalueDatum>>,
lllocals: RefCell<NodeMap<LvalueDatum>>,
// Same as above, but for closure upvars
llupvars: RefCell<HashMap<ast::NodeId, ValueRef>>,
llupvars: RefCell<NodeMap<ValueRef>>,
// The NodeId of the function, or -1 if it doesn't correspond to
// a user-defined function.
......
......@@ -27,6 +27,7 @@
use middle::trans::type_::Type;
use middle::ty;
use util::sha2::Sha256;
use util::nodemap::{NodeMap, NodeSet, DefIdMap};
use std::cell::{Cell, RefCell};
use std::c_str::ToCStr;
......@@ -45,10 +46,10 @@ pub struct CrateContext {
tn: TypeNames,
externs: RefCell<ExternMap>,
intrinsics: HashMap<&'static str, ValueRef>,
item_vals: RefCell<HashMap<ast::NodeId, ValueRef>>,
item_vals: RefCell<NodeMap<ValueRef>>,
exp_map2: resolve::ExportMap2,
reachable: @RefCell<HashSet<ast::NodeId>>,
item_symbols: RefCell<HashMap<ast::NodeId, ~str>>,
reachable: @RefCell<NodeSet>,
item_symbols: RefCell<NodeMap<~str>>,
link_meta: LinkMeta,
drop_glues: RefCell<HashMap<ty::t, ValueRef>>,
tydescs: RefCell<HashMap<ty::t, @tydesc_info>>,
......@@ -56,17 +57,17 @@ pub struct CrateContext {
// created.
finished_tydescs: Cell<bool>,
// Track mapping of external ids to local items imported for inlining
external: RefCell<HashMap<ast::DefId, Option<ast::NodeId>>>,
external: RefCell<DefIdMap<Option<ast::NodeId>>>,
// Backwards version of the `external` map (inlined items to where they
// came from)
external_srcs: RefCell<HashMap<ast::NodeId, ast::DefId>>,
external_srcs: RefCell<NodeMap<ast::DefId>>,
// A set of static items which cannot be inlined into other crates. This
// will pevent in IIItem() structures from being encoded into the metadata
// that is generated
non_inlineable_statics: RefCell<HashSet<ast::NodeId>>,
non_inlineable_statics: RefCell<NodeSet>,
// Cache instances of monomorphized functions
monomorphized: RefCell<HashMap<mono_id, ValueRef>>,
monomorphizing: RefCell<HashMap<ast::DefId, uint>>,
monomorphizing: RefCell<DefIdMap<uint>>,
// Cache generated vtables
vtables: RefCell<HashMap<(ty::t, mono_id), ValueRef>>,
// Cache of constant strings,
......@@ -83,10 +84,10 @@ pub struct CrateContext {
const_globals: RefCell<HashMap<int, ValueRef>>,
// Cache of emitted const values
const_values: RefCell<HashMap<ast::NodeId, ValueRef>>,
const_values: RefCell<NodeMap<ValueRef>>,
// Cache of external const values
extern_const_values: RefCell<HashMap<ast::DefId, ValueRef>>,
extern_const_values: RefCell<DefIdMap<ValueRef>>,
impl_method_cache: RefCell<HashMap<(ast::DefId, ast::Name), ast::DefId>>,
......@@ -125,7 +126,7 @@ pub fn new(sess: session::Session,
maps: astencode::Maps,
symbol_hasher: Sha256,
link_meta: LinkMeta,
reachable: @RefCell<HashSet<ast::NodeId>>)
reachable: @RefCell<NodeSet>)
-> CrateContext {
unsafe {
let llcx = llvm::LLVMContextCreate();
......@@ -185,24 +186,24 @@ pub fn new(sess: session::Session,
tn: tn,
externs: RefCell::new(HashMap::new()),
intrinsics: intrinsics,
item_vals: RefCell::new(HashMap::new()),
item_vals: RefCell::new(NodeMap::new()),
exp_map2: emap2,
reachable: reachable,
item_symbols: RefCell::new(HashMap::new()),
item_symbols: RefCell::new(NodeMap::new()),
link_meta: link_meta,
drop_glues: RefCell::new(HashMap::new()),
tydescs: RefCell::new(HashMap::new()),
finished_tydescs: Cell::new(false),
external: RefCell::new(HashMap::new()),
external_srcs: RefCell::new(HashMap::new()),
non_inlineable_statics: RefCell::new(HashSet::new()),
external: RefCell::new(DefIdMap::new()),
external_srcs: RefCell::new(NodeMap::new()),
non_inlineable_statics: RefCell::new(NodeSet::new()),
monomorphized: RefCell::new(HashMap::new()),
monomorphizing: RefCell::new(HashMap::new()),
monomorphizing: RefCell::new(DefIdMap::new()),
vtables: RefCell::new(HashMap::new()),
const_cstr_cache: RefCell::new(HashMap::new()),
const_globals: RefCell::new(HashMap::new()),
const_values: RefCell::new(HashMap::new()),
extern_const_values: RefCell::new(HashMap::new()),
const_values: RefCell::new(NodeMap::new()),
extern_const_values: RefCell::new(DefIdMap::new()),
impl_method_cache: RefCell::new(HashMap::new()),
closure_bare_wrapper_cache: RefCell::new(HashMap::new()),
module_data: RefCell::new(HashMap::new()),
......
......@@ -66,11 +66,10 @@
use middle::ty;
use util::common::indenter;
use util::ppaux::Repr;
use util::nodemap::NodeMap;
use middle::trans::machine::llsize_of;
use middle::trans::type_::Type;
use collections::HashMap;
use std::vec;
use syntax::ast;
use syntax::ast_map;
......@@ -944,7 +943,7 @@ pub fn trans_local_var<'a>(bcx: &'a Block<'a>,
};
fn take_local<'a>(bcx: &'a Block<'a>,
table: &HashMap<ast::NodeId, Datum<Lvalue>>,
table: &NodeMap<Datum<Lvalue>>,
nid: ast::NodeId)
-> Datum<Lvalue> {
let datum = match table.find(&nid) {
......
......@@ -30,6 +30,7 @@
use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str};
use util::ppaux::{Repr, UserString};
use util::common::{indenter};
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
use std::cast;
use std::cell::{Cell, RefCell};
......@@ -178,11 +179,16 @@ fn ne(&self, other: &intern_key) -> bool {
}
}
#[cfg(stage0)]
impl Hash for intern_key {
fn hash(&self, s: &mut sip::SipState) {
unsafe {
(*self.sty).hash(s)
}
unsafe { (*self.sty).hash(s) }
}
}
#[cfg(not(stage0))]
impl<W:Writer> Hash<W> for intern_key {
fn hash(&self, s: &mut W) {
unsafe { (*self.sty).hash(s) }
}
}
......@@ -250,7 +256,12 @@ pub enum AutoRef {
/// later on.
pub struct ctxt_ {
diag: @syntax::diagnostic::SpanHandler,
// Specifically use a speedy hash algorithm for this hash map, it's used
// quite often.
#[cfg(stage0)]
interner: RefCell<HashMap<intern_key, ~t_box_>>,
#[cfg(not(stage0))]
interner: RefCell<HashMap<intern_key, ~t_box_, ::util::nodemap::FnvHasher>>,
next_id: Cell<uint>,
cstore: @metadata::cstore::CStore,
sess: session::Session,
......@@ -269,94 +280,94 @@ pub struct ctxt_ {
// of this node. This only applies to nodes that refer to entities
// parameterized by type parameters, such as generic fns, types, or
// other items.
node_type_substs: RefCell<HashMap<NodeId, ~[t]>>,
node_type_substs: RefCell<NodeMap<~[t]>>,
// Maps from a method to the method "descriptor"
methods: RefCell<HashMap<DefId, @Method>>,
methods: RefCell<DefIdMap<@Method>>,
// Maps from a trait def-id to a list of the def-ids of its methods
trait_method_def_ids: RefCell<HashMap<DefId, @~[DefId]>>,
trait_method_def_ids: RefCell<DefIdMap<@~[DefId]>>,
// A cache for the trait_methods() routine
trait_methods_cache: RefCell<HashMap<DefId, @~[@Method]>>,
trait_methods_cache: RefCell<DefIdMap<@~[@Method]>>,
impl_trait_cache: RefCell<HashMap<ast::DefId, Option<@ty::TraitRef>>>,
impl_trait_cache: RefCell<DefIdMap<Option<@ty::TraitRef>>>,
trait_refs: RefCell<HashMap<NodeId, @TraitRef>>,
trait_defs: RefCell<HashMap<DefId, @TraitDef>>,
trait_refs: RefCell<NodeMap<@TraitRef>>,
trait_defs: RefCell<DefIdMap<@TraitDef>>,
map: ast_map::Map,
intrinsic_defs: RefCell<HashMap<ast::DefId, t>>,
intrinsic_defs: RefCell<DefIdMap<t>>,
freevars: RefCell<freevars::freevar_map>,
tcache: type_cache,
rcache: creader_cache,
short_names_cache: RefCell<HashMap<t, ~str>>,
needs_unwind_cleanup_cache: RefCell<HashMap<t, bool>>,
tc_cache: RefCell<HashMap<uint, TypeContents>>,
ast_ty_to_ty_cache: RefCell<HashMap<NodeId, ast_ty_to_ty_cache_entry>>,
enum_var_cache: RefCell<HashMap<DefId, @~[@VariantInfo]>>,
ty_param_defs: RefCell<HashMap<ast::NodeId, TypeParameterDef>>,
adjustments: RefCell<HashMap<ast::NodeId, @AutoAdjustment>>,
ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry>>,
enum_var_cache: RefCell<DefIdMap<@~[@VariantInfo]>>,
ty_param_defs: RefCell<NodeMap<TypeParameterDef>>,
adjustments: RefCell<NodeMap<@AutoAdjustment>>,
normalized_cache: RefCell<HashMap<t, t>>,
lang_items: @middle::lang_items::LanguageItems,
// A mapping of fake provided method def_ids to the default implementation
provided_method_sources: RefCell<HashMap<ast::DefId, ast::DefId>>,
supertraits: RefCell<HashMap<ast::DefId, @~[@TraitRef]>>,
provided_method_sources: RefCell<DefIdMap<ast::DefId>>,
supertraits: RefCell<DefIdMap<@~[@TraitRef]>>,
// Maps from def-id of a type or region parameter to its
// (inferred) variance.
item_variance_map: RefCell<HashMap<ast::DefId, @ItemVariances>>,
item_variance_map: RefCell<DefIdMap<@ItemVariances>>,
// A mapping from the def ID of an enum or struct type to the def ID
// of the method that implements its destructor. If the type is not
// present in this map, it does not have a destructor. This map is
// populated during the coherence phase of typechecking.
destructor_for_type: RefCell<HashMap<ast::DefId, ast::DefId>>,
destructor_for_type: RefCell<DefIdMap<ast::DefId>>,
// A method will be in this list if and only if it is a destructor.
destructors: RefCell<HashSet<ast::DefId>>,
destructors: RefCell<DefIdSet>,
// Maps a trait onto a list of impls of that trait.
trait_impls: RefCell<HashMap<ast::DefId, @RefCell<~[@Impl]>>>,
trait_impls: RefCell<DefIdMap<@RefCell<~[@Impl]>>>,
// Maps a def_id of a type to a list of its inherent impls.
// Contains implementations of methods that are inherent to a type.
// Methods in these implementations don't need to be exported.
inherent_impls: RefCell<HashMap<ast::DefId, @RefCell<~[@Impl]>>>,
inherent_impls: RefCell<DefIdMap<@RefCell<~[@Impl]>>>,
// Maps a def_id of an impl to an Impl structure.
// Note that this contains all of the impls that we know about,
// including ones in other crates. It's not clear that this is the best
// way to do it.
impls: RefCell<HashMap<ast::DefId, @Impl>>,
impls: RefCell<DefIdMap<@Impl>>,
// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
// present in this set can be warned about.
used_unsafe: RefCell<HashSet<ast::NodeId>>,
used_unsafe: RefCell<NodeSet>,
// Set of nodes which mark locals as mutable which end up getting used at
// some point. Local variable definitions not in this set can be warned
// about.
used_mut_nodes: RefCell<HashSet<ast::NodeId>>,
used_mut_nodes: RefCell<NodeSet>,
// vtable resolution information for impl declarations
impl_vtables: typeck::impl_vtable_map,
// The set of external nominal types whose implementations have been read.
// This is used for lazy resolution of methods.
populated_external_types: RefCell<HashSet<ast::DefId>>,
populated_external_types: RefCell<DefIdSet>,
// The set of external traits whose implementations have been read. This
// is used for lazy resolution of traits.
populated_external_traits: RefCell<HashSet<ast::DefId>>,
populated_external_traits: RefCell<DefIdSet>,
// Borrows
upvar_borrow_map: RefCell<UpvarBorrowMap>,
// These two caches are used by const_eval when decoding external statics
// and variants that are found.
extern_const_statics: RefCell<HashMap<ast::DefId, Option<@ast::Expr>>>,
extern_const_variants: RefCell<HashMap<ast::DefId, Option<@ast::Expr>>>,
extern_const_statics: RefCell<DefIdMap<Option<@ast::Expr>>>,
extern_const_variants: RefCell<DefIdMap<Option<@ast::Expr>>>,
}
pub enum tbox_flag {
......@@ -1068,7 +1079,7 @@ pub struct ty_param_substs_and_ty {
ty: ty::t
}
pub type type_cache = RefCell<HashMap<ast::DefId, ty_param_bounds_and_ty>>;
pub type type_cache = RefCell<DefIdMap<ty_param_bounds_and_ty>>;
pub type node_type_table = RefCell<HashMap<uint,t>>;
......@@ -1080,54 +1091,61 @@ pub fn mk_ctxt(s: session::Session,
region_maps: middle::region::RegionMaps,
lang_items: @middle::lang_items::LanguageItems)
-> ctxt {
#[cfg(stage0)]
fn hasher() -> HashMap<intern_key, ~t_box_> {
HashMap::new()
}
#[cfg(not(stage0))]
fn hasher() -> HashMap<intern_key, ~t_box_, ::util::nodemap::FnvHasher> {
HashMap::with_hasher(::util::nodemap::FnvHasher)
}
@ctxt_ {
named_region_map: named_region_map,
item_variance_map: RefCell::new(HashMap::new()),
item_variance_map: RefCell::new(DefIdMap::new()),
diag: s.diagnostic(),
interner: RefCell::new(HashMap::new()),
interner: RefCell::new(hasher()),
next_id: Cell::new(primitives::LAST_PRIMITIVE_ID),
cstore: s.cstore,
sess: s,
def_map: dm,
region_maps: region_maps,
node_types: RefCell::new(HashMap::new()),
node_type_substs: RefCell::new(HashMap::new()),
trait_refs: RefCell::new(HashMap::new()),
trait_defs: RefCell::new(HashMap::new()),
node_type_substs: RefCell::new(NodeMap::new()),
trait_refs: RefCell::new(NodeMap::new()),
trait_defs: RefCell::new(DefIdMap::new()),
map: map,
intrinsic_defs: RefCell::new(HashMap::new()),
intrinsic_defs: RefCell::new(DefIdMap::new()),
freevars: RefCell::new(freevars),
tcache: RefCell::new(HashMap::new()),
tcache: RefCell::new(DefIdMap::new()),
rcache: RefCell::new(HashMap::new()),
short_names_cache: RefCell::new(HashMap::new()),
needs_unwind_cleanup_cache: RefCell::new(HashMap::new()),
tc_cache: RefCell::new(HashMap::new()),
ast_ty_to_ty_cache: RefCell::new(HashMap::new()),
enum_var_cache: RefCell::new(HashMap::new()),
methods: RefCell::new(HashMap::new()),
trait_method_def_ids: RefCell::new(HashMap::new()),
trait_methods_cache: RefCell::new(HashMap::new()),
impl_trait_cache: RefCell::new(HashMap::new()),
ty_param_defs: RefCell::new(HashMap::new()),
adjustments: RefCell::new(HashMap::new()),
ast_ty_to_ty_cache: RefCell::new(NodeMap::new()),
enum_var_cache: RefCell::new(DefIdMap::new()),
methods: RefCell::new(DefIdMap::new()),
trait_method_def_ids: RefCell::new(DefIdMap::new()),
trait_methods_cache: RefCell::new(DefIdMap::new()),
impl_trait_cache: RefCell::new(DefIdMap::new()),
ty_param_defs: RefCell::new(NodeMap::new()),
adjustments: RefCell::new(NodeMap::new()),
normalized_cache: RefCell::new(HashMap::new()),
lang_items: lang_items,
provided_method_sources: RefCell::new(HashMap::new()),
supertraits: RefCell::new(HashMap::new()),
destructor_for_type: RefCell::new(HashMap::new()),
destructors: RefCell::new(HashSet::new()),
trait_impls: RefCell::new(HashMap::new()),
inherent_impls: RefCell::new(HashMap::new()),
impls: RefCell::new(HashMap::new()),
used_unsafe: RefCell::new(HashSet::new()),
used_mut_nodes: RefCell::new(HashSet::new()),
impl_vtables: RefCell::new(HashMap::new()),
populated_external_types: RefCell::new(HashSet::new()),
populated_external_traits: RefCell::new(HashSet::new()),
provided_method_sources: RefCell::new(DefIdMap::new()),
supertraits: RefCell::new(DefIdMap::new()),
destructor_for_type: RefCell::new(DefIdMap::new()),
destructors: RefCell::new(DefIdSet::new()),
trait_impls: RefCell::new(DefIdMap::new()),
inherent_impls: RefCell::new(DefIdMap::new()),
impls: RefCell::new(DefIdMap::new()),
used_unsafe: RefCell::new(NodeSet::new()),
used_mut_nodes: RefCell::new(NodeSet::new()),
impl_vtables: RefCell::new(DefIdMap::new()),
populated_external_types: RefCell::new(DefIdSet::new()),
populated_external_traits: RefCell::new(DefIdSet::new()),
upvar_borrow_map: RefCell::new(HashMap::new()),
extern_const_statics: RefCell::new(HashMap::new()),
extern_const_variants: RefCell::new(HashMap::new()),
extern_const_statics: RefCell::new(DefIdMap::new()),
extern_const_variants: RefCell::new(DefIdMap::new()),
}
}
......@@ -3787,7 +3805,7 @@ pub fn trait_ref_supertraits(cx: ctxt, trait_ref: &ty::TraitRef) -> ~[@TraitRef]
fn lookup_locally_or_in_crate_store<V:Clone>(
descr: &str,
def_id: ast::DefId,
map: &mut HashMap<ast::DefId, V>,
map: &mut DefIdMap<V>,
load_external: || -> V) -> V {
/*!
* Helper for looking things up in the various maps
......
......@@ -111,6 +111,7 @@
use util::common::{block_query, indenter, loop_query};
use util::ppaux;
use util::ppaux::{UserString, Repr};
use util::nodemap::NodeMap;
use std::cell::{Cell, RefCell};
use collections::HashMap;
......@@ -153,13 +154,13 @@
/// share the inherited fields.
pub struct Inherited {
infcx: infer::InferCtxt,
locals: @RefCell<HashMap<ast::NodeId, ty::t>>,
locals: @RefCell<NodeMap<ty::t>>,
param_env: ty::ParameterEnvironment,
// Temporary tables:
node_types: RefCell<HashMap<ast::NodeId, ty::t>>,
node_type_substs: RefCell<HashMap<ast::NodeId, ty::substs>>,
adjustments: RefCell<HashMap<ast::NodeId, @ty::AutoAdjustment>>,
node_types: RefCell<NodeMap<ty::t>>,
node_type_substs: RefCell<NodeMap<ty::substs>>,
adjustments: RefCell<NodeMap<@ty::AutoAdjustment>>,
method_map: MethodMap,
vtable_map: vtable_map,
upvar_borrow_map: RefCell<ty::UpvarBorrowMap>,
......@@ -258,13 +259,13 @@ fn new(tcx: ty::ctxt,
-> Inherited {
Inherited {
infcx: infer::new_infer_ctxt(tcx),
locals: @RefCell::new(HashMap::new()),
locals: @RefCell::new(NodeMap::new()),
param_env: param_env,
node_types: RefCell::new(HashMap::new()),
node_type_substs: RefCell::new(HashMap::new()),
adjustments: RefCell::new(HashMap::new()),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
node_types: RefCell::new(NodeMap::new()),
node_type_substs: RefCell::new(NodeMap::new()),
adjustments: RefCell::new(NodeMap::new()),
method_map: @RefCell::new(NodeMap::new()),
vtable_map: @RefCell::new(NodeMap::new()),
upvar_borrow_map: RefCell::new(HashMap::new()),
}
}
......
......@@ -68,9 +68,9 @@
use util::common::time;
use util::ppaux::Repr;
use util::ppaux;
use util::nodemap::{DefIdMap, NodeMap};
use std::cell::RefCell;
use collections::HashMap;
use std::rc::Rc;
use collections::List;
use syntax::codemap::Span;
......@@ -150,7 +150,7 @@ pub struct MethodCallee {
// maps from an expression id that corresponds to a method call to the details
// of the method to be invoked
pub type MethodMap = @RefCell<HashMap<ast::NodeId, MethodCallee>>;
pub type MethodMap = @RefCell<NodeMap<MethodCallee>>;
pub type vtable_param_res = @~[vtable_origin];
// Resolutions for bounds of all parameters, left to right, for a given path.
......@@ -194,7 +194,7 @@ fn repr(&self, tcx: ty::ctxt) -> ~str {
}
}
pub type vtable_map = @RefCell<HashMap<ast::NodeId, vtable_res>>;
pub type vtable_map = @RefCell<NodeMap<vtable_res>>;
// Information about the vtable resolutions for a trait impl.
......@@ -216,7 +216,7 @@ fn repr(&self, tcx: ty::ctxt) -> ~str {
}
}
pub type impl_vtable_map = RefCell<HashMap<ast::DefId, impl_res>>;
pub type impl_vtable_map = RefCell<DefIdMap<impl_res>>;
pub struct CrateCtxt {
// A mapping from method call sites to traits that have that method.
......@@ -441,8 +441,8 @@ pub fn check_crate(tcx: ty::ctxt,
let time_passes = tcx.sess.time_passes();
let ccx = @CrateCtxt {
trait_map: trait_map,
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
method_map: @RefCell::new(NodeMap::new()),
vtable_map: @RefCell::new(NodeMap::new()),
tcx: tcx
};
......
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! An efficient hash map for node IDs
use collections::{HashMap, HashSet};
use std::hash::{Hasher, Hash};
use std::io;
use syntax::ast;
#[cfg(not(stage0))]
pub type NodeMap<T> = HashMap<ast::NodeId, T, FnvHasher>;
#[cfg(not(stage0))]
pub type DefIdMap<T> = HashMap<ast::DefId, T, FnvHasher>;
#[cfg(not(stage0))]
pub type NodeSet = HashSet<ast::NodeId, FnvHasher>;
#[cfg(not(stage0))]
pub type DefIdSet = HashSet<ast::DefId, FnvHasher>;
// Hacks to get good names
#[cfg(not(stage0))]
pub mod NodeMap {
use collections::HashMap;
pub fn new<T>() -> super::NodeMap<T> {
HashMap::with_hasher(super::FnvHasher)
}
}
#[cfg(not(stage0))]
pub mod NodeSet {
use collections::HashSet;
pub fn new() -> super::NodeSet {
HashSet::with_hasher(super::FnvHasher)
}
}
#[cfg(not(stage0))]
pub mod DefIdMap {
use collections::HashMap;
pub fn new<T>() -> super::DefIdMap<T> {
HashMap::with_hasher(super::FnvHasher)
}
}
#[cfg(not(stage0))]
pub mod DefIdSet {
use collections::HashSet;
pub fn new() -> super::DefIdSet {
HashSet::with_hasher(super::FnvHasher)
}
}
#[cfg(stage0)]
pub type NodeMap<T> = HashMap<ast::NodeId, T>;
#[cfg(stage0)]
pub type DefIdMap<T> = HashMap<ast::DefId, T>;
#[cfg(stage0)]
pub type NodeSet = HashSet<ast::NodeId>;
#[cfg(stage0)]
pub type DefIdSet = HashSet<ast::DefId>;
// Hacks to get good names
#[cfg(stage0)]
pub mod NodeMap {
use collections::HashMap;
pub fn new<T>() -> super::NodeMap<T> {
HashMap::new()
}
}
#[cfg(stage0)]
pub mod NodeSet {
use collections::HashSet;
pub fn new() -> super::NodeSet {
HashSet::new()
}
}
#[cfg(stage0)]
pub mod DefIdMap {
use collections::HashMap;
pub fn new<T>() -> super::DefIdMap<T> {
HashMap::new()
}
}
#[cfg(stage0)]
pub mod DefIdSet {
use collections::HashSet;
pub fn new() -> super::DefIdSet {
HashSet::new()
}
}
/// A speedy hash algorithm for node ids and def ids. The hashmap in
/// libcollections by default uses SipHash which isn't quite as speedy as we
/// want. In the compiler we're not really worried about DOS attempts, so we
/// just default to a non-cryptographic hash.
///
/// This uses FNV hashing, as described here:
/// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
#[deriving(Clone)]
pub struct FnvHasher;
pub struct FnvState(u64);
impl Hasher<FnvState> for FnvHasher {
fn hash<T: Hash<FnvState>>(&self, t: &T) -> u64 {
let mut state = FnvState(0xcbf29ce484222325);
t.hash(&mut state);
let FnvState(ret) = state;
return ret;
}
}
impl Writer for FnvState {
fn write(&mut self, bytes: &[u8]) -> io::IoResult<()> {
let FnvState(mut hash) = *self;
for byte in bytes.iter() {
hash = hash * 0x100000001b3;
hash = hash ^ (*byte as u64);
}
*self = FnvState(hash);
Ok(())
}
}
......@@ -46,6 +46,7 @@
use syntax::ast;
use syntax::attr;
use syntax::parse::token::InternedString;
use rustc::util::nodemap::NodeSet;
use clean;
use doctree;
......@@ -158,7 +159,7 @@ pub struct Cache {
priv parent_stack: ~[ast::NodeId],
priv search_index: ~[IndexItem],
priv privmod: bool,
priv public_items: HashSet<ast::NodeId>,
priv public_items: NodeSet,
}
/// Helper struct to render all source code to HTML pages
......@@ -235,7 +236,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
// Crawl the crate to build various caches used for the output
let mut cache = local_data::get(::analysiskey, |analysis| {
let public_items = analysis.map(|a| a.public_items.clone());
let public_items = public_items.unwrap_or(HashSet::new());
let public_items = public_items.unwrap_or(NodeSet::new());
Cache {
impls: HashMap::new(),
typarams: HashMap::new(),
......
......@@ -13,6 +13,7 @@
use std::local_data;
use std::uint;
use syntax::ast;
use rustc::util::nodemap::NodeSet;
use clean;
use clean::Item;
......@@ -110,7 +111,7 @@ pub fn strip_private(krate: clean::Crate) -> plugins::PluginResult {
struct Stripper<'a> {
retained: &'a mut HashSet<ast::NodeId>,
exported_items: &'a HashSet<ast::NodeId>,
exported_items: &'a NodeSet,
}
impl<'a> fold::DocFolder for Stripper<'a> {
......
......@@ -283,7 +283,7 @@ pub struct ExtCtxt<'a> {
parse_sess: @parse::ParseSess,
cfg: ast::CrateConfig,
backtrace: Option<@ExpnInfo>,
loader: &'a mut CrateLoader,
ecfg: expand::ExpansionConfig<'a>,
mod_path: Vec<ast::Ident> ,
trace_mac: bool
......@@ -291,13 +291,13 @@ pub struct ExtCtxt<'a> {
impl<'a> ExtCtxt<'a> {
pub fn new<'a>(parse_sess: @parse::ParseSess, cfg: ast::CrateConfig,
loader: &'a mut CrateLoader) -> ExtCtxt<'a> {
ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> {
ExtCtxt {
parse_sess: parse_sess,
cfg: cfg,
backtrace: None,
loader: loader,
mod_path: Vec::new(),
ecfg: ecfg,
trace_mac: false
}
}
......
......@@ -22,19 +22,31 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
item: @Item,
push: |@Item|) {
let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
(Path::new_(vec!("std", "hash", "Hash"), None,
vec!(~Literal(Path::new_local("__H"))), true),
LifetimeBounds {
lifetimes: Vec::new(),
bounds: vec!(("__H", vec!(Path::new(vec!("std", "io", "Writer"))))),
},
Path::new_local("__H"))
} else {
(Path::new(vec!("std", "hash", "Hash")),
LifetimeBounds::empty(),
Path::new(vec!("std", "hash", "sip", "SipState")))
};
let hash_trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "hash", "Hash")),
path: path,
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
generics: generics,
methods: vec!(
MethodDef {
name: "hash",
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
args: vec!(Ptr(~Literal(Path::new(vec!("std", "hash", "sip", "SipState"))),
Borrowed(None, MutMutable))),
args: vec!(Ptr(~Literal(args), Borrowed(None, MutMutable))),
ret_ty: nil_ty(),
inline: true,
const_nonmatching: false,
......
......@@ -443,7 +443,7 @@ pub fn expand_view_item(vi: &ast::ViewItem,
}
fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
let MacroCrate { lib, cnum } = fld.cx.loader.load_crate(krate);
let MacroCrate { lib, cnum } = fld.cx.ecfg.loader.load_crate(krate);
let crate_name = match krate.node {
ast::ViewItemExternMod(name, _, _) => name,
......@@ -451,7 +451,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
};
let name = format!("<{} macros>", token::get_ident(crate_name));
let exported_macros = fld.cx.loader.get_exported_macros(cnum);
let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum);
for source in exported_macros.iter() {
let item = parse::parse_item_from_source_str(name.clone(),
(*source).clone(),
......@@ -468,7 +468,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
// Make sure the path contains a / or the linker will search for it.
let path = os::make_absolute(&path);
let registrar = match fld.cx.loader.get_registrar_symbol(cnum) {
let registrar = match fld.cx.ecfg.loader.get_registrar_symbol(cnum) {
Some(registrar) => registrar,
None => return
};
......@@ -823,10 +823,15 @@ fn new_span(&mut self, span: Span) -> Span {
}
}
pub struct ExpansionConfig<'a> {
loader: &'a mut CrateLoader,
deriving_hash_type_parameter: bool,
}
pub fn expand_crate(parse_sess: @parse::ParseSess,
loader: &mut CrateLoader,
cfg: ExpansionConfig,
c: Crate) -> Crate {
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), loader);
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
let mut expander = MacroExpander {
extsbox: syntax_expander_table(),
cx: &mut cx,
......@@ -995,7 +1000,11 @@ fn get_registrar_symbol(&mut self, _: ast::CrateNum) -> Option<~str> {
Vec::new(),sess);
// should fail:
let mut loader = ErrLoader;
expand_crate(sess,&mut loader,crate_ast);
let cfg = ::syntax::ext::expand::ExpansionConfig {
loader: &mut loader,
deriving_hash_type_parameter: false,
};
expand_crate(sess,cfg,crate_ast);
}
// make sure that macros can leave scope for modules
......@@ -1010,7 +1019,11 @@ fn get_registrar_symbol(&mut self, _: ast::CrateNum) -> Option<~str> {
Vec::new(),sess);
// should fail:
let mut loader = ErrLoader;
expand_crate(sess,&mut loader,crate_ast);
let cfg = ::syntax::ext::expand::ExpansionConfig {
loader: &mut loader,
deriving_hash_type_parameter: false,
};
expand_crate(sess,cfg,crate_ast);
}
// macro_escape modules shouldn't cause macros to leave scope
......@@ -1024,7 +1037,11 @@ fn get_registrar_symbol(&mut self, _: ast::CrateNum) -> Option<~str> {
Vec::new(), sess);
// should fail:
let mut loader = ErrLoader;
expand_crate(sess, &mut loader, crate_ast);
let cfg = ::syntax::ext::expand::ExpansionConfig {
loader: &mut loader,
deriving_hash_type_parameter: false,
};
expand_crate(sess, cfg, crate_ast);
}
#[test] fn test_contains_flatten (){
......@@ -1062,7 +1079,11 @@ fn expand_crate_str(crate_str: ~str) -> ast::Crate {
let (crate_ast,ps) = string_to_crate_and_sess(crate_str);
// the cfg argument actually does matter, here...
let mut loader = ErrLoader;
expand_crate(ps,&mut loader,crate_ast)
let cfg = ::syntax::ext::expand::ExpansionConfig {
loader: &mut loader,
deriving_hash_type_parameter: false,
};
expand_crate(ps,cfg,crate_ast)
}
//fn expand_and_resolve(crate_str: @str) -> ast::crate {
......
......@@ -26,7 +26,7 @@
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://static.rust-lang.org/doc/master")];
#[feature(macro_rules, globs, managed_boxes)];
#[feature(macro_rules, globs, managed_boxes, default_type_params)];
#[allow(unknown_features)];// Note: remove it after a snapshot.
#[feature(quote)];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册