llvm.org GIT mirror llvm / 041f7c8
[DebugInfo] Simplify and speedup .debug_aranges parsing Parsing .debug_aranges section now takes O(nlogn) operations instead of O(n^2), where "n" is the number of address ranges. With this change, the time required to symbolize an address from a random large Clang-generated binary drops from 165 seconds to 1.5 seconds. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191781 91177308-0d34-0410-b5e6-96231b3b80d8 Alexey Samsonov 6 years ago
1 changed file(s) with 23 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
1515 #include
1616 using namespace llvm;
1717
18 namespace {
19 class CountArangeDescriptors {
20 public:
21 CountArangeDescriptors(uint32_t &count_ref) : Count(count_ref) {}
22 void operator()(const DWARFDebugArangeSet &Set) {
23 Count += Set.getNumDescriptors();
24 }
25 uint32_t &Count;
26 };
27
28 class AddArangeDescriptors {
29 public:
30 AddArangeDescriptors(DWARFDebugAranges::RangeColl &Ranges,
31 DWARFDebugAranges::ParsedCUOffsetColl &CUOffsets)
32 : RangeCollection(Ranges),
33 CUOffsetCollection(CUOffsets) {}
34 void operator()(const DWARFDebugArangeSet &Set) {
35 DWARFDebugAranges::Range Range;
36 Range.CUOffset = Set.getCompileUnitDIEOffset();
37 CUOffsetCollection.insert(Range.CUOffset);
38
39 for (uint32_t i = 0, n = Set.getNumDescriptors(); i < n; ++i) {
40 const DWARFDebugArangeSet::Descriptor *ArangeDescPtr =
41 Set.getDescriptor(i);
42 Range.LowPC = ArangeDescPtr->Address;
43 Range.Length = ArangeDescPtr->Length;
44
45 // Insert each item in increasing address order so binary searching
46 // can later be done!
47 DWARFDebugAranges::RangeColl::iterator InsertPos =
48 std::lower_bound(RangeCollection.begin(), RangeCollection.end(),
49 Range);
50 RangeCollection.insert(InsertPos, Range);
51 }
52
53 }
54 DWARFDebugAranges::RangeColl &RangeCollection;
55 DWARFDebugAranges::ParsedCUOffsetColl &CUOffsetCollection;
56 };
57 }
58
5918 void DWARFDebugAranges::extract(DataExtractor DebugArangesData) {
6019 if (!DebugArangesData.isValidOffset(0))
6120 return;
62 uint32_t offset = 0;
21 uint32_t Offset = 0;
22 typedef std::vector RangeSetColl;
23 RangeSetColl Sets;
24 DWARFDebugArangeSet Set;
25 uint32_t TotalRanges = 0;
6326
64 typedef std::vector SetCollection;
65 SetCollection sets;
27 while (Set.extract(DebugArangesData, &Offset)) {
28 Sets.push_back(Set);
29 TotalRanges += Set.getNumDescriptors();
30 }
31 if (TotalRanges == 0)
32 return;
6633
67 DWARFDebugArangeSet set;
68 Range range;
69 while (set.extract(DebugArangesData, &offset))
70 sets.push_back(set);
34 Aranges.reserve(TotalRanges);
35 for (RangeSetColl::const_iterator I = Sets.begin(), E = Sets.end(); I != E;
36 ++I) {
37 uint32_t CUOffset = I->getCompileUnitDIEOffset();
7138
72 uint32_t count = 0;
73
74 std::for_each(sets.begin(), sets.end(), CountArangeDescriptors(count));
75
76 if (count > 0) {
77 Aranges.reserve(count);
78 AddArangeDescriptors range_adder(Aranges, ParsedCUOffsets);
79 std::for_each(sets.begin(), sets.end(), range_adder);
39 for (uint32_t i = 0, n = I->getNumDescriptors(); i < n; ++i) {
40 const DWARFDebugArangeSet::Descriptor *ArangeDescPtr =
41 I->getDescriptor(i);
42 uint64_t LowPC = ArangeDescPtr->Address;
43 uint64_t HighPC = LowPC + ArangeDescPtr->Length;
44 appendRange(CUOffset, LowPC, HighPC);
45 }
8046 }
47 sortAndMinimize();
8148 }
8249
8350 void DWARFDebugAranges::generate(DWARFContext *CTX) {