Avoid type_store hashtable access for a variety of cases, probably only ty_var matters.
This commit is contained in:
parent
485399a8d5
commit
b258060a94
@ -15,6 +15,20 @@ import front.ast.mutability;
|
||||
import front.creader;
|
||||
import middle.metadata;
|
||||
import util.common;
|
||||
|
||||
import util.common.ty_u8;
|
||||
import util.common.ty_u16;
|
||||
import util.common.ty_u32;
|
||||
import util.common.ty_u64;
|
||||
|
||||
import util.common.ty_i8;
|
||||
import util.common.ty_i16;
|
||||
import util.common.ty_i32;
|
||||
import util.common.ty_i64;
|
||||
|
||||
import util.common.ty_f32;
|
||||
import util.common.ty_f64;
|
||||
|
||||
import util.common.new_def_hash;
|
||||
import util.common.span;
|
||||
import util.typestate_ann.ts_ann;
|
||||
@ -102,13 +116,74 @@ tag type_err {
|
||||
type ty_param_count_and_ty = tup(uint, t);
|
||||
type type_cache = hashmap[ast.def_id,ty_param_count_and_ty];
|
||||
|
||||
type type_store = rec(vec[ty.t] empty_vec_ty,
|
||||
vec[mutable ty.t] empty_vec_mutable_ty,
|
||||
ty.t t_nil,
|
||||
ty.t t_bool,
|
||||
ty.t t_int,
|
||||
ty.t t_float,
|
||||
ty.t t_uint,
|
||||
|
||||
type type_store = hashmap[t,t];
|
||||
ty.t t_i8,
|
||||
ty.t t_i16,
|
||||
ty.t t_i32,
|
||||
ty.t t_i64,
|
||||
|
||||
ty.t t_u8,
|
||||
ty.t t_u16,
|
||||
ty.t t_u32,
|
||||
ty.t t_u64,
|
||||
|
||||
ty.t t_f32,
|
||||
ty.t t_f64,
|
||||
|
||||
ty.t t_char,
|
||||
ty.t t_str,
|
||||
|
||||
ty.t t_native,
|
||||
ty.t t_type,
|
||||
|
||||
mutable vec[ty.t] t_params,
|
||||
mutable vec[ty.t] t_bound_params,
|
||||
mutable vec[ty.t] t_vars,
|
||||
hashmap[t,t] others);
|
||||
|
||||
fn mk_type_store() -> @type_store {
|
||||
auto hasher = hash_ty;
|
||||
auto eqer = eq_ty_full;
|
||||
ret @map.mk_hashmap[t,t](hasher, eqer);
|
||||
|
||||
ret @rec(empty_vec_ty = _vec.empty[ty.t](),
|
||||
empty_vec_mutable_ty = _vec.empty_mut[ty.t](),
|
||||
t_nil = mk_ty_full(ty_nil, none[str]),
|
||||
t_bool = mk_ty_full(ty_bool, none[str]),
|
||||
t_int = mk_ty_full(ty_int, none[str]),
|
||||
t_float = mk_ty_full(ty_float, none[str]),
|
||||
t_uint = mk_ty_full(ty_uint, none[str]),
|
||||
|
||||
t_i8 = mk_ty_full(ty_machine(ty_i8), none[str]),
|
||||
t_i16 = mk_ty_full(ty_machine(ty_i16), none[str]),
|
||||
t_i32 = mk_ty_full(ty_machine(ty_i32), none[str]),
|
||||
t_i64 = mk_ty_full(ty_machine(ty_i64), none[str]),
|
||||
|
||||
t_u8 = mk_ty_full(ty_machine(ty_u8), none[str]),
|
||||
t_u16 = mk_ty_full(ty_machine(ty_u16), none[str]),
|
||||
t_u32 = mk_ty_full(ty_machine(ty_u32), none[str]),
|
||||
t_u64 = mk_ty_full(ty_machine(ty_u64), none[str]),
|
||||
|
||||
t_f32 = mk_ty_full(ty_machine(ty_f32), none[str]),
|
||||
t_f64 = mk_ty_full(ty_machine(ty_f64), none[str]),
|
||||
|
||||
t_char = mk_ty_full(ty_char, none[str]),
|
||||
t_str = mk_ty_full(ty_str, none[str]),
|
||||
|
||||
t_native = mk_ty_full(ty_native, none[str]),
|
||||
t_type = mk_ty_full(ty_type, none[str]),
|
||||
|
||||
mutable t_params = _vec.empty[ty.t](),
|
||||
mutable t_bound_params = _vec.empty[ty.t](),
|
||||
mutable t_vars = _vec.empty[ty.t](),
|
||||
|
||||
others=map.mk_hashmap[t,t](hasher, eqer));
|
||||
}
|
||||
|
||||
// Type constructors
|
||||
@ -119,36 +194,53 @@ fn gen_ty(@type_store tystore, &sty st) -> t {
|
||||
ret gen_ty_full(tystore, st, none[str]);
|
||||
}
|
||||
|
||||
fn gen_ty_full(@type_store tystore, &sty st, option.t[str] cname) -> t {
|
||||
fn mk_ty_full(&sty st, option.t[str] cname) -> t {
|
||||
auto h = hash_type_info(st, cname);
|
||||
auto magic = mk_magic(st);
|
||||
auto new_type = @rec(struct=st, cname=cname, magic=magic, hash=h);
|
||||
ret @rec(struct=st, cname=cname, magic=magic, hash=h);
|
||||
}
|
||||
|
||||
fn gen_ty_full(@type_store tystore, &sty st, option.t[str] cname) -> t {
|
||||
auto new_type = mk_ty_full(st, cname);
|
||||
// Is it interned?
|
||||
alt (tystore.find(new_type)) {
|
||||
alt (tystore.others.find(new_type)) {
|
||||
case (some[t](?typ)) {
|
||||
ret typ;
|
||||
}
|
||||
case (none[t]) {
|
||||
// Nope. Insert it and return.
|
||||
tystore.insert(new_type, new_type);
|
||||
tystore.others.insert(new_type, new_type);
|
||||
ret new_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_nil(@type_store ts) -> t { ret gen_ty(ts, ty_nil); }
|
||||
fn mk_bool(@type_store ts) -> t { ret gen_ty(ts, ty_bool); }
|
||||
fn mk_int(@type_store ts) -> t { ret gen_ty(ts, ty_int); }
|
||||
fn mk_float(@type_store ts) -> t { ret gen_ty(ts, ty_float); }
|
||||
fn mk_uint(@type_store ts) -> t { ret gen_ty(ts, ty_uint); }
|
||||
fn mk_nil(@type_store ts) -> t { ret ts.t_nil; }
|
||||
fn mk_bool(@type_store ts) -> t { ret ts.t_bool; }
|
||||
fn mk_int(@type_store ts) -> t { ret ts.t_int; }
|
||||
fn mk_float(@type_store ts) -> t { ret ts.t_float; }
|
||||
fn mk_uint(@type_store ts) -> t { ret ts.t_uint; }
|
||||
|
||||
fn mk_mach(@type_store ts, util.common.ty_mach tm) -> t {
|
||||
ret gen_ty(ts, ty_machine(tm));
|
||||
alt (tm) {
|
||||
case (ty_u8) { ret ts.t_u8; }
|
||||
case (ty_u16) { ret ts.t_u16; }
|
||||
case (ty_u32) { ret ts.t_u32; }
|
||||
case (ty_u64) { ret ts.t_u64; }
|
||||
|
||||
case (ty_i8) { ret ts.t_i8; }
|
||||
case (ty_i16) { ret ts.t_i16; }
|
||||
case (ty_i32) { ret ts.t_i32; }
|
||||
case (ty_i64) { ret ts.t_i64; }
|
||||
|
||||
case (ty_f32) { ret ts.t_f32; }
|
||||
case (ty_f64) { ret ts.t_f64; }
|
||||
}
|
||||
fail;
|
||||
}
|
||||
|
||||
fn mk_char(@type_store ts) -> t { ret gen_ty(ts, ty_char); }
|
||||
fn mk_str(@type_store ts) -> t { ret gen_ty(ts, ty_str); }
|
||||
fn mk_char(@type_store ts) -> t { ret ts.t_char; }
|
||||
fn mk_str(@type_store ts) -> t { ret ts.t_str; }
|
||||
|
||||
fn mk_tag(@type_store ts, ast.def_id did, vec[t] tys) -> t {
|
||||
ret gen_ty(ts, ty_tag(did, tys));
|
||||
@ -197,22 +289,39 @@ fn mk_obj(@type_store ts, vec[method] meths) -> t {
|
||||
ret gen_ty(ts, ty_obj(meths));
|
||||
}
|
||||
|
||||
fn mk_var(@type_store ts, int v) -> t { ret gen_ty(ts, ty_var(v)); }
|
||||
fn mk_var(@type_store ts, int v) -> t {
|
||||
let int i = _vec.len[t](ts.t_vars) as int;
|
||||
while (i <= v) {
|
||||
ts.t_vars += vec(mk_ty_full(ty_var(i), none[str]));
|
||||
i += 1;
|
||||
}
|
||||
ret ts.t_vars.(v);
|
||||
}
|
||||
|
||||
fn mk_local(@type_store ts, ast.def_id did) -> t {
|
||||
ret gen_ty(ts, ty_local(did));
|
||||
}
|
||||
|
||||
fn mk_param(@type_store ts, uint n) -> t {
|
||||
ret gen_ty(ts, ty_param(n));
|
||||
let uint i = _vec.len[t](ts.t_params);
|
||||
while (i <= n) {
|
||||
ts.t_params += vec(mk_ty_full(ty_param(i), none[str]));
|
||||
i += 1u;
|
||||
}
|
||||
ret ts.t_params.(n);
|
||||
}
|
||||
|
||||
fn mk_bound_param(@type_store ts, uint n) -> t {
|
||||
ret gen_ty(ts, ty_bound_param(n));
|
||||
let uint i = _vec.len[t](ts.t_bound_params);
|
||||
while (i <= n) {
|
||||
ts.t_bound_params += vec(mk_ty_full(ty_bound_param(i), none[str]));
|
||||
i += 1u;
|
||||
}
|
||||
ret ts.t_bound_params.(n);
|
||||
}
|
||||
|
||||
fn mk_type(@type_store ts) -> t { ret gen_ty(ts, ty_type); }
|
||||
fn mk_native(@type_store ts) -> t { ret gen_ty(ts, ty_native); }
|
||||
fn mk_type(@type_store ts) -> t { ret ts.t_type; }
|
||||
fn mk_native(@type_store ts) -> t { ret ts.t_native; }
|
||||
|
||||
|
||||
// Returns the one-level-deep type structure of the given type.
|
||||
|
@ -106,7 +106,7 @@ fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
||||
-> ty_param_count_and_ty {
|
||||
alt (defn) {
|
||||
case (ast.def_arg(?id)) {
|
||||
check (fcx.locals.contains_key(id));
|
||||
// check (fcx.locals.contains_key(id));
|
||||
ret tup(0u, fcx.locals.get(id));
|
||||
}
|
||||
case (ast.def_local(?id)) {
|
||||
@ -118,7 +118,7 @@ fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
||||
ret tup(0u, t);
|
||||
}
|
||||
case (ast.def_obj_field(?id)) {
|
||||
check (fcx.locals.contains_key(id));
|
||||
// check (fcx.locals.contains_key(id));
|
||||
ret tup(0u, fcx.locals.get(id));
|
||||
}
|
||||
case (ast.def_fn(?id)) {
|
||||
@ -138,7 +138,7 @@ fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
||||
fcx.ccx.type_cache, vid);
|
||||
}
|
||||
case (ast.def_binding(?id)) {
|
||||
check (fcx.locals.contains_key(id));
|
||||
// check (fcx.locals.contains_key(id));
|
||||
ret tup(0u, fcx.locals.get(id));
|
||||
}
|
||||
case (ast.def_obj(?id)) {
|
||||
@ -406,7 +406,7 @@ mod Collect {
|
||||
ret creader.get_type(cx.sess, cx.tystore, id);
|
||||
}
|
||||
|
||||
check (cx.id_to_ty_item.contains_key(id));
|
||||
// check (cx.id_to_ty_item.contains_key(id));
|
||||
|
||||
auto it = cx.id_to_ty_item.get(id);
|
||||
auto tpt;
|
||||
@ -493,15 +493,17 @@ mod Collect {
|
||||
ret cx.type_cache.get(odid.ty);
|
||||
}
|
||||
|
||||
case (ast.item_ty(?ident, ?ty, ?tps, ?def_id, _)) {
|
||||
if (cx.type_cache.contains_key(def_id)) {
|
||||
// Avoid repeating work.
|
||||
ret cx.type_cache.get(def_id);
|
||||
case (ast.item_ty(?ident, ?t, ?tps, ?def_id, _)) {
|
||||
alt (cx.type_cache.find(def_id)) {
|
||||
case (some[ty.ty_param_count_and_ty](?tpt)) {
|
||||
ret tpt;
|
||||
}
|
||||
case (none[ty.ty_param_count_and_ty]) {}
|
||||
}
|
||||
|
||||
// Tell ast_ty_to_ty() that we want to perform a recursive
|
||||
// call to resolve any named types.
|
||||
auto typ = convert(ty);
|
||||
auto typ = convert(t);
|
||||
auto ty_param_count = _vec.len[ast.ty_param](tps);
|
||||
auto tpt = tup(ty_param_count, typ);
|
||||
cx.type_cache.insert(def_id, tpt);
|
||||
@ -543,9 +545,11 @@ mod Collect {
|
||||
def_id);
|
||||
}
|
||||
case (ast.native_item_ty(_, ?def_id)) {
|
||||
if (cx.type_cache.contains_key(def_id)) {
|
||||
// Avoid repeating work.
|
||||
ret cx.type_cache.get(def_id);
|
||||
alt (cx.type_cache.find(def_id)) {
|
||||
case (some[ty.ty_param_count_and_ty](?tpt)) {
|
||||
ret tpt;
|
||||
}
|
||||
case (none[ty.ty_param_count_and_ty]) {}
|
||||
}
|
||||
|
||||
auto t = ty.mk_native(cx.tystore);
|
||||
@ -661,7 +665,7 @@ mod Collect {
|
||||
fn fold_item_const(&@env e, &span sp, ast.ident i,
|
||||
@ast.ty t, @ast.expr ex,
|
||||
ast.def_id id, ast.ann a) -> @ast.item {
|
||||
check (e.cx.type_cache.contains_key(id));
|
||||
// check (e.cx.type_cache.contains_key(id));
|
||||
auto typ = e.cx.type_cache.get(id)._1;
|
||||
auto item = ast.item_const(i, t, ex, id, triv_ann(typ));
|
||||
ret @fold.respan[ast.item_](sp, item);
|
||||
@ -670,7 +674,7 @@ mod Collect {
|
||||
fn fold_item_fn(&@env e, &span sp, ast.ident i,
|
||||
&ast._fn f, vec[ast.ty_param] ty_params,
|
||||
ast.def_id id, ast.ann a) -> @ast.item {
|
||||
check (e.cx.type_cache.contains_key(id));
|
||||
// check (e.cx.type_cache.contains_key(id));
|
||||
auto typ = e.cx.type_cache.get(id)._1;
|
||||
auto item = ast.item_fn(i, f, ty_params, id, triv_ann(typ));
|
||||
ret @fold.respan[ast.item_](sp, item);
|
||||
@ -679,7 +683,7 @@ mod Collect {
|
||||
fn fold_native_item_fn(&@env e, &span sp, ast.ident i, option.t[str] ln,
|
||||
&ast.fn_decl d, vec[ast.ty_param] ty_params,
|
||||
ast.def_id id, ast.ann a) -> @ast.native_item {
|
||||
check (e.cx.type_cache.contains_key(id));
|
||||
// check (e.cx.type_cache.contains_key(id));
|
||||
auto typ = e.cx.type_cache.get(id)._1;
|
||||
auto item = ast.native_item_fn(i, ln, d, ty_params, id,
|
||||
triv_ann(typ));
|
||||
@ -710,7 +714,7 @@ mod Collect {
|
||||
fn fold_item_obj(&@env e, &span sp, ast.ident i,
|
||||
&ast._obj ob, vec[ast.ty_param] ty_params,
|
||||
ast.obj_def_ids odid, ast.ann a) -> @ast.item {
|
||||
check (e.cx.type_cache.contains_key(odid.ctor));
|
||||
// check (e.cx.type_cache.contains_key(odid.ctor));
|
||||
auto t = e.cx.type_cache.get(odid.ctor)._1;
|
||||
let vec[method] meth_tys = get_ctor_obj_methods(e, t);
|
||||
let vec[@ast.method] methods = vec();
|
||||
@ -766,7 +770,7 @@ mod Collect {
|
||||
fn fold_item_ty(&@env e, &span sp, ast.ident i,
|
||||
@ast.ty t, vec[ast.ty_param] ty_params,
|
||||
ast.def_id id, ast.ann a) -> @ast.item {
|
||||
check (e.cx.type_cache.contains_key(id));
|
||||
// check (e.cx.type_cache.contains_key(id));
|
||||
auto typ = e.cx.type_cache.get(id)._1;
|
||||
auto item = ast.item_ty(i, t, ty_params, id, triv_ann(typ));
|
||||
ret @fold.respan[ast.item_](sp, item);
|
||||
@ -841,12 +845,15 @@ mod Unify {
|
||||
fn with_params(@fn_ctxt fcx, ty.t expected, ty.t actual,
|
||||
vec[mutable ty.t] param_substs) -> ty.Unify.result {
|
||||
auto cache_key = tup(expected, actual, param_substs);
|
||||
if (fcx.ccx.unify_cache.contains_key(cache_key)) {
|
||||
alt (fcx.ccx.unify_cache.find(cache_key)) {
|
||||
case (some[ty.Unify.result](?r)) {
|
||||
fcx.ccx.cache_hits += 1u;
|
||||
ret fcx.ccx.unify_cache.get(cache_key);
|
||||
ret r;
|
||||
}
|
||||
|
||||
case (none[ty.Unify.result]) {
|
||||
fcx.ccx.cache_misses += 1u;
|
||||
}
|
||||
}
|
||||
|
||||
obj unify_handler(@fn_ctxt fcx, vec[mutable ty.t] param_substs) {
|
||||
fn resolve_local(ast.def_id id) -> option.t[ty.t] {
|
||||
@ -1502,11 +1509,18 @@ fn writeback_local(&option.t[@fn_ctxt] env, &span sp, @ast.local local)
|
||||
-> @ast.decl {
|
||||
auto fcx = option.get[@fn_ctxt](env);
|
||||
|
||||
if (!fcx.locals.contains_key(local.id)) {
|
||||
auto local_ty;
|
||||
alt (fcx.locals.find(local.id)) {
|
||||
case (none[ty.t]) {
|
||||
fcx.ccx.sess.span_err(sp, "unable to determine type of local: "
|
||||
+ local.ident);
|
||||
fail;
|
||||
}
|
||||
auto local_ty = fcx.locals.get(local.id);
|
||||
case (some[ty.t](?lt)) {
|
||||
local_ty = lt;
|
||||
}
|
||||
}
|
||||
|
||||
auto local_wb = @rec(ann=triv_ann(local_ty)
|
||||
with *local
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user