@@ -1905,7 +1905,7 @@ static int is_cacheable(jl_datatype_t *type)
19051905static void cache_insert_type (jl_value_t * type , ssize_t insert_at , int ordered )
19061906{
19071907 assert (jl_is_datatype (type ));
1908- // assign uid
1908+ // assign uid if it hasn't been done already
19091909 if (!jl_is_abstracttype (type ) && ((jl_datatype_t * )type )-> uid == 0 )
19101910 ((jl_datatype_t * )type )-> uid = jl_assign_type_uid ();
19111911 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,
19621962static jl_svec_t * inst_all (jl_svec_t * p , jl_value_t * * env , size_t n ,
19631963 jl_typestack_t * stack , int check );
19641964
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+
19651983static jl_value_t * inst_datatype (jl_datatype_t * dt , jl_svec_t * p , jl_value_t * * iparams , size_t ntp ,
19661984 int cacheable , int isabstract , jl_typestack_t * stack ,
19671985 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
19761994 if (lkup != NULL )
19771995 return lkup ;
19781996 }
1997+ jl_value_t * stack_lkup = lookup_type_stack (stack , dt , ntp , iparams );
1998+ if (stack_lkup )
1999+ return stack_lkup ;
19792000
19802001 // always use original type constructor
19812002 if (!istuple ) {
@@ -2019,7 +2040,9 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
20192040 ndt -> size = 0 ;
20202041 ndt -> alignment = 1 ;
20212042
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 ();
20232046
20242047 if (istuple )
20252048 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
20582081 ndt -> ninitialized = ntp ;
20592082 else
20602083 ndt -> ninitialized = dt -> ninitialized ;
2084+
2085+ if (cacheable ) jl_cache_type_ (ndt );
2086+
20612087 JL_GC_POP ();
20622088 return (jl_value_t * )ndt ;
20632089}
@@ -2224,23 +2250,6 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n,
22242250 // if t's parameters are not bound in the environment, return it uncopied (#9378)
22252251 if (!bound && t == tc ) { JL_GC_POP (); return (jl_value_t * )t ; }
22262252
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- }
22442253 jl_value_t * result = inst_datatype ((jl_datatype_t * )tt , NULL , iparams , ntp , cacheable , isabstract ,
22452254 stack , env , n );
22462255 JL_GC_POP ();
0 commit comments