win: Make GetReadableRangesOfMemoryMap() less slow in Debug

d:\src\crashpad\crashpad>git checkout origin/master
Note: checking out 'origin/master'.
...
HEAD is now at f497e54... win: Fix indirectly gathered memory cap

[f497e54...]d:\src\crashpad\crashpad>ninja -C out\Debug
ninja: Entering directory `out\Debug'
[0->23/23 ~0] STAMP obj\All.actions_depends.stamp

[f497e54...]d:\src\crashpad\crashpad>tim out\Debug\crashpad_snapshot_test --gtest_filter=ProcessSnapshotTest.CrashpadInfoChild
Running main() from gtest_main.cc
Note: Google Test filter = ProcessSnapshotTest.CrashpadInfoChild
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ProcessSnapshotTest
[ RUN      ] ProcessSnapshotTest.CrashpadInfoChild
[       OK ] ProcessSnapshotTest.CrashpadInfoChild (147879 ms)
[----------] 1 test from ProcessSnapshotTest (147880 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (147884 ms total)
[  PASSED  ] 1 test.

real: 2m27.907s
qpc: 147914874us

[f497e54...]d:\src\crashpad\crashpad>git checkout slow-debug
Previous HEAD position was f497e54... win: Fix indirectly gathered memory cap
Switched to branch 'slow-debug'
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

[slow-debug]d:\src\crashpad\crashpad>ninja -C out\Debug
ninja: Entering directory `out\Debug'
[0->23/23 ~0] STAMP obj\All.actions_depends.stamp

[slow-debug]d:\src\crashpad\crashpad>tim out\Debug\crashpad_snapshot_test --gtest_filter=ProcessSnapshotTest.CrashpadInfoChild
Running main() from gtest_main.cc
Note: Google Test filter = ProcessSnapshotTest.CrashpadInfoChild
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ProcessSnapshotTest
[ RUN      ] ProcessSnapshotTest.CrashpadInfoChild
[       OK ] ProcessSnapshotTest.CrashpadInfoChild (4414 ms)
[----------] 1 test from ProcessSnapshotTest (4416 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (4420 ms total)
[  PASSED  ] 1 test.

real: 0m4.453s
qpc: 4454559us

R=mark@chromium.org
BUG=crashpad:114

Change-Id: I9f18fe54a2711a483ced86ece0b261cdfffc6192
Reviewed-on: https://chromium-review.googlesource.com/346490
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Scott Graham 2016-05-20 10:22:52 -07:00
parent f497e54ccb
commit d9c7247870

View File

@ -633,14 +633,27 @@ std::vector<CheckedRange<WinVMAddress, WinVMSize>> GetReadableRangesOfMemoryMap(
const ProcessInfo::MemoryBasicInformation64Vector& memory_info) {
using Range = CheckedRange<WinVMAddress, WinVMSize>;
// Constructing Ranges and using OverlapsRange() is very, very slow in Debug
// builds, so do a manual check in this loop. The ranges are still validated
// by a CheckedRange before being returned.
WinVMAddress range_base = range.base();
WinVMAddress range_end = range.end();
// Find all the ranges that overlap the target range, maintaining their order.
ProcessInfo::MemoryBasicInformation64Vector overlapping;
for (const auto& mi : memory_info) {
const size_t size = memory_info.size();
// This loop is written in an ugly fashion to make Debug performance
// reasonable.
const MEMORY_BASIC_INFORMATION64* begin = &memory_info[0];
for (size_t i = 0; i < size; ++i) {
const MEMORY_BASIC_INFORMATION64& mi = *(begin + i);
static_assert(std::is_same<decltype(mi.BaseAddress), WinVMAddress>::value,
"expected range address to be WinVMAddress");
static_assert(std::is_same<decltype(mi.RegionSize), WinVMSize>::value,
"expected range size to be WinVMSize");
if (range.OverlapsRange(Range(mi.BaseAddress, mi.RegionSize)))
WinVMAddress mi_end = mi.BaseAddress + mi.RegionSize;
if (range_base < mi_end && mi.BaseAddress < range_end)
overlapping.push_back(mi);
}
if (overlapping.empty())