mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-04 08:27:50 +00:00
[Sanitizer] Return code that calculates hash for stacktrace back to StackDepot implementation
llvm-svn: 220663
This commit is contained in:
parent
18c89411b8
commit
e853b4f2e4
@ -19,44 +19,6 @@ namespace __msan {
|
||||
struct ChainedOriginDepotDesc {
|
||||
u32 here_id;
|
||||
u32 prev_id;
|
||||
/* This is murmur2 hash for the 64->32 bit case.
|
||||
It does not behave all that well because the keys have a very biased
|
||||
distribution (I've seen 7-element buckets with the table only 14% full).
|
||||
|
||||
here_id is built of
|
||||
* (1 bits) Reserved, zero.
|
||||
* (8 bits) Part id = bits 13..20 of the hash value of here_id's key.
|
||||
* (23 bits) Sequential number (each part has each own sequence).
|
||||
|
||||
prev_id has either the same distribution as here_id (but with 3:8:21)
|
||||
split, or one of two reserved values (-1) or (-2). Either case can
|
||||
dominate depending on the workload.
|
||||
*/
|
||||
u32 hash() const {
|
||||
const u32 m = 0x5bd1e995;
|
||||
const u32 seed = 0x9747b28c;
|
||||
const u32 r = 24;
|
||||
u32 h = seed;
|
||||
u32 k = here_id;
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
h *= m;
|
||||
h ^= k;
|
||||
|
||||
k = prev_id;
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
h *= m;
|
||||
h ^= k;
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
return h;
|
||||
}
|
||||
bool is_valid() { return true; }
|
||||
};
|
||||
|
||||
struct ChainedOriginDepotNode {
|
||||
@ -72,6 +34,44 @@ struct ChainedOriginDepotNode {
|
||||
static uptr storage_size(const args_type &args) {
|
||||
return sizeof(ChainedOriginDepotNode);
|
||||
}
|
||||
/* This is murmur2 hash for the 64->32 bit case.
|
||||
It does not behave all that well because the keys have a very biased
|
||||
distribution (I've seen 7-element buckets with the table only 14% full).
|
||||
|
||||
here_id is built of
|
||||
* (1 bits) Reserved, zero.
|
||||
* (8 bits) Part id = bits 13..20 of the hash value of here_id's key.
|
||||
* (23 bits) Sequential number (each part has each own sequence).
|
||||
|
||||
prev_id has either the same distribution as here_id (but with 3:8:21)
|
||||
split, or one of two reserved values (-1) or (-2). Either case can
|
||||
dominate depending on the workload.
|
||||
*/
|
||||
static u32 hash(const args_type &args) {
|
||||
const u32 m = 0x5bd1e995;
|
||||
const u32 seed = 0x9747b28c;
|
||||
const u32 r = 24;
|
||||
u32 h = seed;
|
||||
u32 k = args.here_id;
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
h *= m;
|
||||
h ^= k;
|
||||
|
||||
k = args.prev_id;
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
h *= m;
|
||||
h ^= k;
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
return h;
|
||||
}
|
||||
static bool is_valid(const args_type &args) { return true; }
|
||||
void store(const args_type &args, u32 other_hash) {
|
||||
here_id = args.here_id;
|
||||
prev_id = args.prev_id;
|
||||
|
@ -47,6 +47,28 @@ struct StackDepotNode {
|
||||
static uptr storage_size(const args_type &args) {
|
||||
return sizeof(StackDepotNode) + (args.size - 1) * sizeof(uptr);
|
||||
}
|
||||
static u32 hash(const args_type &args) {
|
||||
// murmur2
|
||||
const u32 m = 0x5bd1e995;
|
||||
const u32 seed = 0x9747b28c;
|
||||
const u32 r = 24;
|
||||
u32 h = seed ^ (args.size * sizeof(uptr));
|
||||
for (uptr i = 0; i < args.size; i++) {
|
||||
u32 k = args.trace[i];
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
h *= m;
|
||||
h ^= k;
|
||||
}
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
return h;
|
||||
}
|
||||
static bool is_valid(const args_type &args) {
|
||||
return args.size > 0 && args.trace;
|
||||
}
|
||||
void store(const args_type &args, u32 hash) {
|
||||
atomic_store(&hash_and_use_count, hash & kHashMask, memory_order_relaxed);
|
||||
size = args.size;
|
||||
|
@ -97,8 +97,8 @@ typename StackDepotBase<Node, kReservedBits, kTabSizeLog>::handle_type
|
||||
StackDepotBase<Node, kReservedBits, kTabSizeLog>::Put(args_type args,
|
||||
bool *inserted) {
|
||||
if (inserted) *inserted = false;
|
||||
if (!args.is_valid()) return handle_type();
|
||||
uptr h = args.hash();
|
||||
if (!Node::is_valid(args)) return handle_type();
|
||||
uptr h = Node::hash(args);
|
||||
atomic_uintptr_t *p = &tab[h % kTabSize];
|
||||
uptr v = atomic_load(p, memory_order_consume);
|
||||
Node *s = (Node *)(v & ~1);
|
||||
|
@ -39,27 +39,6 @@ struct StackTrace {
|
||||
// Prints a symbolized stacktrace, followed by an empty line.
|
||||
void Print() const;
|
||||
|
||||
u32 hash() const {
|
||||
// murmur2
|
||||
const u32 m = 0x5bd1e995;
|
||||
const u32 seed = 0x9747b28c;
|
||||
const u32 r = 24;
|
||||
u32 h = seed ^ (size * sizeof(uptr));
|
||||
for (uptr i = 0; i < size; i++) {
|
||||
u32 k = trace[i];
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
h *= m;
|
||||
h ^= k;
|
||||
}
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
return h;
|
||||
}
|
||||
bool is_valid() const { return size > 0 && trace; }
|
||||
|
||||
static bool WillUseFastUnwind(bool request_fast_unwind) {
|
||||
// Check if fast unwind is available. Fast unwind is the only option on Mac.
|
||||
// It is also the only option on FreeBSD as the slow unwinding that
|
||||
|
Loading…
x
Reference in New Issue
Block a user