@@ -1905,7 +1905,7 @@ static int is_cacheable(jl_datatype_t *type)
1905
1905
static void cache_insert_type (jl_value_t * type , ssize_t insert_at , int ordered )
1906
1906
{
1907
1907
assert (jl_is_datatype (type ));
1908
- // assign uid
1908
+ // assign uid if it hasn't been done already
1909
1909
if (!jl_is_abstracttype (type ) && ((jl_datatype_t * )type )-> uid == 0 )
1910
1910
((jl_datatype_t * )type )-> uid = jl_assign_type_uid ();
1911
1911
jl_svec_t * cache ;
@@ -1962,6 +1962,24 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n,
1962
1962
static jl_svec_t * inst_all (jl_svec_t * p , jl_value_t * * env , size_t n ,
1963
1963
jl_typestack_t * stack , int check );
1964
1964
1965
+ static jl_value_t * lookup_type_stack (jl_typestack_t * stack , jl_datatype_t * tt , size_t ntp ,
1966
+ jl_value_t * * iparams )
1967
+ {
1968
+ // if an identical instantiation is already in process somewhere up the
1969
+ // stack, return it. this computes a fixed point for recursive types.
1970
+ jl_typename_t * tn = tt -> name ;
1971
+ while (stack != NULL ) {
1972
+ if (stack -> tt -> name == tn &&
1973
+ ntp == jl_svec_len (stack -> tt -> parameters ) &&
1974
+ typekey_eq (stack -> tt , iparams , ntp )) {
1975
+ jl_value_t * lkup = (jl_value_t * )stack -> tt ;
1976
+ return lkup == tn -> primary ? NULL : lkup ;
1977
+ }
1978
+ stack = stack -> prev ;
1979
+ }
1980
+ return NULL ;
1981
+ }
1982
+
1965
1983
static jl_value_t * inst_datatype (jl_datatype_t * dt , jl_svec_t * p , jl_value_t * * iparams , size_t ntp ,
1966
1984
int cacheable , int isabstract , jl_typestack_t * stack ,
1967
1985
jl_value_t * * env , size_t n )
@@ -1976,6 +1994,9 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
1976
1994
if (lkup != NULL )
1977
1995
return lkup ;
1978
1996
}
1997
+ jl_value_t * stack_lkup = lookup_type_stack (stack , dt , ntp , iparams );
1998
+ if (stack_lkup )
1999
+ return stack_lkup ;
1979
2000
1980
2001
// always use original type constructor
1981
2002
if (!istuple ) {
@@ -2019,7 +2040,9 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
2019
2040
ndt -> size = 0 ;
2020
2041
ndt -> alignment = 1 ;
2021
2042
2022
- if (cacheable ) jl_cache_type_ (ndt );
2043
+ // assign uid as early as possible
2044
+ if (cacheable && !ndt -> abstract && ndt -> uid == 0 )
2045
+ ndt -> uid = jl_assign_type_uid ();
2023
2046
2024
2047
if (istuple )
2025
2048
ndt -> super = jl_any_type ;
@@ -2058,6 +2081,9 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
2058
2081
ndt -> ninitialized = ntp ;
2059
2082
else
2060
2083
ndt -> ninitialized = dt -> ninitialized ;
2084
+
2085
+ if (cacheable ) jl_cache_type_ (ndt );
2086
+
2061
2087
JL_GC_POP ();
2062
2088
return (jl_value_t * )ndt ;
2063
2089
}
@@ -2224,23 +2250,6 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n,
2224
2250
// if t's parameters are not bound in the environment, return it uncopied (#9378)
2225
2251
if (!bound && t == tc ) { JL_GC_POP (); return (jl_value_t * )t ; }
2226
2252
2227
- // if an identical instantiation is already in process somewhere
2228
- // up the stack, return it. this computes a fixed point for
2229
- // recursive types.
2230
- jl_typestack_t * tmp = stack ;
2231
- jl_value_t * lkup = NULL ;
2232
- while (tmp != NULL ) {
2233
- if (tmp -> tt -> name == tn && ntp == jl_svec_len (tmp -> tt -> parameters ) &&
2234
- typekey_eq (tmp -> tt , iparams , ntp )) {
2235
- lkup = (jl_value_t * )tmp -> tt ;
2236
- break ;
2237
- }
2238
- tmp = tmp -> prev ;
2239
- }
2240
- if (lkup != NULL && lkup != (jl_value_t * )tc ) {
2241
- JL_GC_POP ();
2242
- return lkup ;
2243
- }
2244
2253
jl_value_t * result = inst_datatype ((jl_datatype_t * )tt , NULL , iparams , ntp , cacheable , isabstract ,
2245
2254
stack , env , n );
2246
2255
JL_GC_POP ();
0 commit comments