summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-03-16 23:43:11 +0000
committerRui Ueyama <ruiu@google.com>2015-03-16 23:43:11 +0000
commit3c2e306a5c2083c09c7ad6b6963dcc14eae218fb (patch)
treed74885d2fc88ca4b248e862ab81f0c7de8086457
parentad0bdcd2380a09c7dac5ef9748fc20d9cba3e319 (diff)
downloadbcm5719-llvm-3c2e306a5c2083c09c7ad6b6963dcc14eae218fb.tar.gz
bcm5719-llvm-3c2e306a5c2083c09c7ad6b6963dcc14eae218fb.zip
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. llvm-svn: 232436
-rw-r--r--lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp37
1 files changed, 18 insertions, 19 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
index 595b0cc7fac..2862f949fbc 100644
--- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
@@ -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::AtomizeDefinedSymbolsInSection(
*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::AtomizeDefinedSymbolsInSection(
*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::AtomizeDefinedSymbolsInSection(
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(const coff_section *section,
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
OpenPOWER on IntegriCloud