From 5551897294887d632c71275cf11c5654fd80cda7 Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Mon, 4 Dec 2017 12:30:09 +0000 Subject: Move __tsan::Vector to __sanitizer Summary: The low-fat STL-like vector container will be reused in MSan. It is needed to implement an atexit(3) interceptor on NetBSD/amd64 in MSan. Sponsored by Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc Reviewed By: dvyukov Subscribers: kubamracek, mgorny, llvm-commits, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D40726 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@319650 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/CMakeLists.txt | 1 + lib/sanitizer_common/sanitizer_vector.h | 125 ++++++++++++++++++++ lib/sanitizer_common/tests/CMakeLists.txt | 3 +- .../tests/sanitizer_vector_test.cc | 42 +++++++ lib/tsan/CMakeLists.txt | 3 +- lib/tsan/rtl/tsan_interceptors.cc | 2 +- lib/tsan/rtl/tsan_interface_ann.cc | 6 +- lib/tsan/rtl/tsan_report.cc | 14 +-- lib/tsan/rtl/tsan_report.h | 2 +- lib/tsan/rtl/tsan_rtl.cc | 6 +- lib/tsan/rtl/tsan_rtl.h | 3 +- lib/tsan/rtl/tsan_rtl_report.cc | 4 +- lib/tsan/rtl/tsan_rtl_thread.cc | 2 +- lib/tsan/rtl/tsan_vector.h | 127 --------------------- lib/tsan/tests/unit/CMakeLists.txt | 3 +- lib/tsan/tests/unit/tsan_vector_test.cc | 43 ------- 16 files changed, 192 insertions(+), 194 deletions(-) create mode 100644 lib/sanitizer_common/sanitizer_vector.h create mode 100644 lib/sanitizer_common/tests/sanitizer_vector_test.cc delete mode 100644 lib/tsan/rtl/tsan_vector.h delete mode 100644 lib/tsan/tests/unit/tsan_vector_test.cc (limited to 'lib') diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt index db077b565..60caa5c4f 100644 --- a/lib/sanitizer_common/CMakeLists.txt +++ b/lib/sanitizer_common/CMakeLists.txt @@ -140,6 +140,7 @@ set(SANITIZER_HEADERS sanitizer_syscall_linux_x86_64.inc sanitizer_syscall_linux_aarch64.inc sanitizer_thread_registry.h + sanitizer_vector.h sanitizer_win.h) include_directories(..) diff --git a/lib/sanitizer_common/sanitizer_vector.h b/lib/sanitizer_common/sanitizer_vector.h new file mode 100644 index 000000000..25cfeed35 --- /dev/null +++ b/lib/sanitizer_common/sanitizer_vector.h @@ -0,0 +1,125 @@ +//===-- sanitizer_vector.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between sanitizers run-time libraries. +// +//===----------------------------------------------------------------------===// + +// Low-fat STL-like vector container. + +#ifndef SANITIZER_VECTOR_H +#define SANITIZER_VECTOR_H + +#include "sanitizer_common/sanitizer_allocator_internal.h" +#include "sanitizer_common/sanitizer_libc.h" + +namespace __sanitizer { + +template +class Vector { + public: + explicit Vector() + : begin_() + , end_() + , last_() { + } + + ~Vector() { + if (begin_) + InternalFree(begin_); + } + + void Reset() { + if (begin_) + InternalFree(begin_); + begin_ = 0; + end_ = 0; + last_ = 0; + } + + uptr Size() const { + return end_ - begin_; + } + + T &operator[](uptr i) { + DCHECK_LT(i, end_ - begin_); + return begin_[i]; + } + + const T &operator[](uptr i) const { + DCHECK_LT(i, end_ - begin_); + return begin_[i]; + } + + T *PushBack() { + EnsureSize(Size() + 1); + T *p = &end_[-1]; + internal_memset(p, 0, sizeof(*p)); + return p; + } + + T *PushBack(const T& v) { + EnsureSize(Size() + 1); + T *p = &end_[-1]; + internal_memcpy(p, &v, sizeof(*p)); + return p; + } + + void PopBack() { + DCHECK_GT(end_, begin_); + end_--; + } + + void Resize(uptr size) { + if (size == 0) { + end_ = begin_; + return; + } + uptr old_size = Size(); + EnsureSize(size); + if (old_size < size) { + for (uptr i = old_size; i < size; i++) + internal_memset(&begin_[i], 0, sizeof(begin_[i])); + } + } + + private: + T *begin_; + T *end_; + T *last_; + + void EnsureSize(uptr size) { + if (size <= Size()) + return; + if (size <= (uptr)(last_ - begin_)) { + end_ = begin_ + size; + return; + } + uptr cap0 = last_ - begin_; + uptr cap = cap0 * 5 / 4; // 25% growth + if (cap == 0) + cap = 16; + if (cap < size) + cap = size; + T *p = (T*)InternalAlloc(cap * sizeof(T)); + if (cap0) { + internal_memcpy(p, begin_, cap0 * sizeof(T)); + InternalFree(begin_); + } + begin_ = p; + end_ = begin_ + size; + last_ = begin_ + cap; + } + + Vector(const Vector&); + void operator=(const Vector&); +}; +} // namespace __sanitizer + +#endif // #ifndef SANITIZER_VECTOR_H diff --git a/lib/sanitizer_common/tests/CMakeLists.txt b/lib/sanitizer_common/tests/CMakeLists.txt index 2e55257da..1bccaa78f 100644 --- a/lib/sanitizer_common/tests/CMakeLists.txt +++ b/lib/sanitizer_common/tests/CMakeLists.txt @@ -34,7 +34,8 @@ set(SANITIZER_UNITTESTS sanitizer_suppressions_test.cc sanitizer_symbolizer_test.cc sanitizer_test_main.cc - sanitizer_thread_registry_test.cc) + sanitizer_thread_registry_test.cc + sanitizer_vector_test.cc) set(SANITIZER_TEST_HEADERS sanitizer_pthread_wrappers.h diff --git a/lib/sanitizer_common/tests/sanitizer_vector_test.cc b/lib/sanitizer_common/tests/sanitizer_vector_test.cc new file mode 100644 index 000000000..33ed14e19 --- /dev/null +++ b/lib/sanitizer_common/tests/sanitizer_vector_test.cc @@ -0,0 +1,42 @@ +//===-- sanitizer_vector_test.cc ------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of *Sanitizer runtime. +// +//===----------------------------------------------------------------------===// +#include "sanitizer_common/sanitizer_vector.h" +#include "gtest/gtest.h" + +namespace __sanitizer { + +TEST(Vector, Basic) { + Vector v; + EXPECT_EQ(v.Size(), (uptr)0); + v.PushBack(42); + EXPECT_EQ(v.Size(), (uptr)1); + EXPECT_EQ(v[0], 42); + v.PushBack(43); + EXPECT_EQ(v.Size(), (uptr)2); + EXPECT_EQ(v[0], 42); + EXPECT_EQ(v[1], 43); +} + +TEST(Vector, Stride) { + Vector v; + for (int i = 0; i < 1000; i++) { + v.PushBack(i); + EXPECT_EQ(v.Size(), (uptr)(i + 1)); + EXPECT_EQ(v[i], i); + } + for (int i = 0; i < 1000; i++) { + EXPECT_EQ(v[i], i); + } +} + +} // namespace __sanitizer diff --git a/lib/tsan/CMakeLists.txt b/lib/tsan/CMakeLists.txt index 145cd623d..b85762bb8 100644 --- a/lib/tsan/CMakeLists.txt +++ b/lib/tsan/CMakeLists.txt @@ -93,8 +93,7 @@ set(TSAN_HEADERS rtl/tsan_symbolize.h rtl/tsan_sync.h rtl/tsan_trace.h - rtl/tsan_update_shadow_word_inl.h - rtl/tsan_vector.h) + rtl/tsan_update_shadow_word_inl.h) set(TSAN_RUNTIME_LIBRARIES) add_compiler_rt_component(tsan) diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index f3c354fa2..b6e869368 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -200,7 +200,7 @@ struct InterceptorContext { Vector AtExitStack; InterceptorContext() - : libignore(LINKER_INITIALIZED), AtExitStack(MBlockAtExit) { + : libignore(LINKER_INITIALIZED), AtExitStack() { } }; diff --git a/lib/tsan/rtl/tsan_interface_ann.cc b/lib/tsan/rtl/tsan_interface_ann.cc index f68a0468d..a7922a42e 100644 --- a/lib/tsan/rtl/tsan_interface_ann.cc +++ b/lib/tsan/rtl/tsan_interface_ann.cc @@ -14,6 +14,7 @@ #include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stacktrace.h" +#include "sanitizer_common/sanitizer_vector.h" #include "tsan_interface_ann.h" #include "tsan_mutex.h" #include "tsan_report.h" @@ -21,7 +22,6 @@ #include "tsan_mman.h" #include "tsan_flags.h" #include "tsan_platform.h" -#include "tsan_vector.h" #define CALLERPC ((uptr)__builtin_return_address(0)) @@ -185,10 +185,10 @@ void PrintMatchedBenignRaces() { int unique_count = 0; int hit_count = 0; int add_count = 0; - Vector hit_matched(MBlockScopedBuf); + Vector hit_matched; CollectMatchedBenignRaces(&hit_matched, &unique_count, &hit_count, &ExpectRace::hitcount); - Vector add_matched(MBlockScopedBuf); + Vector add_matched; CollectMatchedBenignRaces(&add_matched, &unique_count, &add_count, &ExpectRace::addcount); if (hit_matched.Size()) { diff --git a/lib/tsan/rtl/tsan_report.cc b/lib/tsan/rtl/tsan_report.cc index be5d6b7ea..af4707696 100644 --- a/lib/tsan/rtl/tsan_report.cc +++ b/lib/tsan/rtl/tsan_report.cc @@ -48,18 +48,18 @@ class Decorator: public __sanitizer::SanitizerCommonDecorator { ReportDesc::ReportDesc() : tag(kExternalTagNone) - , stacks(MBlockReportStack) - , mops(MBlockReportMop) - , locs(MBlockReportLoc) - , mutexes(MBlockReportMutex) - , threads(MBlockReportThread) - , unique_tids(MBlockReportThread) + , stacks() + , mops() + , locs() + , mutexes() + , threads() + , unique_tids() , sleep() , count() { } ReportMop::ReportMop() - : mset(MBlockReportMutex) { + : mset() { } ReportDesc::~ReportDesc() { diff --git a/lib/tsan/rtl/tsan_report.h b/lib/tsan/rtl/tsan_report.h index bc1582f90..cdc999c6a 100644 --- a/lib/tsan/rtl/tsan_report.h +++ b/lib/tsan/rtl/tsan_report.h @@ -14,8 +14,8 @@ #define TSAN_REPORT_H #include "sanitizer_common/sanitizer_symbolizer.h" +#include "sanitizer_common/sanitizer_vector.h" #include "tsan_defs.h" -#include "tsan_vector.h" namespace __tsan { diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc index 8e12fb67f..17b820977 100644 --- a/lib/tsan/rtl/tsan_rtl.cc +++ b/lib/tsan/rtl/tsan_rtl.cc @@ -102,8 +102,8 @@ Context::Context() , thread_registry(new(thread_registry_placeholder) ThreadRegistry( CreateThreadContext, kMaxTid, kThreadQuarantineSize, kMaxTidReuse)) , racy_mtx(MutexTypeRacy, StatMtxRacy) - , racy_stacks(MBlockRacyStacks) - , racy_addresses(MBlockRacyAddresses) + , racy_stacks() + , racy_addresses() , fired_suppressions_mtx(MutexTypeFired, StatMtxFired) , fired_suppressions(8) , clock_alloc("clock allocator") { @@ -121,7 +121,7 @@ ThreadState::ThreadState(Context *ctx, int tid, int unique_id, u64 epoch, // , ignore_interceptors() , clock(tid, reuse_count) #if !SANITIZER_GO - , jmp_bufs(MBlockJmpBuf) + , jmp_bufs() #endif , tid(tid) , unique_id(unique_id) diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h index 8967a4b52..7d44ccae9 100644 --- a/lib/tsan/rtl/tsan_rtl.h +++ b/lib/tsan/rtl/tsan_rtl.h @@ -34,12 +34,13 @@ #include "sanitizer_common/sanitizer_libignore.h" #include "sanitizer_common/sanitizer_suppressions.h" #include "sanitizer_common/sanitizer_thread_registry.h" +#include "sanitizer_common/sanitizer_vector.h" #include "tsan_clock.h" #include "tsan_defs.h" #include "tsan_flags.h" +#include "tsan_mman.h" #include "tsan_sync.h" #include "tsan_trace.h" -#include "tsan_vector.h" #include "tsan_report.h" #include "tsan_platform.h" #include "tsan_mutexset.h" diff --git a/lib/tsan/rtl/tsan_rtl_report.cc b/lib/tsan/rtl/tsan_rtl_report.cc index 37b276805..cc582ab50 100644 --- a/lib/tsan/rtl/tsan_rtl_report.cc +++ b/lib/tsan/rtl/tsan_rtl_report.cc @@ -393,7 +393,7 @@ void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk, const u64 ebegin = RoundDown(eend, kTracePartSize); DPrintf("#%d: RestoreStack epoch=%zu ebegin=%zu eend=%zu partidx=%d\n", tid, (uptr)epoch, (uptr)ebegin, (uptr)eend, partidx); - Vector stack(MBlockReportStack); + Vector stack; stack.Resize(hdr->stack0.size + 64); for (uptr i = 0; i < hdr->stack0.size; i++) { stack[i] = hdr->stack0.trace[i]; @@ -659,7 +659,7 @@ void ReportRace(ThreadState *thr) { return; // MutexSet is too large to live on stack. - Vector mset_buffer(MBlockScopedBuf); + Vector mset_buffer; mset_buffer.Resize(sizeof(MutexSet) / sizeof(u64) + 1); MutexSet *mset2 = new(&mset_buffer[0]) MutexSet(); diff --git a/lib/tsan/rtl/tsan_rtl_thread.cc b/lib/tsan/rtl/tsan_rtl_thread.cc index 83fab082a..e4d65b9a9 100644 --- a/lib/tsan/rtl/tsan_rtl_thread.cc +++ b/lib/tsan/rtl/tsan_rtl_thread.cc @@ -211,7 +211,7 @@ void ThreadFinalize(ThreadState *thr) { if (!flags()->report_thread_leaks) return; ThreadRegistryLock l(ctx->thread_registry); - Vector leaks(MBlockScopedBuf); + Vector leaks; ctx->thread_registry->RunCallbackForEachThreadLocked( MaybeReportThreadLeak, &leaks); for (uptr i = 0; i < leaks.Size(); i++) { diff --git a/lib/tsan/rtl/tsan_vector.h b/lib/tsan/rtl/tsan_vector.h deleted file mode 100644 index a7fb3fa58..000000000 --- a/lib/tsan/rtl/tsan_vector.h +++ /dev/null @@ -1,127 +0,0 @@ -//===-- tsan_vector.h -------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of ThreadSanitizer (TSan), a race detector. -// -//===----------------------------------------------------------------------===// - -// Low-fat STL-like vector container. - -#ifndef TSAN_VECTOR_H -#define TSAN_VECTOR_H - -#include "tsan_defs.h" -#include "tsan_mman.h" - -namespace __tsan { - -template -class Vector { - public: - explicit Vector(MBlockType typ) - : typ_(typ) - , begin_() - , end_() - , last_() { - } - - ~Vector() { - if (begin_) - internal_free(begin_); - } - - void Reset() { - if (begin_) - internal_free(begin_); - begin_ = 0; - end_ = 0; - last_ = 0; - } - - uptr Size() const { - return end_ - begin_; - } - - T &operator[](uptr i) { - DCHECK_LT(i, end_ - begin_); - return begin_[i]; - } - - const T &operator[](uptr i) const { - DCHECK_LT(i, end_ - begin_); - return begin_[i]; - } - - T *PushBack() { - EnsureSize(Size() + 1); - T *p = &end_[-1]; - internal_memset(p, 0, sizeof(*p)); - return p; - } - - T *PushBack(const T& v) { - EnsureSize(Size() + 1); - T *p = &end_[-1]; - internal_memcpy(p, &v, sizeof(*p)); - return p; - } - - void PopBack() { - DCHECK_GT(end_, begin_); - end_--; - } - - void Resize(uptr size) { - if (size == 0) { - end_ = begin_; - return; - } - uptr old_size = Size(); - EnsureSize(size); - if (old_size < size) { - for (uptr i = old_size; i < size; i++) - internal_memset(&begin_[i], 0, sizeof(begin_[i])); - } - } - - private: - const MBlockType typ_; - T *begin_; - T *end_; - T *last_; - - void EnsureSize(uptr size) { - if (size <= Size()) - return; - if (size <= (uptr)(last_ - begin_)) { - end_ = begin_ + size; - return; - } - uptr cap0 = last_ - begin_; - uptr cap = cap0 * 5 / 4; // 25% growth - if (cap == 0) - cap = 16; - if (cap < size) - cap = size; - T *p = (T*)internal_alloc(typ_, cap * sizeof(T)); - if (cap0) { - internal_memcpy(p, begin_, cap0 * sizeof(T)); - internal_free(begin_); - } - begin_ = p; - end_ = begin_ + size; - last_ = begin_ + cap; - } - - Vector(const Vector&); - void operator=(const Vector&); -}; -} // namespace __tsan - -#endif // #ifndef TSAN_VECTOR_H diff --git a/lib/tsan/tests/unit/CMakeLists.txt b/lib/tsan/tests/unit/CMakeLists.txt index 6898f641d..c08508d50 100644 --- a/lib/tsan/tests/unit/CMakeLists.txt +++ b/lib/tsan/tests/unit/CMakeLists.txt @@ -6,8 +6,7 @@ set(TSAN_UNIT_TEST_SOURCES tsan_shadow_test.cc tsan_stack_test.cc tsan_sync_test.cc - tsan_unit_test_main.cc - tsan_vector_test.cc) + tsan_unit_test_main.cc) add_tsan_unittest(TsanUnitTest SOURCES ${TSAN_UNIT_TEST_SOURCES}) diff --git a/lib/tsan/tests/unit/tsan_vector_test.cc b/lib/tsan/tests/unit/tsan_vector_test.cc deleted file mode 100644 index c54ac1ee6..000000000 --- a/lib/tsan/tests/unit/tsan_vector_test.cc +++ /dev/null @@ -1,43 +0,0 @@ -//===-- tsan_vector_test.cc -----------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of ThreadSanitizer (TSan), a race detector. -// -//===----------------------------------------------------------------------===// -#include "tsan_vector.h" -#include "tsan_rtl.h" -#include "gtest/gtest.h" - -namespace __tsan { - -TEST(Vector, Basic) { - Vector v(MBlockScopedBuf); - EXPECT_EQ(v.Size(), (uptr)0); - v.PushBack(42); - EXPECT_EQ(v.Size(), (uptr)1); - EXPECT_EQ(v[0], 42); - v.PushBack(43); - EXPECT_EQ(v.Size(), (uptr)2); - EXPECT_EQ(v[0], 42); - EXPECT_EQ(v[1], 43); -} - -TEST(Vector, Stride) { - Vector v(MBlockScopedBuf); - for (int i = 0; i < 1000; i++) { - v.PushBack(i); - EXPECT_EQ(v.Size(), (uptr)(i + 1)); - EXPECT_EQ(v[i], i); - } - for (int i = 0; i < 1000; i++) { - EXPECT_EQ(v[i], i); - } -} - -} // namespace __tsan -- cgit v1.2.3