@@ -1610,31 +1610,32 @@ JL_DLLEXPORT void jl_method_instance_add_backedge(jl_method_instance_t *callee,
1610
1610
JL_LOCK (& callee -> def .method -> writelock );
1611
1611
if (invokesig == jl_nothing )
1612
1612
invokesig = NULL ; // julia uses `nothing` but C uses NULL (#undef)
1613
+ int found = 0 ;
1614
+ // TODO: use jl_cache_type_(invokesig) like cache_method does to save memory
1613
1615
if (!callee -> backedges ) {
1614
1616
// lazy-init the backedges array
1615
1617
callee -> backedges = jl_alloc_vec_any (0 );
1616
1618
jl_gc_wb (callee , callee -> backedges );
1617
- push_edge (callee -> backedges , invokesig , caller );
1618
1619
}
1619
1620
else {
1620
1621
size_t i = 0 , l = jl_array_len (callee -> backedges );
1621
- int found = 0 ;
1622
- jl_value_t * invokeTypes ;
1623
- jl_method_instance_t * mi ;
1624
- while (i < l ) {
1625
- i = get_next_edge (callee -> backedges , i , & invokeTypes , & mi );
1626
- // TODO: it would be better to canonicalize (how?) the Tuple-type so
1627
- // that we don't have to call `jl_egal`
1628
- if (mi == caller && ((invokesig == NULL && invokeTypes == NULL ) ||
1629
- (invokesig && invokeTypes && jl_egal (invokesig , invokeTypes )))) {
1622
+ for (i = 0 ; i < l ; i ++ ) {
1623
+ // optimized version of while (i < l) i = get_next_edge(callee->backedges, i, &invokeTypes, &mi);
1624
+ jl_value_t * mi = jl_array_ptr_ref (callee -> backedges , i );
1625
+ if (mi != (jl_value_t * )caller )
1626
+ continue ;
1627
+ jl_value_t * invokeTypes = i > 0 ? jl_array_ptr_ref (callee -> backedges , i - 1 ) : NULL ;
1628
+ if (invokeTypes && jl_is_method_instance (invokeTypes ))
1629
+ invokeTypes = NULL ;
1630
+ if ((invokesig == NULL && invokeTypes == NULL ) ||
1631
+ (invokesig && invokeTypes && jl_types_equal (invokesig , invokeTypes ))) {
1630
1632
found = 1 ;
1631
1633
break ;
1632
1634
}
1633
1635
}
1634
- if (!found ) {
1635
- push_edge (callee -> backedges , invokesig , caller );
1636
- }
1637
1636
}
1637
+ if (!found )
1638
+ push_edge (callee -> backedges , invokesig , caller );
1638
1639
JL_UNLOCK (& callee -> def .method -> writelock );
1639
1640
}
1640
1641
@@ -1650,6 +1651,7 @@ JL_DLLEXPORT void jl_method_table_add_backedge(jl_methtable_t *mt, jl_value_t *t
1650
1651
jl_array_ptr_set (mt -> backedges , 1 , caller );
1651
1652
}
1652
1653
else {
1654
+ // TODO: use jl_cache_type_(tt) like cache_method does, instead of a linear scan
1653
1655
size_t i , l = jl_array_len (mt -> backedges );
1654
1656
for (i = 1 ; i < l ; i += 2 ) {
1655
1657
if (jl_types_equal (jl_array_ptr_ref (mt -> backedges , i - 1 ), typ )) {
0 commit comments