@@ -1562,13 +1562,8 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1562
1562
jl_typename_t * tn = dt -> name ;
1563
1563
int istuple = (tn == jl_tuple_typename );
1564
1564
int isnamedtuple = (tn == jl_namedtuple_typename );
1565
- if (tn != jl_type_typename ) {
1566
- size_t i ;
1567
- for (i = 0 ; i < ntp ; i ++ )
1568
- iparams [i ] = normalize_unionalls (iparams [i ]);
1569
- }
1570
1565
1571
- // check type cache, if applicable
1566
+ // check if type cache will be applicable
1572
1567
int cacheable = 1 ;
1573
1568
if (istuple ) {
1574
1569
size_t i ;
@@ -1582,26 +1577,32 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1582
1577
if (jl_has_free_typevars (iparams [i ]))
1583
1578
cacheable = 0 ;
1584
1579
}
1580
+ // if applicable, check the cache first for a match
1585
1581
if (cacheable ) {
1582
+ jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
1583
+ if (lkup != NULL )
1584
+ return lkup ;
1585
+ }
1586
+ // if some normalization might be needed, do that now
1587
+ // it is probably okay to mutate iparams, and we only store globally rooted objects here
1588
+ if (check && cacheable ) {
1586
1589
size_t i ;
1587
1590
for (i = 0 ; i < ntp ; i ++ ) {
1588
1591
jl_value_t * pi = iparams [i ];
1589
1592
if (pi == jl_bottom_type )
1590
1593
continue ;
1591
1594
if (jl_is_datatype (pi ))
1592
1595
continue ;
1593
- if (jl_is_vararg (pi )) {
1594
- pi = jl_unwrap_vararg (pi );
1595
- if (jl_has_free_typevars (pi ))
1596
- continue ;
1597
- }
1598
- // normalize types equal to wrappers (prepare for wrapper_id)
1596
+ if (jl_is_vararg (pi ))
1597
+ // This would require some special handling, but is not needed
1598
+ // at the moment (and might be better handled in jl_wrap_vararg instead).
1599
+ continue ;
1600
+ if (!cacheable && jl_has_free_typevars (pi ))
1601
+ continue ;
1602
+ // normalize types equal to wrappers (prepare for Typeofwrapper)
1599
1603
jl_value_t * tw = extract_wrapper (pi );
1600
1604
if (tw && tw != pi && (tn != jl_type_typename || jl_typeof (pi ) == jl_typeof (tw )) &&
1601
1605
jl_types_equal (pi , tw )) {
1602
- // This would require some special handling, but is never used at
1603
- // the moment.
1604
- assert (!jl_is_vararg (iparams [i ]));
1605
1606
iparams [i ] = tw ;
1606
1607
if (p ) jl_gc_wb (p , tw );
1607
1608
}
@@ -1611,6 +1612,9 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1611
1612
// normalize Type{Type{Union{}}} to Type{TypeofBottom}
1612
1613
iparams [0 ] = (jl_value_t * )jl_typeofbottom_type ;
1613
1614
}
1615
+ }
1616
+ // then check the cache again, if applicable
1617
+ if (cacheable ) {
1614
1618
jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
1615
1619
if (lkup != NULL )
1616
1620
return lkup ;
@@ -1619,12 +1623,15 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1619
1623
if (stack_lkup )
1620
1624
return stack_lkup ;
1621
1625
1626
+ // check parameters against bounds in type definition
1627
+ // for whether this is even valid
1622
1628
if (!istuple ) {
1623
- // check parameters against bounds in type definition
1629
+ assert ( ntp > 0 );
1624
1630
check_datatype_parameters (tn , iparams , ntp );
1625
1631
}
1626
1632
else if (ntp == 0 && jl_emptytuple_type != NULL ) {
1627
1633
// empty tuple type case
1634
+ assert (istuple );
1628
1635
return (jl_value_t * )jl_emptytuple_type ;
1629
1636
}
1630
1637
@@ -1670,6 +1677,42 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1670
1677
jl_svecset (p , i , iparams [i ]);
1671
1678
}
1672
1679
1680
+ // try to simplify some type parameters
1681
+ if (check && tn != jl_type_typename ) {
1682
+ size_t i ;
1683
+ int changed = 0 ;
1684
+ if (istuple ) // normalization might change Tuple's, but not other types's, cacheable status
1685
+ cacheable = 1 ;
1686
+ for (i = 0 ; i < ntp ; i ++ ) {
1687
+ jl_value_t * newp = normalize_unionalls (iparams [i ]);
1688
+ if (newp != iparams [i ]) {
1689
+ iparams [i ] = newp ;
1690
+ jl_svecset (p , i , newp );
1691
+ changed = 1 ;
1692
+ }
1693
+ if (istuple && cacheable && !jl_is_concrete_type (newp ))
1694
+ cacheable = 0 ;
1695
+ }
1696
+ if (changed ) {
1697
+ // If this changed something, we need to check the cache again, in
1698
+ // case we missed the match earlier before the normalizations
1699
+ //
1700
+ // e.g. return inst_datatype_inner(dt, p, iparams, ntp, stack, env, 0);
1701
+ if (cacheable ) {
1702
+ jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
1703
+ if (lkup != NULL ) {
1704
+ JL_GC_POP ();
1705
+ return lkup ;
1706
+ }
1707
+ }
1708
+ jl_value_t * stack_lkup = lookup_type_stack (stack , dt , ntp , iparams );
1709
+ if (stack_lkup ) {
1710
+ JL_GC_POP ();
1711
+ return stack_lkup ;
1712
+ }
1713
+ }
1714
+ }
1715
+
1673
1716
// acquire the write lock now that we know we need a new object
1674
1717
// since we're going to immediately leak it globally via the instantiation stack
1675
1718
if (cacheable ) {
0 commit comments