[PATCH] Change internal allocator in sanitizer tools
Alexey Samsonov
samsonov at google.com
Thu Apr 18 04:50:35 PDT 2013
Address comments by dvyukov@
Hi kcc,
http://llvm-reviews.chandlerc.com/D671
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D671?vs=1626&id=1683#toc
Files:
lib/tsan/rtl/tsan_platform_linux.cc
lib/sanitizer_common/sanitizer_allocator.cc
lib/sanitizer_common/tests/sanitizer_allocator_test.cc
lib/sanitizer_common/sanitizer_common.h
Index: lib/tsan/rtl/tsan_platform_linux.cc
===================================================================
--- lib/tsan/rtl/tsan_platform_linux.cc
+++ lib/tsan/rtl/tsan_platform_linux.cc
@@ -257,12 +257,15 @@
#ifndef TSAN_GO
static void CheckPIE() {
// Ensure that the binary is indeed compiled with -pie.
+ u64 internal_alloc_beg, internal_alloc_size;
+ GetInternalAllocatorLocation(&internal_alloc_beg, &internal_alloc_size);
MemoryMappingLayout proc_maps(true);
uptr start, end;
if (proc_maps.Next(&start, &end,
/*offset*/0, /*filename*/0, /*filename_size*/0,
/*protection*/0)) {
- if ((u64)start < kLinuxAppMemBeg) {
+ if ((u64)start < kLinuxAppMemBeg &&
+ (u64)start != internal_alloc_beg) {
Printf("FATAL: ThreadSanitizer can not mmap the shadow memory ("
"something is mapped at 0x%zx < 0x%zx)\n",
start, kLinuxAppMemBeg);
Index: lib/sanitizer_common/sanitizer_allocator.cc
===================================================================
--- lib/sanitizer_common/sanitizer_allocator.cc
+++ lib/sanitizer_common/sanitizer_allocator.cc
@@ -11,29 +11,86 @@
// run-time libraries.
// This allocator that is used inside run-times.
//===----------------------------------------------------------------------===//
+#include "sanitizer_allocator.h"
#include "sanitizer_common.h"
-// FIXME: We should probably use more low-level allocator that would
-// mmap some pages and split them into chunks to fulfill requests.
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
-extern "C" void *__libc_malloc(__sanitizer::uptr size);
+namespace __sanitizer {
+
+// ThreadSanitizer for Go uses libc malloc/free.
+#if SANITIZER_LINUX && defined(TSAN_GO)
+extern "C" void *__libc_malloc(uptr size);
extern "C" void __libc_free(void *ptr);
-# define LIBC_MALLOC __libc_malloc
-# define LIBC_FREE __libc_free
-#else // SANITIZER_LINUX && !SANITIZER_ANDROID
-# include <stdlib.h>
-# define LIBC_MALLOC malloc
-# define LIBC_FREE free
-#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
-namespace __sanitizer {
+static void *RawInternalAlloc(uptr size) {
+ return __libc_malloc(size);
+}
+static void RawInternalFree(void *ptr) {
+ __libc_free(ptr);
+}
+#else // SANITIZER_LINUX && defined(TSAN_GO)
+
+# if SANITIZER_WORDSIZE == 32
+typedef SizeClassAllocator32<0, (1ULL << 32), 16, CompactSizeClassMap>
+PrimaryAllocator;
+# else
+# if defined(__powerpc64__)
+static const uptr kInternalAllocatorSpace = 0x0d0000000000ULL;
+# else
+static const uptr kInternalAllocatorSpace = 0x690000000000ULL;
+# endif
+static const uptr kInternalAllocatorSize = 0x10000000000ULL; // 1T
+typedef SizeClassAllocator64<kInternalAllocatorSpace, kInternalAllocatorSize,
+ 0 /* metadata */, CompactSizeClassMap>
+PrimaryAllocator;
+# endif
+
+typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
+typedef LargeMmapAllocator<> SecondaryAllocator;
+typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
+ SecondaryAllocator> Allocator;
+
+static Allocator internal_allocator;
+static AllocatorCache internal_allocator_cache;
+static BlockingMutex internal_allocator_mu(LINKER_INITIALIZED);
+static bool internal_allocator_inited;
+
+static void *RawInternalAlloc(uptr size) {
+ BlockingMutexLock l(&internal_allocator_mu);
+ if (!internal_allocator_inited) {
+ internal_allocator.Init();
+ internal_allocator_inited = true;
+ }
+ return internal_allocator.Allocate(&internal_allocator_cache,
+ size, 8, false);
+}
+
+static void RawInternalFree(void *ptr) {
+ BlockingMutexLock l(&internal_allocator_mu);
+ CHECK(internal_allocator_inited);
+ internal_allocator.Deallocate(&internal_allocator_cache, ptr);
+}
+
+#endif // SANITIZER_LINUX && defined(TSAN_GO)
+
+void GetInternalAllocatorLocation(u64 *space, u64 *size) {
+#if defined(TSAN_GO)
+ *space = 0;
+ *size = 0;
+#elif SANITIZER_WORDSIZE == 64
+ *space = kInternalAllocatorSpace;
+ *size = kInternalAllocatorSize;
+#elif SANITIZER_WORDSIZE == 32
+ *space = 0;
+ *size = (1ULL << 32);
+#endif
+}
-const u64 kBlockMagic = 0x6A6CB03ABCEBC041ull;
+static const u64 kBlockMagic = 0x6A6CB03ABCEBC041ull;
void *InternalAlloc(uptr size) {
if (size + sizeof(u64) < size)
return 0;
- void *p = LIBC_MALLOC(size + sizeof(u64));
+ void *p = RawInternalAlloc(size + sizeof(u64));
if (p == 0)
return 0;
((u64*)p)[0] = kBlockMagic;
@@ -44,9 +101,9 @@
if (addr == 0)
return;
addr = (char*)addr - sizeof(u64);
- CHECK_EQ(((u64*)addr)[0], kBlockMagic);
+ CHECK_EQ(kBlockMagic, ((u64*)addr)[0]);
((u64*)addr)[0] = 0;
- LIBC_FREE(addr);
+ RawInternalFree(addr);
}
// LowLevelAllocator
Index: lib/sanitizer_common/tests/sanitizer_allocator_test.cc
===================================================================
--- lib/sanitizer_common/tests/sanitizer_allocator_test.cc
+++ lib/sanitizer_common/tests/sanitizer_allocator_test.cc
@@ -574,6 +574,19 @@
}
}
+TEST(Allocator, AllocatorLocationTest) {
+ u64 space, size;
+ GetInternalAllocatorLocation(&space, &size);
+ CHECK_GT(size, 0);
+ u64 end = space + size;
+ if (SANITIZER_WORDSIZE == 64) {
+ CHECK_GT(space, 0);
+ CHECK_LE(end, 0x800000000000ULL);
+ } else {
+ CHECK_LE(end, 0x100000000ULL);
+ }
+}
+
class IterationTestCallback {
public:
explicit IterationTestCallback(std::set<void *> *chunks)
Index: lib/sanitizer_common/sanitizer_common.h
===================================================================
--- lib/sanitizer_common/sanitizer_common.h
+++ lib/sanitizer_common/sanitizer_common.h
@@ -61,6 +61,9 @@
// Internal allocator
void *InternalAlloc(uptr size);
void InternalFree(void *p);
+// Use this to make sure tool mappings doesn't overlap with memory reserved
+// for internal allocator.
+void GetInternalAllocatorLocation(u64 *space, u64 *size);
// InternalScopedBuffer can be used instead of large stack arrays to
// keep frame size low.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D671.2.patch
Type: text/x-patch
Size: 6032 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130418/5f62bda7/attachment.bin>
More information about the llvm-commits
mailing list