Skip to content

Commit 99dc683

Browse files
committed
[NFC][lsan] Use hash table to track root regions
This avoid O(N) in __lsan_unregister_root_region. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D151784
1 parent 0375a2d commit 99dc683

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

compiler-rt/lib/lsan/lsan_common.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,6 @@ static LeakSuppressionContext *GetSuppressionContext() {
241241
return suppression_ctx;
242242
}
243243

244-
static InternalMmapVectorNoCtor<Region> root_regions;
245-
246244
void InitCommonLsan() {
247245
if (common_flags()->detect_leaks) {
248246
// Initialization which can fail or print warnings should only be done if
@@ -523,15 +521,33 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
523521

524522
# endif // SANITIZER_FUCHSIA
525523

526-
bool HasRootRegions() { return !root_regions.empty(); }
524+
// A map that contains [region_begin, region_end) pairs.
525+
using RootRegions = DenseMap<detail::DenseMapPair<uptr, uptr>, uptr>;
526+
527+
static RootRegions &GetRootRegionsLocked() {
528+
global_mutex.CheckLocked();
529+
static RootRegions *regions = nullptr;
530+
alignas(RootRegions) static char placeholder[sizeof(RootRegions)];
531+
if (!regions)
532+
regions = new (placeholder) RootRegions();
533+
return *regions;
534+
}
535+
536+
bool HasRootRegions() { return !GetRootRegionsLocked().empty(); }
527537

528538
void ScanRootRegions(Frontier *frontier,
529539
const InternalMmapVectorNoCtor<Region> &mapped_regions) {
530540
if (!flags()->use_root_regions)
531541
return;
532542

543+
InternalMmapVector<Region> regions;
544+
GetRootRegionsLocked().forEach([&](const auto &kv) {
545+
regions.push_back({kv.first.first, kv.first.second});
546+
return true;
547+
});
548+
533549
InternalMmapVector<Region> intersection;
534-
Intersect(mapped_regions, root_regions, intersection);
550+
Intersect(mapped_regions, regions, intersection);
535551

536552
for (const Region &r : intersection) {
537553
LOG_POINTERS("Root region intersects with mapped region at %p-%p\n",
@@ -1011,7 +1027,7 @@ void __lsan_register_root_region(const void *begin, uptr size) {
10111027
CHECK_LT(b, e);
10121028

10131029
Lock l(&global_mutex);
1014-
root_regions.push_back({b, e});
1030+
++GetRootRegionsLocked()[{b, e}];
10151031
#endif // CAN_SANITIZE_LEAKS
10161032
}
10171033

@@ -1021,18 +1037,14 @@ void __lsan_unregister_root_region(const void *begin, uptr size) {
10211037
uptr b = reinterpret_cast<uptr>(begin);
10221038
uptr e = b + size;
10231039
CHECK_LT(b, e);
1040+
VReport(1, "Unregistered root region at %p of size %zu\n", begin, size);
10241041

10251042
{
10261043
Lock l(&global_mutex);
1027-
for (uptr i = 0; i < root_regions.size(); i++) {
1028-
Region region = root_regions[i];
1029-
if (region.begin == b && region.end == e) {
1030-
uptr last_index = root_regions.size() - 1;
1031-
root_regions[i] = root_regions[last_index];
1032-
root_regions.pop_back();
1033-
VReport(1, "Unregistered root region at %p of size %zu\n", begin, size);
1034-
return;
1035-
}
1044+
if (auto *f = GetRootRegionsLocked().find({b, e})) {
1045+
if (--(f->second) == 0)
1046+
GetRootRegionsLocked().erase(f);
1047+
return;
10361048
}
10371049
}
10381050
Report(

0 commit comments

Comments
 (0)