It should still be found in the first loop then. In both cases the pointer is used as the hash value. Its only that since my change in hash_svalue it wont anymore, since the extra mixing is only used on the function pointer.
It's not only that, it's also that in the first loop it compares with c->args, while in the second it compares with c->args->item[0].
Yes, I noticed that and hence assumed that the order does not matter. If it does, my optimization is bad. On the other hand, if the buckets are properly sorted, we could do both is_identical checks and either return or push if the current one is not identical to the top on the stack.
Since backend_find_call_out has this bad O(n) complexity, where n is the number of times the function has been queued, I think it could just as well look through all matches and pick the one with the lowest tv value. But it can still do both is_identical optimizations.
The alternative, to keep the buckets sorted, is a rather more meaty change. It's not just a matter of sorting them either, because that'd make new_call_out O(n) instead, which would be worse. One would have to change to a different data structure, like one binary heap per bucket.
It also looks like a rehash shuffles the buckets a bit.
This is something that would be fixed by power of two hash tables, since the code only seems to increase the hash table size. And then, buckets are only split, never shuffled.
I don't think it matters in this case, since it doesn't visit the items in bucket order. It uses the binary heap afaics.