summaryrefslogtreecommitdiffstats
path: root/app/perfelfmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/perfelfmap.cpp')
-rw-r--r--app/perfelfmap.cpp38
1 files changed, 20 insertions, 18 deletions
diff --git a/app/perfelfmap.cpp b/app/perfelfmap.cpp
index be7bad7..e891fa0 100644
--- a/app/perfelfmap.cpp
+++ b/app/perfelfmap.cpp
@@ -32,7 +32,7 @@ QDebug operator<<(QDebug stream, const PerfElfMap::ElfInfo& info)
<< "len=" << info.length << ", "
<< "pgoff=" << info.pgoff << ", "
<< "timeAdded=" << info.timeAdded << ", "
- << "timeOverwritten=" << info.timeOverwritten << "}";
+ << "}";
return stream.space();
}
@@ -55,32 +55,30 @@ bool PerfElfMap::registerElf(const quint64 addr, const quint64 len, quint64 pgof
const quint64 time, const QFileInfo &fullPath)
{
bool cacheInvalid = false;
- quint64 overwritten = std::numeric_limits<quint64>::max();
const quint64 addrEnd = addr + len;
const bool isFile = fullPath.isFile();
QVarLengthArray<ElfInfo, 8> newElfs;
+ QVarLengthArray<int, 8> removedElfs;
for (auto i = m_elfs.begin(), end = m_elfs.end(); i != end && i->addr < addrEnd; ++i) {
const quint64 iEnd = i->addr + i->length;
if (iEnd <= addr)
continue;
- if (i->timeOverwritten > time) {
- // Newly added elf overwrites existing one. Mark the existing one as overwritten and
- // reinsert any fragments of it that remain.
-
- if (i->addr < addr) {
- newElfs.push_back(ElfInfo(i->file, i->addr, addr - i->addr, i->pgoff,
- time, i->timeOverwritten));
- }
- if (iEnd > addrEnd) {
- newElfs.push_back(ElfInfo(i->file, addrEnd, iEnd - addrEnd,
- i->pgoff + addrEnd - i->addr, time,
- i->timeOverwritten));
- }
- i->timeOverwritten = time;
+ // Newly added elf overwrites existing one. Mark the existing one as overwritten and
+ // reinsert any fragments of it that remain.
+
+ if (i->addr < addr) {
+ newElfs.push_back(ElfInfo(i->file, i->addr, addr - i->addr,
+ i->pgoff, time));
+ }
+ if (iEnd > addrEnd) {
+ newElfs.push_back(ElfInfo(i->file, addrEnd, iEnd - addrEnd,
+ i->pgoff + addrEnd - i->addr, time));
}
+ removedElfs.push_back(std::distance(m_elfs.begin(), i));
+
// Overlapping module. Clear the cache, but only when the section is actually backed by a
// file. Otherwise, we will see tons of overlapping heap/anon sections which don't actually
// invalidate our caches
@@ -88,7 +86,11 @@ bool PerfElfMap::registerElf(const quint64 addr, const quint64 len, quint64 pgof
cacheInvalid = true;
}
- newElfs.push_back(ElfInfo(fullPath, addr, len, pgoff, time, overwritten));
+ // remove the overwritten elfs, iterate from the back to not invalidate the indices
+ for (auto it = removedElfs.rbegin(), end = removedElfs.rend(); it != end; ++it)
+ m_elfs.remove(*it);
+
+ newElfs.push_back(ElfInfo(fullPath, addr, len, pgoff, time));
for (const auto &elf : newElfs) {
auto it = std::lower_bound(m_elfs.begin(), m_elfs.end(),
@@ -110,7 +112,7 @@ PerfElfMap::ElfInfo PerfElfMap::findElf(quint64 ip, quint64 timestamp) const
}
while (true) {
- if (i->timeAdded <= timestamp && i->timeOverwritten > timestamp)
+ if (i->timeAdded <= timestamp)
return (i->addr + i->length > ip) ? *i : ElfInfo();
if (i == m_elfs.constBegin())