@@ -1610,31 +1610,32 @@ JL_DLLEXPORT void jl_method_instance_add_backedge(jl_method_instance_t *callee,
16101610 JL_LOCK (& callee -> def .method -> writelock );
16111611 if (invokesig == jl_nothing )
16121612 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
16131615 if (!callee -> backedges ) {
16141616 // lazy-init the backedges array
16151617 callee -> backedges = jl_alloc_vec_any (0 );
16161618 jl_gc_wb (callee , callee -> backedges );
1617- push_edge (callee -> backedges , invokesig , caller );
16181619 }
16191620 else {
16201621 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 ))) {
16301632 found = 1 ;
16311633 break ;
16321634 }
16331635 }
1634- if (!found ) {
1635- push_edge (callee -> backedges , invokesig , caller );
1636- }
16371636 }
1637+ if (!found )
1638+ push_edge (callee -> backedges , invokesig , caller );
16381639 JL_UNLOCK (& callee -> def .method -> writelock );
16391640}
16401641
@@ -1650,6 +1651,7 @@ JL_DLLEXPORT void jl_method_table_add_backedge(jl_methtable_t *mt, jl_value_t *t
16501651 jl_array_ptr_set (mt -> backedges , 1 , caller );
16511652 }
16521653 else {
1654+ // TODO: use jl_cache_type_(tt) like cache_method does, instead of a linear scan
16531655 size_t i , l = jl_array_len (mt -> backedges );
16541656 for (i = 1 ; i < l ; i += 2 ) {
16551657 if (jl_types_equal (jl_array_ptr_ref (mt -> backedges , i - 1 ), typ )) {
0 commit comments