diff options
author | Alexey Samsonov <vonosmas@gmail.com> | 2014-10-27 03:10:27 +0000 |
---|---|---|
committer | Alexey Samsonov <vonosmas@gmail.com> | 2014-10-27 03:10:27 +0000 |
commit | e853b4f2e42d80156272ebca58a8e92c79d2082a (patch) | |
tree | fb027654970ec7a66d4e3bdaadd80315bbd092a5 | |
parent | 18c89411b8c24883bc2d7e86a4ec40ebc8957b54 (diff) | |
download | bcm5719-llvm-e853b4f2e42d80156272ebca58a8e92c79d2082a.tar.gz bcm5719-llvm-e853b4f2e42d80156272ebca58a8e92c79d2082a.zip |
[Sanitizer] Return code that calculates hash for stacktrace back to StackDepot implementation
llvm-svn: 220663
4 files changed, 43 insertions, 42 deletions
diff --git a/compiler-rt/lib/msan/msan_chained_origin_depot.cc b/compiler-rt/lib/msan/msan_chained_origin_depot.cc index 8bc13980942..f3fb3c8fe5d 100644 --- a/compiler-rt/lib/msan/msan_chained_origin_depot.cc +++ b/compiler-rt/lib/msan/msan_chained_origin_depot.cc @@ -19,6 +19,21 @@ namespace __msan { struct ChainedOriginDepotDesc { u32 here_id; u32 prev_id; +}; + +struct ChainedOriginDepotNode { + ChainedOriginDepotNode *link; + u32 id; + u32 here_id; + u32 prev_id; + + typedef ChainedOriginDepotDesc args_type; + bool eq(u32 hash, const args_type &args) const { + return here_id == args.here_id && prev_id == args.prev_id; + } + 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). @@ -32,19 +47,19 @@ struct ChainedOriginDepotDesc { split, or one of two reserved values (-1) or (-2). Either case can dominate depending on the workload. */ - u32 hash() const { + static u32 hash(const args_type &args) { const u32 m = 0x5bd1e995; const u32 seed = 0x9747b28c; const u32 r = 24; u32 h = seed; - u32 k = here_id; + u32 k = args.here_id; k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; - k = prev_id; + k = args.prev_id; k *= m; k ^= k >> r; k *= m; @@ -56,22 +71,7 @@ struct ChainedOriginDepotDesc { h ^= h >> 15; return h; } - bool is_valid() { return true; } -}; - -struct ChainedOriginDepotNode { - ChainedOriginDepotNode *link; - u32 id; - u32 here_id; - u32 prev_id; - - typedef ChainedOriginDepotDesc args_type; - bool eq(u32 hash, const args_type &args) const { - return here_id == args.here_id && prev_id == args.prev_id; - } - static uptr storage_size(const args_type &args) { - return sizeof(ChainedOriginDepotNode); - } + 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; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cc index afd45ddd2e1..f10f1f973fd 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cc @@ -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; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h index d2d3d34980c..5de2e711fe4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h @@ -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); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h index a3d548804f9..4f613fad164 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h @@ -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 |