From 17459d0bd355e550a06ee044de077bcd552e9cc5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 23 Mar 2013 18:55:58 -0400 Subject: [PATCH] rustc: Purge of HashMap, fixing segfaulting cases Various FIXME comments added around to denote copies which when removed cause the compiler to segfault at some point before stage2. None of these copies should even be necessary. --- src/librustc/metadata/tyencode.rs | 2 +- src/librustc/middle/astencode.rs | 6 ++- src/librustc/middle/const_eval.rs | 3 +- src/librustc/middle/kind.rs | 14 ++++--- src/librustc/middle/trans/base.rs | 19 ++++++---- src/librustc/middle/trans/callee.rs | 14 +++++-- src/librustc/middle/trans/common.rs | 7 ++-- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/trans/glue.rs | 2 +- src/librustc/middle/trans/reachable.rs | 4 +- src/librustc/middle/trans/reflect.rs | 2 +- src/librustc/middle/trans/type_of.rs | 12 ++++-- src/librustc/middle/trans/type_use.rs | 9 ++++- src/librustc/middle/ty.rs | 37 +++++++++---------- src/librustc/middle/typeck/check/mod.rs | 4 +- src/librustc/middle/typeck/check/writeback.rs | 2 +- src/librustc/middle/typeck/mod.rs | 5 +-- 17 files changed, 83 insertions(+), 61 deletions(-) diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 021d472fa0e..6734abb7e80 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -61,7 +61,7 @@ pub fn enc_ty(w: @io::Writer, cx: @ctxt, t: ty::t) { match cx.abbrevs { ac_no_abbrevs => { let result_str = match cx.tcx.short_names_cache.find(&t) { - Some(s) => /*bad*/copy *s, + Some(&s) => /*bad*/copy *s, None => { let s = do io::with_str_writer |wr| { enc_sty(wr, cx, /*bad*/copy ty::get(t).sty); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index e1863a9f400..1e1dde33037 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -856,7 +856,9 @@ fn encode_side_tables_for_id(ecx: @e::EncodeContext, do ebml_w.tag(c::tag_table_node_type_subst) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - ebml_w.emit_tys(ecx, /*bad*/copy *tys) + // FIXME(#5562): removing this copy causes a segfault + // before stage2 + ebml_w.emit_tys(ecx, /*bad*/copy **tys) } } } @@ -922,7 +924,7 @@ fn encode_side_tables_for_id(ecx: @e::EncodeContext, } } - for maps.method_map.find(&id).each |mme| { + for maps.method_map.find(&id).each |&mme| { do ebml_w.tag(c::tag_table_method_map) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 8cf6e931c92..a6c954b3851 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -17,7 +17,6 @@ use middle; use core::float; use core::vec; -use std::oldmap::HashMap; use syntax::{ast, ast_map, ast_util, visit}; use syntax::ast::*; @@ -194,7 +193,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, mutbl_map: @mut LinearSet::new(), root_map: @mut LinearMap::new(), last_use_map: @mut LinearMap::new(), - method_map: HashMap(), + method_map: @mut LinearMap::new(), vtable_map: @mut LinearMap::new(), write_guard_map: @mut LinearSet::new(), moves_map: @mut LinearSet::new(), diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index ab3dc75c79f..ca301182e6f 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -274,6 +274,8 @@ pub fn check_expr(e: @expr, cx: Context, v: visit::vt) { _ => e.id }; for cx.tcx.node_type_substs.find(&type_parameter_id).each |ts| { + // FIXME(#5562): removing this copy causes a segfault before stage2 + let ts = /*bad*/ copy **ts; let bounds = match e.node { expr_path(_) => { let did = ast_util::def_id_of_def(*cx.tcx.def_map.get(&e.id)); @@ -289,15 +291,15 @@ pub fn check_expr(e: @expr, cx: Context, v: visit::vt) { ~"non path/method call expr has type substs??") } }; - if vec::len(*ts) != vec::len(*bounds) { + if ts.len() != bounds.len() { // Fail earlier to make debugging easier fail!(fmt!("internal error: in kind::check_expr, length \ mismatch between actual and declared bounds: actual = \ %s (%u tys), declared = %? (%u tys)", - tys_to_str(cx.tcx, *ts), ts.len(), - *bounds, (*bounds).len())); + tys_to_str(cx.tcx, ts), ts.len(), + *bounds, bounds.len())); } - for vec::each2(*ts, *bounds) |ty, bound| { + for vec::each2(ts, *bounds) |ty, bound| { check_bounds(cx, type_parameter_id, e.span, *ty, *bound) } } @@ -335,9 +337,11 @@ fn check_ty(aty: @Ty, cx: Context, v: visit::vt) { match aty.node { ty_path(_, id) => { for cx.tcx.node_type_substs.find(&id).each |ts| { + // FIXME(#5562): removing this copy causes a segfault before stage2 + let ts = /*bad*/ copy **ts; let did = ast_util::def_id_of_def(*cx.tcx.def_map.get(&id)); let bounds = ty::lookup_item_type(cx.tcx, did).bounds; - for vec::each2(*ts, *bounds) |ty, bound| { + for vec::each2(ts, *bounds) |ty, bound| { check_bounds(cx, aty.id, aty.span, *ty, *bound) } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a4f0c7c73cd..680e9c7053d 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -72,8 +72,7 @@ use core::int; use core::io; use core::libc::{c_uint, c_ulonglong}; use core::uint; -use std::oldmap::HashMap; -use std::{oldmap, time, list}; +use std::{time, list}; use syntax::ast::ident; use syntax::ast_map::{path, path_elt_to_str, path_mod, path_name}; use syntax::ast_util::{def_id_of_def, local_def, path_to_ident}; @@ -170,7 +169,10 @@ pub fn get_extern_fn(externs: ExternMap, name: @str, cc: lib::llvm::CallConv, ty: TypeRef) -> ValueRef { - if externs.contains_key(&name) { return externs.get(&name); } + match externs.find(&name) { + Some(n) => return copy *n, + None => () + } let f = decl_fn(llmod, name, cc, ty); externs.insert(name, f); return f; @@ -178,8 +180,11 @@ pub fn get_extern_fn(externs: ExternMap, pub fn get_extern_const(externs: ExternMap, llmod: ModuleRef, name: @str, ty: TypeRef) -> ValueRef { + match externs.find(&name) { + Some(n) => return copy *n, + None => () + } unsafe { - if externs.contains_key(&name) { return externs.get(&name); } let c = str::as_c_str(name, |buf| { llvm::LLVMAddGlobal(llmod, ty, buf) }); @@ -3061,7 +3066,7 @@ pub fn trans_crate(sess: session::Session, llmod: llmod, td: td, tn: tn, - externs: HashMap(), + externs: @mut LinearMap::new(), intrinsics: intrinsics, item_vals: @mut LinearMap::new(), exp_map2: emap2, @@ -3082,8 +3087,8 @@ pub fn trans_crate(sess: session::Session, const_globals: @mut LinearMap::new(), const_values: @mut LinearMap::new(), module_data: @mut LinearMap::new(), - lltypes: ty::new_ty_hash(), - llsizingtypes: ty::new_ty_hash(), + lltypes: @mut LinearMap::new(), + llsizingtypes: @mut LinearMap::new(), adt_reprs: @mut LinearMap::new(), names: new_namegen(sess.parse_sess.interner), next_addrspace: new_addrspace_gen(), diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index e2a5b5f5009..dd882087d38 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -82,9 +82,12 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee { } ast::expr_field(base, _, _) => { match bcx.ccx().maps.method_map.find(&expr.id) { - Some(ref origin) => { // An impl method + Some(origin) => { // An impl method + // FIXME(#5562): removing this copy causes a segfault + // before stage2 + let origin = /*bad*/ copy *origin; return meth::trans_method_callee(bcx, expr.id, - base, (*origin)); + base, origin); } None => {} // not a method, just a field } @@ -343,11 +346,14 @@ pub fn trans_method_call(in_cx: block, expr_ty(in_cx, call_ex), |cx| { match cx.ccx().maps.method_map.find(&call_ex.id) { - Some(ref origin) => { + Some(origin) => { + // FIXME(#5562): removing this copy causes a segfault + // before stage2 + let origin = /*bad*/ copy *origin; meth::trans_method_callee(cx, call_ex.callee_id, rcvr, - (*origin)) + origin) } None => { cx.tcx().sess.span_bug(call_ex.span, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 437562e3a13..5805f7fbe3a 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -52,7 +52,6 @@ use core::str; use core::to_bytes; use core::vec::raw::to_ptr; use core::vec; -use std::oldmap::{HashMap, Set}; use syntax::ast::ident; use syntax::ast_map::{path, path_elt}; use syntax::codemap::span; @@ -156,7 +155,7 @@ pub fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res { } } -pub type ExternMap = HashMap<@str, ValueRef>; +pub type ExternMap = @mut LinearMap<@str, ValueRef>; // Crate context. Every crate we compile has one of these. pub struct CrateContext { @@ -203,8 +202,8 @@ pub struct CrateContext { // Cache of emitted const values const_values: @mut LinearMap, module_data: @mut LinearMap<~str, ValueRef>, - lltypes: HashMap, - llsizingtypes: HashMap, + lltypes: @mut LinearMap, + llsizingtypes: @mut LinearMap, adt_reprs: @mut LinearMap, names: namegen, next_addrspace: addrspace_gen, diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 2fad2bd9b60..33576a682a7 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1647,7 +1647,7 @@ fn trans_overloaded_op(bcx: block, dest: Dest, +autoref_arg: AutorefArg) -> block { - let origin = bcx.ccx().maps.method_map.get(&expr.id); + let origin = *bcx.ccx().maps.method_map.get(&expr.id); let fty = node_id_type(bcx, expr.callee_id); return callee::trans_call_inner( bcx, expr.info(), fty, diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index bf5a699ed82..1639c6b414d 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -402,7 +402,7 @@ pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) { let mut bcx = bcx; let ty_visitor_name = special_idents::ty_visitor; fail_unless!(bcx.ccx().tcx.intrinsic_defs.contains_key(&ty_visitor_name)); - let (trait_id, ty) = bcx.ccx().tcx.intrinsic_defs.get(&ty_visitor_name); + let (trait_id, ty) = *bcx.ccx().tcx.intrinsic_defs.get(&ty_visitor_name); let v = PointerCast(bcx, v, T_ptr(type_of::type_of(bcx.ccx(), ty))); bcx = reflect::emit_calls_to_trait_visit_ty(bcx, t, v, trait_id); build_return(bcx); diff --git a/src/librustc/middle/trans/reachable.rs b/src/librustc/middle/trans/reachable.rs index c025d970db7..026a27dce2c 100644 --- a/src/librustc/middle/trans/reachable.rs +++ b/src/librustc/middle/trans/reachable.rs @@ -193,7 +193,7 @@ fn traverse_inline_body(cx: ctx, body: &blk) { } expr_field(_, _, _) => { match cx.method_map.find(&e.id) { - Some(typeck::method_map_entry { + Some(&typeck::method_map_entry { origin: typeck::method_static(did), _ }) => { @@ -204,7 +204,7 @@ fn traverse_inline_body(cx: ctx, body: &blk) { } expr_method_call(*) => { match cx.method_map.find(&e.id) { - Some(typeck::method_map_entry { + Some(&typeck::method_map_entry { origin: typeck::method_static(did), _ }) => { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 41e63cc878e..b8145e65326 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -337,7 +337,7 @@ pub fn emit_calls_to_trait_visit_ty(bcx: block, use syntax::parse::token::special_idents::tydesc; let final = sub_block(bcx, ~"final"); fail_unless!(bcx.ccx().tcx.intrinsic_defs.contains_key(&tydesc)); - let (_, tydesc_ty) = bcx.ccx().tcx.intrinsic_defs.get(&tydesc); + let (_, tydesc_ty) = *bcx.ccx().tcx.intrinsic_defs.get(&tydesc); let tydesc_ty = type_of(bcx.ccx(), tydesc_ty); let mut r = Reflector { visitor_val: visitor_val, diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index ab8d03014d6..8e4719d2ccc 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -101,8 +101,10 @@ pub fn type_of_non_gc_box(cx: @CrateContext, t: ty::t) -> TypeRef { // behavior. pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef { - if cx.llsizingtypes.contains_key(&t) { - return cx.llsizingtypes.get(&t); + match cx.llsizingtypes.find(&t) { + // FIXME(#5562): removing this copy causes a segfault in stage1 core + Some(t) => return /*bad*/ copy *t, + None => () } let llsizingty = match ty::get(t).sty { @@ -161,7 +163,11 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { debug!("type_of %?: %?", t, ty::get(t)); // Check the cache. - if cx.lltypes.contains_key(&t) { return cx.lltypes.get(&t); } + match cx.lltypes.find(&t) { + // FIXME(#5562): removing this copy causes a segfault in stage1 core + Some(t) => return /*bad*/ copy *t, + None => () + } // Replace any typedef'd types with their equivalent non-typedef // type. This ensures that all LLVM nominal types that contain diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index ba05d5bca21..62cde5999e8 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -250,8 +250,11 @@ pub fn mark_for_method_call(cx: Context, e_id: node_id, callee_id: node_id) { match mth.origin { typeck::method_static(did) => { for cx.ccx.tcx.node_type_substs.find(&callee_id).each |ts| { + // FIXME(#5562): removing this copy causes a segfault + // before stage2 + let ts = /*bad*/ copy **ts; let type_uses = type_uses_for(cx.ccx, did, ts.len()); - for vec::each2(type_uses, *ts) |uses, subst| { + for vec::each2(type_uses, ts) |uses, subst| { type_needs(cx, *uses, *subst) } } @@ -296,9 +299,11 @@ pub fn mark_for_expr(cx: Context, e: @expr) { } expr_path(_) => { for cx.ccx.tcx.node_type_substs.find(&e.id).each |ts| { + // FIXME(#5562): removing this copy causes a segfault before stage2 + let ts = copy **ts; let id = ast_util::def_id_of_def(*cx.ccx.tcx.def_map.get(&e.id)); let uses_for_ts = type_uses_for(cx.ccx, id, ts.len()); - for vec::each2(uses_for_ts, *ts) |uses, subst| { + for vec::each2(uses_for_ts, ts) |uses, subst| { type_needs(cx, *uses, *subst) } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a6b6c71f387..74146e56da2 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -38,8 +38,6 @@ use core::to_bytes; use core::uint; use core::vec; use core::hashmap::linear::{LinearMap, LinearSet}; -use std::oldmap::HashMap; -use std::oldmap; use std::smallintmap::SmallIntMap; use syntax::ast::*; use syntax::ast_util::{is_local, local_def}; @@ -265,16 +263,16 @@ 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: HashMap, + node_type_substs: @mut LinearMap, items: ast_map::map, - intrinsic_defs: HashMap, + intrinsic_defs: @mut LinearMap, freevars: freevars::freevar_map, tcache: type_cache, rcache: creader_cache, ccache: constness_cache, - short_names_cache: HashMap, - needs_unwind_cleanup_cache: HashMap, + short_names_cache: @mut LinearMap, + needs_unwind_cleanup_cache: @mut LinearMap, tc_cache: @mut LinearMap, ast_ty_to_ty_cache: @mut LinearMap, enum_var_cache: @mut LinearMap, @@ -282,7 +280,7 @@ struct ctxt_ { ty_param_bounds: @mut LinearMap, inferred_modes: @mut LinearMap, adjustments: @mut LinearMap, - normalized_cache: HashMap, + normalized_cache: @mut LinearMap, lang_items: middle::lang_items::LanguageItems, // A mapping from an implementation ID to the method info and trait // method ID of the provided (a.k.a. default) methods in the traits that @@ -788,8 +786,8 @@ fn mk_rcache() -> creader_cache { return @mut LinearMap::new(); } -pub fn new_ty_hash() -> oldmap::HashMap { - oldmap::HashMap() +pub fn new_ty_hash() -> @mut LinearMap { + @mut LinearMap::new() } pub fn mk_ctxt(s: session::Session, @@ -826,9 +824,9 @@ pub fn mk_ctxt(s: session::Session, region_map: region_map, region_paramd_items: region_paramd_items, node_types: @mut SmallIntMap::new(), - node_type_substs: oldmap::HashMap(), + node_type_substs: @mut LinearMap::new(), items: amap, - intrinsic_defs: oldmap::HashMap(), + intrinsic_defs: @mut LinearMap::new(), freevars: freevars, tcache: @mut LinearMap::new(), rcache: mk_rcache(), @@ -1621,25 +1619,24 @@ pub fn type_needs_drop(cx: ctxt, ty: t) -> bool { // cleanups. pub fn type_needs_unwind_cleanup(cx: ctxt, ty: t) -> bool { match cx.needs_unwind_cleanup_cache.find(&ty) { - Some(result) => return result, + Some(&result) => return result, None => () } - let tycache = new_ty_hash(); + let mut tycache = LinearSet::new(); let needs_unwind_cleanup = - type_needs_unwind_cleanup_(cx, ty, tycache, false); + type_needs_unwind_cleanup_(cx, ty, &mut tycache, false); cx.needs_unwind_cleanup_cache.insert(ty, needs_unwind_cleanup); return needs_unwind_cleanup; } fn type_needs_unwind_cleanup_(cx: ctxt, ty: t, - tycache: oldmap::HashMap, + tycache: &mut LinearSet, encountered_box: bool) -> bool { // Prevent infinite recursion - match tycache.find(&ty) { - Some(_) => return false, - None => { tycache.insert(ty, ()); } + if !tycache.insert(ty) { + return false; } let mut encountered_box = encountered_box; @@ -2724,7 +2721,7 @@ pub fn node_id_to_type(cx: ctxt, id: ast::node_id) -> t { pub fn node_id_to_type_params(cx: ctxt, id: ast::node_id) -> ~[t] { match cx.node_type_substs.find(&id) { None => return ~[], - Some(ts) => return ts + Some(ts) => return /*bad*/ copy *ts } } @@ -4164,7 +4161,7 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t { } match cx.normalized_cache.find(&t) { - Some(t) => return t, + Some(&t) => return t, None => () } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index f534519d147..3af23bb20ac 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3453,8 +3453,8 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { let ty_visitor_name = tcx.sess.ident_of(~"TyVisitor"); fail_unless!(tcx.intrinsic_defs.contains_key(&tydesc_name)); fail_unless!(ccx.tcx.intrinsic_defs.contains_key(&ty_visitor_name)); - let (_, tydesc_ty) = tcx.intrinsic_defs.get(&tydesc_name); - let (_, visitor_trait) = tcx.intrinsic_defs.get(&ty_visitor_name); + let (_, tydesc_ty) = *tcx.intrinsic_defs.get(&tydesc_name); + let (_, visitor_trait) = *tcx.intrinsic_defs.get(&ty_visitor_name); let visitor_trait = match ty::get(visitor_trait).sty { ty::ty_trait(trait_def_id, ref trait_substs, _) => { diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index 1d6c74fd899..9ba98a4d27f 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -66,7 +66,7 @@ fn resolve_method_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) { // Resolve any method map entry match fcx.inh.method_map.find(&id) { None => {} - Some(ref mme) => { + Some(mme) => { for resolve_type_vars_in_type(fcx, sp, mme.self_arg.ty).each |t| { let method_map = fcx.ccx.method_map; let new_entry = method_map_entry { diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 817aafc2b19..b783a099e16 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -60,7 +60,6 @@ use core::result; use core::vec; use std::list::{List, Nil, Cons}; use std::list; -use std::oldmap::HashMap; use syntax::codemap::{span, spanned, respan}; use syntax::print::pprust::*; use syntax::{ast, ast_util, ast_map}; @@ -130,7 +129,7 @@ pub struct method_map_entry { // maps from an expression id that corresponds to a method call to the details // of the method to be invoked -pub type method_map = HashMap; +pub type method_map = @mut LinearMap; // Resolutions for bounds of all parameters, left to right, for a given path. pub type vtable_res = @~[vtable_origin]; @@ -343,7 +342,7 @@ pub fn check_crate(tcx: ty::ctxt, let time_passes = tcx.sess.time_passes(); let ccx = @mut CrateCtxt { trait_map: trait_map, - method_map: HashMap(), + method_map: @mut LinearMap::new(), vtable_map: @mut LinearMap::new(), coherence_info: @coherence::CoherenceInfo(), tcx: tcx