summaryrefslogtreecommitdiff
path: root/lib/ubsan/ubsan_type_hash.cc
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-10-17 22:51:04 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-10-17 22:51:04 +0000
commit0c46cdebe103e5745a3b7be0b8c9c454a06bcccb (patch)
tree6692241ff390603638477c7ca0e8269f3eed9608 /lib/ubsan/ubsan_type_hash.cc
parent8e22b68ce64e34d3fc90f02d967bcceb279f3302 (diff)
Make the big array in the UBSan C++ runtime be zero-initialized to dramatically
shrink the binary size of the ubsan runtime. Also fix a bug where long-running processes could eventually trigger a crash in the runtime by filling up the cache. I've not found a nice way to add a test for this crasher; ideas welcome. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192931 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ubsan/ubsan_type_hash.cc')
-rw-r--r--lib/ubsan/ubsan_type_hash.cc16
1 files changed, 9 insertions, 7 deletions
diff --git a/lib/ubsan/ubsan_type_hash.cc b/lib/ubsan/ubsan_type_hash.cc
index b27aefc16..a388bcc6d 100644
--- a/lib/ubsan/ubsan_type_hash.cc
+++ b/lib/ubsan/ubsan_type_hash.cc
@@ -85,16 +85,18 @@ namespace abi = __cxxabiv1;
// reused as needed. The second caching layer is a large hash table with open
// chaining. We can freely evict from either layer since this is just a cache.
//
-// FIXME: Make these hash table accesses thread-safe. The races here are benign
-// (worst-case, we could miss a bug or see a slowdown) but we should
-// avoid upsetting race detectors.
+// FIXME: Make these hash table accesses thread-safe. The races here are benign:
+// assuming the unsequenced loads and stores don't misbehave too badly,
+// the worst case is false negatives or poor cache behavior, not false
+// positives or crashes.
/// Find a bucket to store the given hash value in.
static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
static const unsigned HashTableSize = 65537;
- static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize] = { 1 };
+ static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize];
- unsigned Probe = V & 65535;
+ unsigned First = (V & 65535) ^ 1;
+ unsigned Probe = First;
for (int Tries = 5; Tries; --Tries) {
if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)
return &__ubsan_vptr_hash_set[Probe];
@@ -104,12 +106,12 @@ static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
}
// FIXME: Pick a random entry from the probe sequence to evict rather than
// just taking the first.
- return &__ubsan_vptr_hash_set[V];
+ return &__ubsan_vptr_hash_set[First];
}
/// A cache of recently-checked hashes. Mini hash table with "random" evictions.
__ubsan::HashValue
-__ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize] = { 1 };
+__ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize];
/// \brief Determine whether \p Derived has a \p Base base class subobject at
/// offset \p Offset.