@@ -1720,6 +1720,35 @@ DLLEXPORT jl_value_t *jl_tupletype_fill(size_t n, jl_value_t *v)
1720
1720
return p ;
1721
1721
}
1722
1722
1723
+ static int contains_unions (jl_value_t * type )
1724
+ {
1725
+ if (jl_is_uniontype (type )) return 1 ;
1726
+ if (jl_is_typector (type )) return contains_unions (((jl_typector_t * )type )-> body );
1727
+ if (!jl_is_datatype (type )) return 0 ;
1728
+ int i ;
1729
+ for (i = 0 ; i < jl_nparams (type ); i ++ ) {
1730
+ if (contains_unions (jl_tparam (type ,i )))
1731
+ return 1 ;
1732
+ }
1733
+ return 0 ;
1734
+ }
1735
+
1736
+ // this function determines whether a type is simple enough to form
1737
+ // a total order based on UIDs and object_id.
1738
+ static int is_typekey_ordered (jl_value_t * * key , size_t n )
1739
+ {
1740
+ size_t i ;
1741
+ for (i = 0 ; i < n ; i ++ ) {
1742
+ jl_value_t * k = key [i ];
1743
+ if (jl_is_type (k ) &&
1744
+ !(jl_is_datatype (k ) && (((jl_datatype_t * )k )-> uid ||
1745
+ k == ((jl_datatype_t * )k )-> name -> primary ||
1746
+ (!jl_has_typevars_ (k ,1 ) && !contains_unions (k )))))
1747
+ return 0 ;
1748
+ }
1749
+ return 1 ;
1750
+ }
1751
+
1723
1752
// ordered comparison of types
1724
1753
static int typekey_compare (jl_datatype_t * tt , jl_value_t * * key , size_t n )
1725
1754
{
@@ -1729,49 +1758,78 @@ static int typekey_compare(jl_datatype_t *tt, jl_value_t **key, size_t n)
1729
1758
if (n < tnp ) return -1 ;
1730
1759
if (n > tnp ) return 1 ;
1731
1760
for (j = 0 ; j < n ; j ++ ) {
1732
- jl_value_t * tj = jl_svecref (tt -> parameters ,j );
1733
- jl_value_t * kj = key [j ];
1761
+ jl_value_t * kj = key [j ], * tj = jl_svecref (tt -> parameters ,j );
1734
1762
if (tj != kj ) {
1735
- if (!type_eqv__ (tj , kj , 1 )) {
1736
- uptrint_t tid =
1737
- (jl_is_datatype (tj ) && ((jl_datatype_t * )tj )-> uid ) ? ((jl_datatype_t * )tj )-> uid : jl_object_id (tj );
1738
- uptrint_t kid =
1739
- (jl_is_datatype (kj ) && ((jl_datatype_t * )kj )-> uid ) ? ((jl_datatype_t * )kj )-> uid : jl_object_id (kj );
1763
+ int dtt = jl_is_datatype (tj );
1764
+ int dtk = jl_is_datatype (kj );
1765
+ if (!dtt && !dtk && jl_egal (tj , kj ))
1766
+ continue ;
1767
+ uptrint_t tid = (dtt && ((jl_datatype_t * )tj )-> uid ? ((jl_datatype_t * )tj )-> uid : jl_object_id (tj ));
1768
+ uptrint_t kid = (dtk && ((jl_datatype_t * )kj )-> uid ? ((jl_datatype_t * )kj )-> uid : jl_object_id (kj ));
1769
+ if (kid != tid )
1740
1770
return kid < tid ? -1 : 1 ;
1741
- }
1742
1771
}
1743
1772
}
1744
1773
return 0 ;
1745
1774
}
1746
1775
1747
- // look up a type in a cache by binary search.
1776
+ static int typekey_eq (jl_datatype_t * tt , jl_value_t * * key , size_t n )
1777
+ {
1778
+ size_t j ;
1779
+ size_t tnp = jl_nparams (tt );
1780
+ if (n != tnp ) return 0 ;
1781
+ for (j = 0 ; j < n ; j ++ ) {
1782
+ jl_value_t * kj = key [j ], * tj = jl_svecref (tt -> parameters ,j );
1783
+ if (tj != kj && !type_eqv__ (tj , kj , 1 ))
1784
+ return 0 ;
1785
+ }
1786
+ return 1 ;
1787
+ }
1788
+
1789
+ // look up a type in a cache by binary or linear search.
1748
1790
// if found, returns the index of the found item. if not found, returns
1749
1791
// ~n, where n is the index where the type should be inserted.
1750
- static ssize_t lookup_type_idx (jl_typename_t * tn , jl_value_t * * key , size_t n )
1792
+ static ssize_t lookup_type_idx (jl_typename_t * tn , jl_value_t * * key , size_t n , int ordered )
1751
1793
{
1752
1794
if (n == 0 ) return -1 ;
1753
- jl_value_t * cache = tn -> cache ;
1754
- jl_value_t * * data = jl_svec_data (cache );
1755
- size_t cl = jl_svec_len (cache );
1756
- ssize_t lo = -1 ;
1757
- ssize_t hi = cl ;
1758
- while (lo < hi - 1 ) {
1759
- ssize_t m = ((size_t )(lo + hi ))>>1 ;
1760
- jl_datatype_t * tt = (jl_datatype_t * )data [m ];
1761
- int cmp = typekey_compare (tt , key , n );
1762
- if (cmp == 0 ) return m ;
1763
- if (cmp < 0 )
1764
- hi = m ;
1765
- else
1766
- lo = m ;
1795
+ if (ordered ) {
1796
+ jl_svec_t * cache = tn -> cache ;
1797
+ jl_value_t * * data = jl_svec_data (cache );
1798
+ size_t cl = jl_svec_len (cache );
1799
+ ssize_t lo = -1 ;
1800
+ ssize_t hi = cl ;
1801
+ while (lo < hi - 1 ) {
1802
+ ssize_t m = ((size_t )(lo + hi ))>>1 ;
1803
+ jl_datatype_t * tt = (jl_datatype_t * )data [m ];
1804
+ int cmp = typekey_compare (tt , key , n );
1805
+ if (cmp == 0 ) return m ;
1806
+ if (cmp < 0 )
1807
+ hi = m ;
1808
+ else
1809
+ lo = m ;
1810
+ }
1811
+ return ~hi ;
1812
+ }
1813
+ else {
1814
+ jl_svec_t * cache = tn -> linearcache ;
1815
+ jl_value_t * * data = jl_svec_data (cache );
1816
+ size_t cl = jl_svec_len (cache );
1817
+ ssize_t i ;
1818
+ for (i = 0 ; i < cl ; i ++ ) {
1819
+ jl_datatype_t * tt = (jl_datatype_t * )data [i ];
1820
+ if (tt == NULL ) return ~i ;
1821
+ if (typekey_eq (tt , key , n ))
1822
+ return i ;
1823
+ }
1824
+ return ~cl ;
1767
1825
}
1768
- return ~hi ;
1769
1826
}
1770
1827
1771
1828
static jl_value_t * lookup_type (jl_typename_t * tn , jl_value_t * * key , size_t n )
1772
1829
{
1773
- ssize_t idx = lookup_type_idx (tn , key , n );
1774
- return (idx < 0 ) ? NULL : jl_svecref (tn -> cache , idx );
1830
+ int ord = is_typekey_ordered (key , n );
1831
+ ssize_t idx = lookup_type_idx (tn , key , n , ord );
1832
+ return (idx < 0 ) ? NULL : jl_svecref (ord ? tn -> cache : tn -> linearcache , idx );
1775
1833
}
1776
1834
1777
1835
static int t_uid_ctr = 1 ;
@@ -1809,21 +1867,28 @@ static int is_cacheable(jl_datatype_t *type)
1809
1867
return 1 ;
1810
1868
}
1811
1869
1812
- static void cache_insert_type (jl_value_t * type , ssize_t insert_at )
1870
+ static void cache_insert_type (jl_value_t * type , ssize_t insert_at , int ordered )
1813
1871
{
1814
1872
assert (jl_is_datatype (type ));
1815
1873
// assign uid
1816
1874
if (!jl_is_abstracttype (type ) && ((jl_datatype_t * )type )-> uid == 0 )
1817
1875
((jl_datatype_t * )type )-> uid = jl_assign_type_uid ();
1818
- jl_value_t * cache = ((jl_datatype_t * )type )-> name -> cache ;
1876
+ jl_svec_t * cache ;
1877
+ if (ordered )
1878
+ cache = ((jl_datatype_t * )type )-> name -> cache ;
1879
+ else
1880
+ cache = ((jl_datatype_t * )type )-> name -> linearcache ;
1819
1881
assert (jl_is_svec (cache ));
1820
1882
size_t n = jl_svec_len (cache );
1821
1883
if (n == 0 || jl_svecref (cache ,n - 1 ) != NULL ) {
1822
1884
jl_svec_t * nc = jl_alloc_svec (n < 8 ? 8 : (n * 3 )>>1 );
1823
1885
memcpy (jl_svec_data (nc ), jl_svec_data (cache ), sizeof (void * ) * n );
1824
- ((jl_datatype_t * )type )-> name -> cache = (jl_value_t * )nc ;
1886
+ if (ordered )
1887
+ ((jl_datatype_t * )type )-> name -> cache = nc ;
1888
+ else
1889
+ ((jl_datatype_t * )type )-> name -> linearcache = nc ;
1825
1890
gc_wb (((jl_datatype_t * )type )-> name , nc );
1826
- cache = ( jl_value_t * ) nc ;
1891
+ cache = nc ;
1827
1892
n = jl_svec_len (nc );
1828
1893
}
1829
1894
jl_value_t * * p = jl_svec_data (cache );
@@ -1842,11 +1907,12 @@ static void cache_insert_type(jl_value_t *type, ssize_t insert_at)
1842
1907
jl_value_t * jl_cache_type_ (jl_datatype_t * type )
1843
1908
{
1844
1909
if (is_cacheable (type )) {
1910
+ int ord = is_typekey_ordered (jl_svec_data (type -> parameters ), jl_svec_len (type -> parameters ));
1845
1911
ssize_t idx = lookup_type_idx (type -> name , type -> parameters -> data ,
1846
- jl_svec_len (type -> parameters ));
1912
+ jl_svec_len (type -> parameters ), ord );
1847
1913
if (idx >= 0 )
1848
- return jl_svecref (type -> name -> cache , idx );
1849
- cache_insert_type ((jl_value_t * )type , ~idx );
1914
+ return jl_svecref (ord ? type -> name -> cache : type -> name -> linearcache , idx );
1915
+ cache_insert_type ((jl_value_t * )type , ~idx , ord );
1850
1916
}
1851
1917
return (jl_value_t * )type ;
1852
1918
}
@@ -1918,6 +1984,8 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
1918
1984
ndt -> size = 0 ;
1919
1985
ndt -> alignment = 1 ;
1920
1986
1987
+ if (cacheable ) jl_cache_type_ (ndt );
1988
+
1921
1989
if (istuple )
1922
1990
ndt -> super = jl_any_type ;
1923
1991
else
@@ -1953,10 +2021,8 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
1953
2021
ndt -> ninitialized = ntp ;
1954
2022
else
1955
2023
ndt -> ninitialized = dt -> ninitialized ;
1956
- if (cacheable ) jl_cache_type_ (ndt );
1957
- jl_value_t * result = (jl_value_t * )ndt ;
1958
2024
JL_GC_POP ();
1959
- return result ;
2025
+ return ( jl_value_t * ) ndt ;
1960
2026
}
1961
2027
1962
2028
static jl_tupletype_t * jl_apply_tuple_type_v_ (jl_value_t * * p , size_t np , jl_svec_t * params )
@@ -2098,7 +2164,7 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n,
2098
2164
jl_value_t * lkup = NULL ;
2099
2165
while (tmp != NULL ) {
2100
2166
if (tmp -> tt -> name == tn && ntp == jl_svec_len (tmp -> tt -> parameters ) &&
2101
- typekey_compare (tmp -> tt , iparams , ntp )== 0 ) {
2167
+ typekey_eq (tmp -> tt , iparams , ntp )) {
2102
2168
lkup = (jl_value_t * )tmp -> tt ;
2103
2169
break ;
2104
2170
}
@@ -2947,8 +3013,7 @@ void jl_init_types(void)
2947
3013
// create base objects
2948
3014
jl_datatype_type = jl_new_uninitialized_datatype (9 );
2949
3015
jl_set_typeof (jl_datatype_type , jl_datatype_type );
2950
- jl_typename_type = jl_new_uninitialized_datatype (5 );
2951
- jl_typename_type = jl_new_uninitialized_datatype (6 );
3016
+ jl_typename_type = jl_new_uninitialized_datatype (7 );
2952
3017
jl_sym_type = jl_new_uninitialized_datatype (0 );
2953
3018
jl_symbol_type = jl_sym_type ;
2954
3019
jl_simplevector_type = jl_new_uninitialized_datatype (1 );
@@ -2993,11 +3058,13 @@ void jl_init_types(void)
2993
3058
jl_typename_type -> name -> primary = (jl_value_t * )jl_typename_type ;
2994
3059
jl_typename_type -> super = jl_any_type ;
2995
3060
jl_typename_type -> parameters = jl_emptysvec ;
2996
- jl_typename_type -> name -> names = jl_svec (6 , jl_symbol ("name" ), jl_symbol ("module" ),
3061
+ jl_typename_type -> name -> names = jl_svec (7 , jl_symbol ("name" ), jl_symbol ("module" ),
2997
3062
jl_symbol ("names" ), jl_symbol ("primary" ),
2998
- jl_symbol ("cache" ), jl_symbol ("uid" ));
2999
- jl_typename_type -> types = jl_svec (6 , jl_sym_type , jl_any_type , jl_simplevector_type ,
3000
- jl_type_type , jl_any_type , jl_any_type );
3063
+ jl_symbol ("cache" ), jl_symbol ("linearcache" ),
3064
+ jl_symbol ("uid" ));
3065
+ jl_typename_type -> types = jl_svec (7 , jl_sym_type , jl_any_type , jl_simplevector_type ,
3066
+ jl_type_type , jl_simplevector_type , jl_simplevector_type ,
3067
+ jl_any_type );
3001
3068
jl_typename_type -> uid = jl_assign_type_uid ();
3002
3069
jl_typename_type -> instance = NULL ;
3003
3070
jl_typename_type -> struct_decl = NULL ;
@@ -3287,7 +3354,7 @@ void jl_init_types(void)
3287
3354
jl_svecset (jl_function_type -> types , 0 , pointer_void );
3288
3355
jl_svecset (jl_tvar_type -> types , 3 , (jl_value_t * )jl_bool_type );
3289
3356
jl_svecset (jl_simplevector_type -> types , 0 , jl_long_type );
3290
- jl_svecset (jl_typename_type -> types , 5 , jl_long_type );
3357
+ jl_svecset (jl_typename_type -> types , 6 , jl_long_type );
3291
3358
3292
3359
jl_compute_field_offsets (jl_datatype_type );
3293
3360
jl_compute_field_offsets (jl_typename_type );
0 commit comments