@@ -1844,13 +1844,8 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1844
1844
jl_typename_t * tn = dt -> name ;
1845
1845
int istuple = (tn == jl_tuple_typename );
1846
1846
int isnamedtuple = (tn == jl_namedtuple_typename );
1847
- if (check && tn != jl_type_typename ) {
1848
- size_t i ;
1849
- for (i = 0 ; i < ntp ; i ++ )
1850
- iparams [i ] = normalize_unionalls (iparams [i ]);
1851
- }
1852
1847
1853
- // check type cache, if applicable
1848
+ // check if type cache will be applicable
1854
1849
int cacheable = 1 ;
1855
1850
if (istuple ) {
1856
1851
size_t i ;
@@ -1886,26 +1881,32 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1886
1881
if (jl_has_free_typevars (iparams [i ]))
1887
1882
cacheable = 0 ;
1888
1883
}
1884
+ // if applicable, check the cache first for a match
1889
1885
if (cacheable ) {
1886
+ jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
1887
+ if (lkup != NULL )
1888
+ return lkup ;
1889
+ }
1890
+ // if some normalization might be needed, do that now
1891
+ // it is probably okay to mutate iparams, and we only store globally rooted objects here
1892
+ if (check && cacheable ) {
1890
1893
size_t i ;
1891
1894
for (i = 0 ; i < ntp ; i ++ ) {
1892
1895
jl_value_t * pi = iparams [i ];
1893
1896
if (pi == jl_bottom_type )
1894
1897
continue ;
1895
1898
if (jl_is_datatype (pi ))
1896
1899
continue ;
1897
- if (jl_is_vararg (pi )) {
1898
- pi = jl_unwrap_vararg (pi );
1899
- if (jl_has_free_typevars (pi ))
1900
- continue ;
1901
- }
1902
- // normalize types equal to wrappers (prepare for wrapper_id)
1900
+ if (jl_is_vararg (pi ))
1901
+ // This would require some special handling, but is not needed
1902
+ // at the moment (and might be better handled in jl_wrap_vararg instead).
1903
+ continue ;
1904
+ if (!cacheable && jl_has_free_typevars (pi ))
1905
+ continue ;
1906
+ // normalize types equal to wrappers (prepare for Typeofwrapper)
1903
1907
jl_value_t * tw = extract_wrapper (pi );
1904
1908
if (tw && tw != pi && (tn != jl_type_typename || jl_typeof (pi ) == jl_typeof (tw )) &&
1905
1909
jl_types_equal (pi , tw )) {
1906
- // This would require some special handling, but is never used at
1907
- // the moment.
1908
- assert (!jl_is_vararg (iparams [i ]));
1909
1910
iparams [i ] = tw ;
1910
1911
if (p ) jl_gc_wb (p , tw );
1911
1912
}
@@ -1915,6 +1916,9 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1915
1916
// normalize Type{Type{Union{}}} to Type{TypeofBottom}
1916
1917
iparams [0 ] = (jl_value_t * )jl_typeofbottom_type ;
1917
1918
}
1919
+ }
1920
+ // then check the cache again, if applicable
1921
+ if (cacheable ) {
1918
1922
jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
1919
1923
if (lkup != NULL )
1920
1924
return lkup ;
@@ -1923,12 +1927,15 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1923
1927
if (stack_lkup )
1924
1928
return stack_lkup ;
1925
1929
1930
+ // check parameters against bounds in type definition
1931
+ // for whether this is even valid
1926
1932
if (check && !istuple ) {
1927
- // check parameters against bounds in type definition
1933
+ assert ( ntp > 0 );
1928
1934
check_datatype_parameters (tn , iparams , ntp );
1929
1935
}
1930
1936
else if (ntp == 0 && jl_emptytuple_type != NULL ) {
1931
1937
// empty tuple type case
1938
+ assert (istuple );
1932
1939
return (jl_value_t * )jl_emptytuple_type ;
1933
1940
}
1934
1941
@@ -1974,6 +1981,42 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1974
1981
jl_svecset (p , i , iparams [i ]);
1975
1982
}
1976
1983
1984
+ // try to simplify some type parameters
1985
+ if (check && tn != jl_type_typename ) {
1986
+ size_t i ;
1987
+ int changed = 0 ;
1988
+ if (istuple ) // normalization might change Tuple's, but not other types's, cacheable status
1989
+ cacheable = 1 ;
1990
+ for (i = 0 ; i < ntp ; i ++ ) {
1991
+ jl_value_t * newp = normalize_unionalls (iparams [i ]);
1992
+ if (newp != iparams [i ]) {
1993
+ iparams [i ] = newp ;
1994
+ jl_svecset (p , i , newp );
1995
+ changed = 1 ;
1996
+ }
1997
+ if (istuple && cacheable && !jl_is_concrete_type (newp ))
1998
+ cacheable = 0 ;
1999
+ }
2000
+ if (changed ) {
2001
+ // If this changed something, we need to check the cache again, in
2002
+ // case we missed the match earlier before the normalizations
2003
+ //
2004
+ // e.g. return inst_datatype_inner(dt, p, iparams, ntp, stack, env, 0);
2005
+ if (cacheable ) {
2006
+ jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
2007
+ if (lkup != NULL ) {
2008
+ JL_GC_POP ();
2009
+ return lkup ;
2010
+ }
2011
+ }
2012
+ jl_value_t * stack_lkup = lookup_type_stack (stack , dt , ntp , iparams );
2013
+ if (stack_lkup ) {
2014
+ JL_GC_POP ();
2015
+ return stack_lkup ;
2016
+ }
2017
+ }
2018
+ }
2019
+
1977
2020
// acquire the write lock now that we know we need a new object
1978
2021
// since we're going to immediately leak it globally via the instantiation stack
1979
2022
if (cacheable ) {
0 commit comments