@@ -48,12 +48,18 @@ tag any_item {
48
48
49
49
type ty_item_table = hashmap [ ast. def_id , any_item] ;
50
50
51
+ type unify_cache_entry = tup ( @ty. t , @ty. t , vec[ mutable @ty. t] ) ;
52
+ type unify_cache = hashmap [ unify_cache_entry, ty. unify_result ] ;
53
+
51
54
type crate_ctxt = rec ( session . session sess,
52
55
ty. type_cache type_cache ,
53
56
@ty_item_table item_items ,
54
57
vec[ ast. obj_field] obj_fields ,
55
58
option. t[ ast. def_id] this_obj ,
56
- mutable int next_var_id ) ;
59
+ mutable int next_var_id ,
60
+ unify_cache unify_cache,
61
+ mutable uint cache_hits ,
62
+ mutable uint cache_misses ) ;
57
63
58
64
type fn_ctxt = rec ( @ty. t ret_ty ,
59
65
@ty_table locals ,
@@ -842,6 +848,14 @@ mod Unify {
842
848
843
849
fn with_params ( @fn_ctxt fcx , @ty. t expected , @ty. t actual ,
844
850
vec[ mutable @ty. t] param_substs ) -> ty. unify_result {
851
+ auto cache_key = tup ( expected, actual, param_substs) ;
852
+ if ( fcx. ccx . unify_cache . contains_key ( cache_key) ) {
853
+ fcx. ccx . cache_hits += 1 u;
854
+ ret fcx. ccx . unify_cache . get ( cache_key) ;
855
+ }
856
+
857
+ fcx. ccx . cache_misses += 1 u;
858
+
845
859
obj unify_handler ( @fn_ctxt fcx, vec[ mutable @ty. t ] param_substs) {
846
860
fn resolve_local ( ast. def_id id ) -> option . t[ @ty. t] {
847
861
alt ( fcx. locals . find ( id) ) {
@@ -898,7 +912,9 @@ mod Unify {
898
912
899
913
900
914
auto handler = unify_handler ( fcx, param_substs) ;
901
- ret ty. unify ( expected, actual, handler) ;
915
+ auto result = ty. unify ( expected, actual, handler) ;
916
+ fcx. ccx . unify_cache . insert ( cache_key, result) ;
917
+ ret result;
902
918
}
903
919
}
904
920
@@ -2699,19 +2715,59 @@ fn update_obj_fields(&@crate_ctxt ccx, @ast.item i) -> @crate_ctxt {
2699
2715
}
2700
2716
2701
2717
2718
+ // Utilities for the unification cache
2719
+
2720
+ fn hash_unify_cache_entry ( & unify_cache_entry uce) -> uint {
2721
+ auto h = ty. hash_ty ( uce. _0 ) ;
2722
+ h += h << 5 u + ty. hash_ty ( uce. _1 ) ;
2723
+
2724
+ auto i = 0 u;
2725
+ auto tys_len = _vec. len [ mutable @ty. t ] ( uce. _2 ) ;
2726
+ while ( i < tys_len) {
2727
+ h += h << 5 u + ty. hash_ty ( uce. _2 . ( i) ) ;
2728
+ i += 1 u;
2729
+ }
2730
+
2731
+ ret h;
2732
+ }
2733
+
2734
+ fn eq_unify_cache_entry ( & unify_cache_entry a, & unify_cache_entry b) -> bool {
2735
+ if ( !ty. eq_ty ( a. _0 , b. _0 ) || !ty. eq_ty ( a. _1 , b. _1 ) ) { ret false ; }
2736
+
2737
+ auto i = 0 u;
2738
+ auto tys_len = _vec. len [ mutable @ty. t ] ( a. _2 ) ;
2739
+ if ( _vec. len [ mutable @ty. t ] ( b. _2 ) != tys_len) { ret false ; }
2740
+
2741
+ while ( i < tys_len) {
2742
+ if ( !ty. eq_ty ( a. _2 . ( i ) , b. _2 . ( i) ) ) { ret false ; }
2743
+ i += 1 u;
2744
+ }
2745
+
2746
+ ret true;
2747
+ }
2748
+
2749
+
2702
2750
type typecheck_result = tup ( @ast. crate , ty. type_cache ) ;
2703
2751
2704
2752
fn check_crate ( session . session sess, @ast. crate crate) -> typecheck_result {
2705
2753
auto result = collect_item_types ( sess, crate ) ;
2706
2754
2707
2755
let vec[ ast. obj_field ] fields = vec ( ) ;
2708
2756
2757
+ auto hasher = hash_unify_cache_entry;
2758
+ auto eqer = eq_unify_cache_entry;
2759
+ auto unify_cache =
2760
+ map. mk_hashmap [ unify_cache_entry, ty. unify_result ] ( hasher, eqer) ;
2761
+
2709
2762
auto ccx = @rec ( sess=sess,
2710
2763
type_cache=result. _1 ,
2711
2764
item_items=result. _2 ,
2712
2765
obj_fields=fields,
2713
2766
this_obj=none[ ast. def_id ] ,
2714
- mutable next_var_id=0 ) ;
2767
+ mutable next_var_id=0 ,
2768
+ unify_cache=unify_cache,
2769
+ mutable cache_hits=0 u,
2770
+ mutable cache_misses=0 u) ;
2715
2771
2716
2772
auto fld = fold. new_identity_fold [ @crate_ctxt] ( ) ;
2717
2773
@@ -2721,6 +2777,10 @@ fn check_crate(session.session sess, @ast.crate crate) -> typecheck_result {
2721
2777
with * fld) ;
2722
2778
2723
2779
auto crate_1 = fold. fold_crate [ @crate_ctxt] ( ccx, fld, result. _0 ) ;
2780
+
2781
+ log #fmt( "cache hit rate: %u/%u" , ccx. cache_hits ,
2782
+ ccx. cache_hits + ccx. cache_misses ) ;
2783
+
2724
2784
ret tup ( crate_1, ccx. type_cache ) ;
2725
2785
}
2726
2786
0 commit comments