oprofile fix for hashing backtraces.

Oprofile's hash function uses a 64-bit value for the
key where the high 32-bit are the 'from' address in a backtrace,
and the low 32-bits are the current PC. However, the hash
function was:

  uint32_t temp = (value >> 32) ^ value;
  return ((temp << 0) ^ (temp >> 8)) & data->hash_mask;

If 'from' and 'to' are the same (recursive function), this hashes
to 0, and you end up with lots of collisions, turning the
theoretically O(1) operation into O(n).

To fix it, I just drop the high 32-bits from the hash:

  uint32_t temp = value & 0xffffffff;
  return ((temp << 0) ^ (temp >> 8)) & data->hash_mask;

In testing, this drastically reduces the oprofile overhead
for some tracing.

Change-Id: I8ae65a8a73771c89b576c895f135efd7b730eaf5
2 files changed