Skip to content

Commit 0375a2d

Browse files
committed
[NFC][sanitizer] Avoid O(N^2) algorithm
Usually root_regions size is small so unlikey this change will provide a noticable difference. However it's easy to make sure that even with large number of root_regions it works reasonably fast. Differential Revision: https://reviews.llvm.org/D151781
1 parent c42e555 commit 0375a2d

File tree

2 files changed

+12
-30
lines changed

2 files changed

+12
-30
lines changed

compiler-rt/lib/lsan/lsan_common.cpp

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -525,30 +525,19 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
525525

526526
bool HasRootRegions() { return !root_regions.empty(); }
527527

528-
static void ScanRootRegion(Frontier *frontier, const Region &root_region,
529-
uptr region_begin, uptr region_end,
530-
bool is_readable) {
531-
uptr intersection_begin = Max(root_region.begin, region_begin);
532-
uptr intersection_end = Min(region_end, root_region.end);
533-
if (intersection_begin >= intersection_end)
534-
return;
535-
LOG_POINTERS("Root region %p-%p intersects with mapped region %p-%p (%s)\n",
536-
(void *)root_region.begin, (void *)root_region.end,
537-
(void *)region_begin, (void *)region_end,
538-
is_readable ? "readable" : "unreadable");
539-
if (is_readable)
540-
ScanRangeForPointers(intersection_begin, intersection_end, frontier, "ROOT",
541-
kReachable);
542-
}
543-
544528
void ScanRootRegions(Frontier *frontier,
545529
const InternalMmapVectorNoCtor<Region> &mapped_regions) {
546-
if (!flags()->use_root_regions || mapped_regions.empty())
530+
if (!flags()->use_root_regions)
547531
return;
548532

549-
for (const auto &m : mapped_regions)
550-
for (const auto &r : root_regions)
551-
ScanRootRegion(frontier, r, m.begin, m.end, true);
533+
InternalMmapVector<Region> intersection;
534+
Intersect(mapped_regions, root_regions, intersection);
535+
536+
for (const Region &r : intersection) {
537+
LOG_POINTERS("Root region intersects with mapped region at %p-%p\n",
538+
(void *)r.begin, (void *)r.end);
539+
ScanRangeForPointers(r.begin, r.end, frontier, "ROOT", kReachable);
540+
}
552541
}
553542

554543
// Scans root regions for heap pointers.

compiler-rt/lib/lsan/lsan_common.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "sanitizer_common/sanitizer_allocator.h"
1818
#include "sanitizer_common/sanitizer_common.h"
19+
#include "sanitizer_common/sanitizer_common_range.h"
1920
#include "sanitizer_common/sanitizer_internal_defs.h"
2021
#include "sanitizer_common/sanitizer_platform.h"
2122
#include "sanitizer_common/sanitizer_stackdepot.h"
@@ -79,11 +80,6 @@ enum IgnoreObjectResult {
7980
kIgnoreObjectInvalid
8081
};
8182

82-
struct Range {
83-
uptr begin;
84-
uptr end;
85-
};
86-
8783
//// --------------------------------------------------------------------------
8884
//// Poisoning prototypes.
8985
//// --------------------------------------------------------------------------
@@ -239,11 +235,6 @@ void InitializePlatformSpecificModules();
239235
void ProcessGlobalRegions(Frontier *frontier);
240236
void ProcessPlatformSpecificAllocations(Frontier *frontier);
241237

242-
struct Region {
243-
uptr begin;
244-
uptr end;
245-
};
246-
247238
// LockStuffAndStopTheWorld can start to use Scan* calls to collect into
248239
// this Frontier vector before the StopTheWorldCallback actually runs.
249240
// This is used when the OS has a unified callback API for suspending
@@ -256,6 +247,8 @@ struct CheckForLeaksParam {
256247
bool success = false;
257248
};
258249

250+
using Region = Range;
251+
259252
bool HasRootRegions();
260253
void ScanRootRegions(Frontier *frontier,
261254
const InternalMmapVectorNoCtor<Region> &region);

0 commit comments

Comments
 (0)