Avoid type_store hashtable access for a variety of cases, probably only ty_var matters.

This commit is contained in:
Graydon Hoare 2011-04-25 09:49:08 -07:00
parent 485399a8d5
commit b258060a94
2 changed files with 168 additions and 45 deletions

View File

@ -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.

View File

@ -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,13 +845,16 @@ 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)) {
fcx.ccx.cache_hits += 1u;
ret fcx.ccx.unify_cache.get(cache_key);
alt (fcx.ccx.unify_cache.find(cache_key)) {
case (some[ty.Unify.result](?r)) {
fcx.ccx.cache_hits += 1u;
ret r;
}
case (none[ty.Unify.result]) {
fcx.ccx.cache_misses += 1u;
}
}
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] {
alt (fcx.locals.find(id)) {
@ -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)) {
fcx.ccx.sess.span_err(sp, "unable to determine type of local: "
+ local.ident);
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;
}
case (some[ty.t](?lt)) {
local_ty = lt;
}
}
auto local_ty = fcx.locals.get(local.id);
auto local_wb = @rec(ann=triv_ann(local_ty)
with *local
);