[lld] r232436 - PECOFF: Make FileCOFF:findAtomAt from O(n) to O(1).
Rui Ueyama
ruiu at google.com
Mon Mar 16 16:43:11 PDT 2015
Author: ruiu
Date: Mon Mar 16 18:43:11 2015
New Revision: 232436
URL: http://llvm.org/viewvc/llvm-project?rev=232436&view=rev
Log:
PECOFF: Make FileCOFF:findAtomAt from O(n) to O(1).
I knew I cut corners when I wrote this. Turned out that it is
actually slow when a file being read has many symbols. This patch
is to stop doing linear search and instead do map lookup.
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=232436&r1=232435&r2=232436&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Mon Mar 16 18:43:11 2015
@@ -196,9 +196,8 @@ private:
// A sorted map to find an atom from a section and an offset within
// the section.
- std::map<const coff_section *,
- std::map<uint32_t, std::vector<COFFDefinedAtom *>>>
- _definedAtomLocations;
+ std::map<const coff_section *, std::multimap<uint32_t, COFFDefinedAtom *>>
+ _definedAtomLocations;
uint64_t _ordinal;
llvm::COFF::MachineTypes _machineType;
@@ -696,7 +695,7 @@ std::error_code FileCOFF::AtomizeDefined
*this, "", sectionName, sectionSize, Atom::scopeTranslationUnit,
type, isComdat, perms, _merge[section], data, getNextOrdinal());
atoms.push_back(atom);
- _definedAtomLocations[section][0].push_back(atom);
+ _definedAtomLocations[section].insert(std::make_pair(0, atom));
return std::error_code();
}
@@ -709,7 +708,7 @@ std::error_code FileCOFF::AtomizeDefined
*this, "", sectionName, sectionSize, Atom::scopeTranslationUnit,
type, isComdat, perms, _merge[section], data, getNextOrdinal());
atoms.push_back(atom);
- _definedAtomLocations[section][0].push_back(atom);
+ _definedAtomLocations[section].insert(std::make_pair(0, atom));
}
for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
@@ -723,7 +722,7 @@ std::error_code FileCOFF::AtomizeDefined
type, isComdat, perms, _merge[section], data, getNextOrdinal());
atoms.push_back(atom);
_symbolAtom[*si] = atom;
- _definedAtomLocations[section][si->getValue()].push_back(atom);
+ _definedAtomLocations[section].insert(std::make_pair(si->getValue(), atom));
}
return std::error_code();
}
@@ -786,19 +785,19 @@ std::error_code FileCOFF::findAtomAt(con
uint32_t targetAddress,
COFFDefinedFileAtom *&result,
uint32_t &offsetInAtom) {
- for (auto i : _definedAtomLocations[section]) {
- uint32_t atomAddress = i.first;
- std::vector<COFFDefinedAtom *> &atomsAtSameLocation = i.second;
- COFFDefinedAtom *atom = atomsAtSameLocation.back();
- if (atomAddress <= targetAddress &&
- targetAddress < atomAddress + atom->size()) {
- result = atom;
- offsetInAtom = targetAddress - atomAddress;
- return std::error_code();
- }
- }
- // Relocation target is out of range
- return llvm::object::object_error::parse_failed;
+ auto loc = _definedAtomLocations.find(section);
+ if (loc == _definedAtomLocations.end())
+ return llvm::object::object_error::parse_failed;
+ std::multimap<uint32_t, COFFDefinedAtom *> &map = loc->second;
+
+ auto it = map.upper_bound(targetAddress);
+ if (it == map.begin())
+ return llvm::object::object_error::parse_failed;
+ --it;
+ uint32_t atomAddress = it->first;
+ result = it->second;
+ offsetInAtom = targetAddress - atomAddress;
+ return std::error_code();
}
/// Find the atom for the symbol that was at the \p index in the symbol
More information about the llvm-commits
mailing list