[llvm-commits] [compiler-rt] r162897 - in /compiler-rt/trunk/lib/sanitizer_common: sanitizer_mutex.h sanitizer_stackdepot.cc sanitizer_stackdepot.h tests/sanitizer_stackdepot_test.cc
Dmitry Vyukov
dvyukov at google.com
Thu Aug 30 03:02:48 PDT 2012
Author: dvyukov
Date: Thu Aug 30 05:02:48 2012
New Revision: 162897
URL: http://llvm.org/viewvc/llvm-project?rev=162897&view=rev
Log:
asan/tsan: first version of "stack depot"
Added:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.h
compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h?rev=162897&r1=162896&r2=162897&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h Thu Aug 30 05:02:48 2012
@@ -20,9 +20,9 @@
namespace __sanitizer {
-class SpinMutex {
+class StaticSpinMutex {
public:
- SpinMutex() {
+ void Init() {
atomic_store(&state_, 0, memory_order_relaxed);
}
@@ -50,7 +50,15 @@
return;
}
}
+};
+class SpinMutex : public StaticSpinMutex {
+ public:
+ SpinMutex() {
+ Init();
+ }
+
+ private:
SpinMutex(const SpinMutex&);
void operator=(const SpinMutex&);
};
@@ -93,7 +101,7 @@
void operator=(const GenericScopedReadLock&);
};
-typedef GenericScopedLock<SpinMutex> SpinMutexLock;
+typedef GenericScopedLock<StaticSpinMutex> SpinMutexLock;
} // namespace __sanitizer
Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.cc?rev=162897&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.cc Thu Aug 30 05:02:48 2012
@@ -0,0 +1,87 @@
+//===-- sanitizer_stackdepot.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 shared between AddressSanitizer and ThreadSanitizer
+// run-time libraries.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_stackdepot.h"
+#include "sanitizer_common.h"
+#include "sanitizer_mutex.h"
+
+namespace __sanitizer {
+
+struct StackDesc {
+ StackDesc *link;
+ u32 id;
+ uptr hash;
+ uptr size;
+ uptr stack[1];
+};
+
+static struct {
+ StaticSpinMutex mtx;
+ StackDesc *head;
+ u8 *region_pos;
+ u8 *region_end;
+ u32 seq;
+} depot;
+
+static uptr hash(uptr *stack, uptr size) {
+ return 0;
+}
+
+static StackDesc *allocDesc(uptr size) {
+ uptr memsz = sizeof(StackDesc) + (size - 1) * sizeof(uptr);
+ if (depot.region_pos + memsz > depot.region_end) {
+ uptr allocsz = 64*1024;
+ if (allocsz < memsz)
+ allocsz = memsz;
+ depot.region_pos = (u8*)MmapOrDie(allocsz, "stack depot");
+ depot.region_end = depot.region_pos + allocsz;
+ }
+ StackDesc *s = (StackDesc*)depot.region_pos;
+ depot.region_pos += memsz;
+ return s;
+}
+
+u32 StackDepotPut(uptr *stack, uptr size) {
+ if (stack == 0 || size == 0)
+ return 0;
+ uptr h = hash(stack, size);
+ SpinMutexLock l(&depot.mtx);
+ for (StackDesc *s = depot.head; s; s = s->link) {
+ if (s->hash == h && s->size == size
+ && internal_memcmp(s->stack, stack, size * sizeof(uptr)) == 0)
+ return s->id;
+ }
+ StackDesc *s = allocDesc(size);
+ s->id = ++depot.seq;
+ s->hash = h;
+ s->size = size;
+ internal_memcpy(s->stack, stack, size * sizeof(uptr));
+ s->link = depot.head;
+ depot.head = s;
+ return s->id;
+}
+
+uptr *StackDepotGet(u32 id, uptr *size) {
+ if (id == 0)
+ return 0;
+ SpinMutexLock l(&depot.mtx);
+ for (StackDesc *s = depot.head; s; s = s->link) {
+ if (s->id == id) {
+ *size = s->size;
+ return s->stack;
+ }
+ }
+ return 0;
+}
+
+} // namespace __sanitizer
Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.h?rev=162897&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.h (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stackdepot.h Thu Aug 30 05:02:48 2012
@@ -0,0 +1,29 @@
+//===-- sanitizer_stackdepot.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 AddressSanitizer and ThreadSanitizer
+// run-time libraries.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_STACKDEPOT_H
+#define SANITIZER_STACKDEPOT_H
+
+#include "sanitizer/common_interface_defs.h"
+
+namespace __sanitizer {
+
+// StackDepot efficiently stores huge amounts of stack traces.
+
+// Maps stack trace to an unique id.
+u32 StackDepotPut(uptr *stack, uptr size);
+// Retrieves a stored stack trace by the id.
+uptr *StackDepotGet(u32 id, uptr *size);
+
+} // namespace __sanitizer
+
+#endif // SANITIZER_STACKDEPOT_H
Added: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc?rev=162897&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc Thu Aug 30 05:02:48 2012
@@ -0,0 +1,63 @@
+//===-- sanitizer_stackdepot_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/AddressSanitizer runtime.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_stackdepot.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "sanitizer_common/sanitizer_libc.h"
+#include "gtest/gtest.h"
+
+namespace __sanitizer {
+
+TEST(SanitizerCommon, StackDepotBasic) {
+ uptr s1[] = {1, 2, 3, 4, 5};
+ u32 i1 = StackDepotPut(s1, ARRAY_SIZE(s1));
+ uptr sz1 = 0;
+ uptr *sp1 = StackDepotGet(i1, &sz1);
+ EXPECT_NE(sp1, (uptr*)0);
+ EXPECT_EQ(sz1, ARRAY_SIZE(s1));
+ EXPECT_EQ(internal_memcmp(sp1?:s1, s1, sizeof(s1)), 0);
+}
+
+TEST(SanitizerCommon, StackDepotAbsent) {
+ uptr sz1 = 0;
+ uptr *sp1 = StackDepotGet(-10, &sz1);
+ EXPECT_EQ(sp1, (uptr*)0);
+}
+
+TEST(SanitizerCommon, StackDepotZero) {
+ u32 i1 = StackDepotPut(0, 0);
+ uptr sz1 = 0;
+ uptr *sp1 = StackDepotGet(i1, &sz1);
+ EXPECT_EQ(sp1, (uptr*)0);
+}
+
+TEST(SanitizerCommon, StackDepotSame) {
+ uptr s1[] = {1, 2, 3, 4, 6};
+ u32 i1 = StackDepotPut(s1, ARRAY_SIZE(s1));
+ u32 i2 = StackDepotPut(s1, ARRAY_SIZE(s1));
+ EXPECT_EQ(i1, i2);
+ uptr sz1 = 0;
+ uptr *sp1 = StackDepotGet(i1, &sz1);
+ EXPECT_NE(sp1, (uptr*)0);
+ EXPECT_EQ(sz1, ARRAY_SIZE(s1));
+ EXPECT_EQ(internal_memcmp(sp1?:s1, s1, sizeof(s1)), 0);
+}
+
+TEST(SanitizerCommon, StackDepotSeveral) {
+ uptr s1[] = {1, 2, 3, 4, 7};
+ u32 i1 = StackDepotPut(s1, ARRAY_SIZE(s1));
+ uptr s2[] = {1, 2, 3, 4, 8, 9};
+ u32 i2 = StackDepotPut(s2, ARRAY_SIZE(s2));
+ EXPECT_NE(i1, i2);
+}
+
+} // namespace __sanitizer
More information about the llvm-commits
mailing list