Skip to content

Commit fc3a260

Browse files
committed
[sanitizer] Don't lock for StackStore::Allocated()
1 parent 7151c71 commit fc3a260

File tree

2 files changed

+43
-47
lines changed

2 files changed

+43
-47
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ StackTrace StackStore::Load(Id id) {
5656
uptr idx = IdToOffset(id);
5757
uptr block_idx = GetBlockIdx(idx);
5858
CHECK_LT(block_idx, ARRAY_SIZE(blocks_));
59-
const uptr *stack_trace = blocks_[block_idx].GetOrUnpack();
59+
const uptr *stack_trace = blocks_[block_idx].GetOrUnpack(this);
6060
if (!stack_trace)
6161
return {};
6262
stack_trace += GetInBlockIdx(idx);
@@ -65,11 +65,7 @@ StackTrace StackStore::Load(Id id) {
6565
}
6666

6767
uptr StackStore::Allocated() const {
68-
uptr next_block = GetBlockIdx(
69-
RoundUpTo(atomic_load_relaxed(&total_frames_), kBlockSizeFrames));
70-
uptr res = 0;
71-
for (uptr i = 0; i < next_block; ++i) res += blocks_[i].Allocated();
72-
return res + sizeof(*this);
68+
return atomic_load_relaxed(&allocated_) + sizeof(*this);
7369
}
7470

7571
uptr *StackStore::Alloc(uptr count, uptr *idx, uptr *pack) {
@@ -83,7 +79,7 @@ uptr *StackStore::Alloc(uptr count, uptr *idx, uptr *pack) {
8379
// Fits into the a single block.
8480
CHECK_LT(block_idx, ARRAY_SIZE(blocks_));
8581
*idx = start;
86-
return blocks_[block_idx].GetOrCreate() + GetInBlockIdx(start);
82+
return blocks_[block_idx].GetOrCreate(this) + GetInBlockIdx(start);
8783
}
8884

8985
// Retry. We can't use range allocated in two different blocks.
@@ -96,14 +92,24 @@ uptr *StackStore::Alloc(uptr count, uptr *idx, uptr *pack) {
9692
}
9793
}
9894

95+
void *StackStore::Map(uptr size, const char *mem_type) {
96+
atomic_fetch_add(&allocated_, size, memory_order_relaxed);
97+
return MmapNoReserveOrDie(size, mem_type);
98+
}
99+
100+
void StackStore::Unmap(void *addr, uptr size) {
101+
atomic_fetch_sub(&allocated_, size, memory_order_relaxed);
102+
UnmapOrDie(addr, size);
103+
}
104+
99105
uptr StackStore::Pack(Compression type) {
100106
uptr res = 0;
101-
for (BlockInfo &b : blocks_) res += b.Pack(type);
107+
for (BlockInfo &b : blocks_) res += b.Pack(type, this);
102108
return res;
103109
}
104110

105111
void StackStore::TestOnlyUnmap() {
106-
for (BlockInfo &b : blocks_) b.TestOnlyUnmap();
112+
for (BlockInfo &b : blocks_) b.TestOnlyUnmap(this);
107113
internal_memset(this, 0, sizeof(*this));
108114
}
109115

@@ -114,22 +120,21 @@ uptr *StackStore::BlockInfo::Get() const {
114120
return reinterpret_cast<uptr *>(atomic_load_relaxed(&data_));
115121
}
116122

117-
uptr *StackStore::BlockInfo::Create() {
123+
uptr *StackStore::BlockInfo::Create(StackStore *store) {
118124
SpinMutexLock l(&mtx_);
119125
uptr *ptr = Get();
120126
if (!ptr) {
121-
ptr = reinterpret_cast<uptr *>(
122-
MmapNoReserveOrDie(kBlockSizeBytes, "StackStore"));
127+
ptr = reinterpret_cast<uptr *>(store->Map(kBlockSizeBytes, "StackStore"));
123128
atomic_store(&data_, reinterpret_cast<uptr>(ptr), memory_order_release);
124129
}
125130
return ptr;
126131
}
127132

128-
uptr *StackStore::BlockInfo::GetOrCreate() {
133+
uptr *StackStore::BlockInfo::GetOrCreate(StackStore *store) {
129134
uptr *ptr = Get();
130135
if (LIKELY(ptr))
131136
return ptr;
132-
return Create();
137+
return Create(store);
133138
}
134139

135140
class SLeb128Encoder {
@@ -229,7 +234,7 @@ struct PackedHeader {
229234
};
230235
} // namespace
231236

232-
uptr *StackStore::BlockInfo::GetOrUnpack() {
237+
uptr *StackStore::BlockInfo::GetOrUnpack(StackStore *store) {
233238
SpinMutexLock l(&mtx_);
234239
switch (state) {
235240
case State::Storing:
@@ -249,8 +254,8 @@ uptr *StackStore::BlockInfo::GetOrUnpack() {
249254

250255
uptr packed_size_aligned = RoundUpTo(header->size, GetPageSizeCached());
251256

252-
uptr *unpacked = reinterpret_cast<uptr *>(
253-
MmapNoReserveOrDie(kBlockSizeBytes, "StackStoreUnpack"));
257+
uptr *unpacked =
258+
reinterpret_cast<uptr *>(store->Map(kBlockSizeBytes, "StackStoreUnpack"));
254259

255260
uptr *unpacked_end;
256261
switch (header->type) {
@@ -271,13 +276,13 @@ uptr *StackStore::BlockInfo::GetOrUnpack() {
271276

272277
MprotectReadOnly(reinterpret_cast<uptr>(unpacked), kBlockSizeBytes);
273278
atomic_store(&data_, reinterpret_cast<uptr>(unpacked), memory_order_release);
274-
UnmapOrDie(ptr, packed_size_aligned);
279+
store->Unmap(ptr, packed_size_aligned);
275280

276281
state = State::Unpacked;
277282
return Get();
278283
}
279284

280-
uptr StackStore::BlockInfo::Pack(Compression type) {
285+
uptr StackStore::BlockInfo::Pack(Compression type, StackStore *store) {
281286
if (type == Compression::None)
282287
return 0;
283288

@@ -294,8 +299,8 @@ uptr StackStore::BlockInfo::Pack(Compression type) {
294299
if (!ptr || !Stored(0))
295300
return 0;
296301

297-
u8 *packed = reinterpret_cast<u8 *>(
298-
MmapNoReserveOrDie(kBlockSizeBytes, "StackStorePack"));
302+
u8 *packed =
303+
reinterpret_cast<u8 *>(store->Map(kBlockSizeBytes, "StackStorePack"));
299304
PackedHeader *header = reinterpret_cast<PackedHeader *>(packed);
300305
u8 *alloc_end = packed + kBlockSizeBytes;
301306

@@ -323,40 +328,26 @@ uptr StackStore::BlockInfo::Pack(Compression type) {
323328
if (kBlockSizeBytes - header->size < kBlockSizeBytes / 8) {
324329
VPrintf(1, "Undo and keep block unpacked\n");
325330
MprotectReadOnly(reinterpret_cast<uptr>(ptr), kBlockSizeBytes);
326-
UnmapOrDie(packed, kBlockSizeBytes);
331+
store->Unmap(packed, kBlockSizeBytes);
327332
state = State::Unpacked;
328333
return 0;
329334
}
330335

331336
uptr packed_size_aligned = RoundUpTo(header->size, GetPageSizeCached());
332-
UnmapOrDie(packed + packed_size_aligned,
333-
kBlockSizeBytes - packed_size_aligned);
337+
store->Unmap(packed + packed_size_aligned,
338+
kBlockSizeBytes - packed_size_aligned);
334339
MprotectReadOnly(reinterpret_cast<uptr>(packed), packed_size_aligned);
335340

336341
atomic_store(&data_, reinterpret_cast<uptr>(packed), memory_order_release);
337-
UnmapOrDie(ptr, kBlockSizeBytes);
342+
store->Unmap(ptr, kBlockSizeBytes);
338343

339344
state = State::Packed;
340345
return kBlockSizeBytes - packed_size_aligned;
341346
}
342347

343-
uptr StackStore::BlockInfo::Allocated() const {
344-
SpinMutexLock l(&mtx_);
345-
switch (state) {
346-
case State::Packed: {
347-
const PackedHeader *ptr = reinterpret_cast<const PackedHeader *>(Get());
348-
CHECK_NE(nullptr, ptr);
349-
return RoundUpTo(ptr->size, GetPageSizeCached());
350-
}
351-
case State::Unpacked:
352-
case State::Storing:
353-
return kBlockSizeBytes;
354-
}
355-
}
356-
357-
void StackStore::BlockInfo::TestOnlyUnmap() {
348+
void StackStore::BlockInfo::TestOnlyUnmap(StackStore *store) {
358349
if (uptr *ptr = Get())
359-
UnmapOrDie(ptr, kBlockSizeBytes);
350+
store->Unmap(ptr, kBlockSizeBytes);
360351
}
361352

362353
bool StackStore::BlockInfo::Stored(uptr n) {

compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,15 @@ class StackStore {
7272

7373
uptr *Alloc(uptr count, uptr *idx, uptr *pack);
7474

75+
void *Map(uptr size, const char *mem_type);
76+
void Unmap(void *addr, uptr size);
77+
7578
// Total number of allocated frames.
7679
atomic_uintptr_t total_frames_ = {};
7780

81+
// Tracks total allocated memory in bytes.
82+
atomic_uintptr_t allocated_ = {};
83+
7884
// Each block will hold pointer to exactly kBlockSizeFrames.
7985
class BlockInfo {
8086
atomic_uintptr_t data_;
@@ -90,15 +96,14 @@ class StackStore {
9096
};
9197
State state GUARDED_BY(mtx_);
9298

93-
uptr *Create();
99+
uptr *Create(StackStore *store);
94100

95101
public:
96102
uptr *Get() const;
97-
uptr *GetOrCreate();
98-
uptr *GetOrUnpack();
99-
uptr Pack(Compression type);
100-
uptr Allocated() const;
101-
void TestOnlyUnmap();
103+
uptr *GetOrCreate(StackStore *store);
104+
uptr *GetOrUnpack(StackStore *store);
105+
uptr Pack(Compression type, StackStore *store);
106+
void TestOnlyUnmap(StackStore *store);
102107
bool Stored(uptr n);
103108
bool IsPacked() const;
104109
};

0 commit comments

Comments
 (0)