Skip to content

Commit b91a5ea

Browse files
committedMar 20, 2017
Use pthreads for thread-local lsan allocator cache on darwin
Summary: This patch allows us to move away from using __thread on darwin, which is requiring for building lsan for darwin on ios version 7 and on iossim i386. Reviewers: kubamracek, kcc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D29994 llvm-svn: 298274
1 parent 89268b1 commit b91a5ea

File tree

4 files changed

+56
-44
lines changed

4 files changed

+56
-44
lines changed
 

‎compiler-rt/lib/lsan/lsan_allocator.cc

+8-43
Original file line numberDiff line numberDiff line change
@@ -24,53 +24,18 @@
2424
extern "C" void *memset(void *ptr, int value, uptr num);
2525

2626
namespace __lsan {
27-
28-
struct ChunkMetadata {
29-
u8 allocated : 8; // Must be first.
30-
ChunkTag tag : 2;
31-
#if SANITIZER_WORDSIZE == 64
32-
uptr requested_size : 54;
33-
#else
34-
uptr requested_size : 32;
35-
uptr padding : 22;
36-
#endif
37-
u32 stack_trace_id;
38-
};
39-
40-
#if defined(__mips64) || defined(__aarch64__) || defined(__i386__)
4127
#if defined(__i386__)
4228
static const uptr kMaxAllowedMallocSize = 1UL << 30;
43-
#else
29+
#elif defined(__mips64) || defined(__aarch64__)
4430
static const uptr kMaxAllowedMallocSize = 4UL << 30;
45-
#endif
46-
static const uptr kRegionSizeLog = 20;
47-
static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
48-
typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
49-
typedef CompactSizeClassMap SizeClassMap;
50-
typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE,
51-
sizeof(ChunkMetadata), SizeClassMap, kRegionSizeLog, ByteMap>
52-
PrimaryAllocator;
5331
#else
5432
static const uptr kMaxAllowedMallocSize = 8UL << 30;
55-
56-
struct AP64 { // Allocator64 parameters. Deliberately using a short name.
57-
static const uptr kSpaceBeg = 0x600000000000ULL;
58-
static const uptr kSpaceSize = 0x40000000000ULL; // 4T.
59-
static const uptr kMetadataSize = sizeof(ChunkMetadata);
60-
typedef DefaultSizeClassMap SizeClassMap;
61-
typedef NoOpMapUnmapCallback MapUnmapCallback;
62-
static const uptr kFlags = 0;
63-
};
64-
65-
typedef SizeClassAllocator64<AP64> PrimaryAllocator;
6633
#endif
67-
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
6834
typedef LargeMmapAllocator<> SecondaryAllocator;
6935
typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
7036
SecondaryAllocator> Allocator;
7137

7238
static Allocator allocator;
73-
static THREADLOCAL AllocatorCache cache;
7439

7540
void InitializeAllocator() {
7641
allocator.InitLinkerInitialized(
@@ -79,7 +44,7 @@ void InitializeAllocator() {
7944
}
8045

8146
void AllocatorThreadFinish() {
82-
allocator.SwallowCache(&cache);
47+
allocator.SwallowCache(GetAllocatorCache());
8348
}
8449

8550
static ChunkMetadata *Metadata(const void *p) {
@@ -111,7 +76,7 @@ void *Allocate(const StackTrace &stack, uptr size, uptr alignment,
11176
Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", size);
11277
return nullptr;
11378
}
114-
void *p = allocator.Allocate(&cache, size, alignment, false);
79+
void *p = allocator.Allocate(GetAllocatorCache(), size, alignment, false);
11580
// Do not rely on the allocator to clear the memory (it's slow).
11681
if (cleared && allocator.FromPrimary(p))
11782
memset(p, 0, size);
@@ -125,25 +90,25 @@ void Deallocate(void *p) {
12590
if (&__sanitizer_free_hook) __sanitizer_free_hook(p);
12691
RunFreeHooks(p);
12792
RegisterDeallocation(p);
128-
allocator.Deallocate(&cache, p);
93+
allocator.Deallocate(GetAllocatorCache(), p);
12994
}
13095

13196
void *Reallocate(const StackTrace &stack, void *p, uptr new_size,
13297
uptr alignment) {
13398
RegisterDeallocation(p);
13499
if (new_size > kMaxAllowedMallocSize) {
135100
Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", new_size);
136-
allocator.Deallocate(&cache, p);
101+
allocator.Deallocate(GetAllocatorCache(), p);
137102
return nullptr;
138103
}
139-
p = allocator.Reallocate(&cache, p, new_size, alignment);
104+
p = allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment);
140105
RegisterAllocation(stack, p, new_size);
141106
return p;
142107
}
143108

144109
void GetAllocatorCacheRange(uptr *begin, uptr *end) {
145-
*begin = (uptr)&cache;
146-
*end = *begin + sizeof(cache);
110+
*begin = (uptr)GetAllocatorCache();
111+
*end = *begin + sizeof(AllocatorCache);
147112
}
148113

149114
uptr GetMallocUsableSize(const void *p) {

‎compiler-rt/lib/lsan/lsan_allocator.h

+37
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
#ifndef LSAN_ALLOCATOR_H
1616
#define LSAN_ALLOCATOR_H
1717

18+
#include "sanitizer_common/sanitizer_allocator.h"
1819
#include "sanitizer_common/sanitizer_common.h"
1920
#include "sanitizer_common/sanitizer_internal_defs.h"
21+
#include "lsan_common.h"
2022

2123
namespace __lsan {
2224

@@ -34,6 +36,41 @@ void GetAllocatorCacheRange(uptr *begin, uptr *end);
3436
void AllocatorThreadFinish();
3537
void InitializeAllocator();
3638

39+
struct ChunkMetadata {
40+
u8 allocated : 8; // Must be first.
41+
ChunkTag tag : 2;
42+
#if SANITIZER_WORDSIZE == 64
43+
uptr requested_size : 54;
44+
#else
45+
uptr requested_size : 32;
46+
uptr padding : 22;
47+
#endif
48+
u32 stack_trace_id;
49+
};
50+
51+
#if defined(__mips64) || defined(__aarch64__) || defined(__i386__)
52+
static const uptr kRegionSizeLog = 20;
53+
static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
54+
typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
55+
typedef CompactSizeClassMap SizeClassMap;
56+
typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE,
57+
sizeof(ChunkMetadata), SizeClassMap, kRegionSizeLog, ByteMap>
58+
PrimaryAllocator;
59+
#elif defined(__x86_64__)
60+
struct AP64 { // Allocator64 parameters. Deliberately using a short name.
61+
static const uptr kSpaceBeg = 0x600000000000ULL;
62+
static const uptr kSpaceSize = 0x40000000000ULL; // 4T.
63+
static const uptr kMetadataSize = sizeof(ChunkMetadata);
64+
typedef DefaultSizeClassMap SizeClassMap;
65+
typedef NoOpMapUnmapCallback MapUnmapCallback;
66+
static const uptr kFlags = 0;
67+
};
68+
69+
typedef SizeClassAllocator64<AP64> PrimaryAllocator;
70+
#endif
71+
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
72+
73+
AllocatorCache *GetAllocatorCache();
3774
} // namespace __lsan
3875

3976
#endif // LSAN_ALLOCATOR_H

‎compiler-rt/lib/lsan/lsan_common_linux.cc

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "sanitizer_common/sanitizer_flags.h"
2323
#include "sanitizer_common/sanitizer_linux.h"
2424
#include "sanitizer_common/sanitizer_stackdepot.h"
25+
#include "lsan_allocator.h"
2526

2627
namespace __lsan {
2728

@@ -38,6 +39,9 @@ static THREADLOCAL u32 current_thread_tid = kInvalidTid;
3839
u32 GetCurrentThread() { return current_thread_tid; }
3940
void SetCurrentThread(u32 tid) { current_thread_tid = tid; }
4041

42+
static THREADLOCAL AllocatorCache allocator_cache;
43+
AllocatorCache *GetAllocatorCache() { return &allocator_cache; }
44+
4145
__attribute__((tls_model("initial-exec")))
4246
THREADLOCAL int disable_counter;
4347
bool DisabledInThisThread() { return disable_counter > 0; }

‎compiler-rt/lib/lsan/lsan_common_mac.cc

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,22 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
#include "sanitizer_common/sanitizer_allocator_internal.h"
1615
#include "sanitizer_common/sanitizer_platform.h"
1716
#include "lsan_common.h"
1817

1918
#if CAN_SANITIZE_LEAKS && SANITIZER_MAC
2019

20+
#include "sanitizer_common/sanitizer_allocator_internal.h"
21+
#include "lsan_allocator.h"
22+
2123
#include <pthread.h>
2224

2325
namespace __lsan {
2426

2527
typedef struct {
2628
int disable_counter;
2729
u32 current_thread_id;
30+
AllocatorCache cache;
2831
} thread_local_data_t;
2932

3033
static pthread_key_t key;
@@ -40,6 +43,7 @@ static thread_local_data_t *get_tls_val() {
4043
ptr = (thread_local_data_t *)InternalAlloc(sizeof(*ptr));
4144
ptr->disable_counter = 0;
4245
ptr->current_thread_id = kInvalidTid;
46+
ptr->cache = AllocatorCache();
4347
pthread_setspecific(key, ptr);
4448
}
4549

@@ -62,6 +66,8 @@ u32 GetCurrentThread() { return get_tls_val()->current_thread_id; }
6266

6367
void SetCurrentThread(u32 tid) { get_tls_val()->current_thread_id = tid; }
6468

69+
AllocatorCache *GetAllocatorCache() { return &get_tls_val()->cache; }
70+
6571
void InitializePlatformSpecificModules() {
6672
CHECK(0 && "unimplemented");
6773
}

0 commit comments

Comments
 (0)
Please sign in to comment.