Cleanup on the unified section list changes. Main changes are:
- ObjectFile::GetSymtab() and ObjectFile::ClearSymtab() no longer takes any flags
- Module coordinates with the object files and contain a unified section list so that object file and symbol file can share sections when they need to, yet contain their own sections.
Other cleanups:
- Fixed Symbol::GetByteSize() to not have the symbol table compute the byte sizes on the fly
- Modified the ObjectFileMachO class to compute symbol sizes all at once efficiently
- Modified the Symtab class to store a file address lookup table for more efficient lookups
- Removed Section::Finalize() and SectionList::Finalize() as they did nothing
- Improved performance of the detection of symbol files that have debug maps by excluding stripped files and core files, debug files, object files and stubs
- Added the ability to tell if an ObjectFile has been stripped with ObjectFile::IsStripped() (used this for the above performance improvement)
llvm-svn: 185990
diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp
index b16340b..27af698 100644
--- a/lldb/source/Symbol/Symtab.cpp
+++ b/lldb/source/Symbol/Symtab.cpp
@@ -27,10 +27,10 @@
Symtab::Symtab(ObjectFile *objfile) :
m_objfile (objfile),
m_symbols (),
- m_addr_indexes (),
+ m_file_addr_to_index (),
m_name_to_index (),
m_mutex (Mutex::eMutexTypeRecursive),
- m_addr_indexes_computed (false),
+ m_file_addr_to_index_computed (false),
m_name_indexes_computed (false)
{
}
@@ -63,9 +63,9 @@
// when calling this function to avoid performance issues.
uint32_t symbol_idx = m_symbols.size();
m_name_to_index.Clear();
- m_addr_indexes.clear();
+ m_file_addr_to_index.Clear();
m_symbols.push_back(symbol);
- m_addr_indexes_computed = false;
+ m_file_addr_to_index_computed = false;
m_name_indexes_computed = false;
return symbol_idx;
}
@@ -144,19 +144,14 @@
case eSortOrderByAddress:
s->PutCString (" (sorted by address):\n");
DumpSymbolHeader (s);
- if (!m_addr_indexes_computed)
+ if (!m_file_addr_to_index_computed)
InitAddressIndexes();
- const size_t num_symbols = GetNumSymbols();
- std::vector<uint32_t>::const_iterator pos;
- std::vector<uint32_t>::const_iterator end = m_addr_indexes.end();
- for (pos = m_addr_indexes.begin(); pos != end; ++pos)
+ const size_t num_entries = m_file_addr_to_index.GetSize();
+ for (size_t i=0; i<num_entries; ++i)
{
- size_t idx = *pos;
- if (idx < num_symbols)
- {
- s->Indent();
- m_symbols[idx].Dump(s, target, idx);
- }
+ s->Indent();
+ const uint32_t symbol_idx = m_file_addr_to_index.GetEntryRef(i).data;
+ m_symbols[symbol_idx].Dump(s, target, symbol_idx);
}
break;
}
@@ -943,92 +938,94 @@
Symtab::InitAddressIndexes()
{
// Protected function, no need to lock mutex...
- if (!m_addr_indexes_computed && !m_symbols.empty())
+ if (!m_file_addr_to_index_computed && !m_symbols.empty())
{
- m_addr_indexes_computed = true;
+ m_file_addr_to_index_computed = true;
+ FileRangeToIndexMap::Entry entry;
const_iterator begin = m_symbols.begin();
const_iterator end = m_symbols.end();
for (const_iterator pos = m_symbols.begin(); pos != end; ++pos)
{
if (pos->ValueIsAddress())
- m_addr_indexes.push_back (std::distance(begin, pos));
- }
-
- SortSymbolIndexesByValue (m_addr_indexes, false);
- m_addr_indexes.push_back (UINT32_MAX); // Terminator for bsearch since we might need to look at the next symbol
- }
-}
-
-size_t
-Symtab::CalculateSymbolSize (Symbol *symbol)
-{
- Mutex::Locker locker (m_mutex);
-
- if (m_symbols.empty())
- return 0;
-
- // Make sure this symbol is from this symbol table...
- if (symbol < &m_symbols.front() || symbol > &m_symbols.back())
- return 0;
-
- size_t byte_size = 0;
-
- // Else if this is an address based symbol, figure out the delta between
- // it and the next address based symbol
- if (symbol->ValueIsAddress())
- {
- if (!m_addr_indexes_computed)
- InitAddressIndexes();
- const size_t num_addr_indexes = m_addr_indexes.size();
- const lldb::addr_t symbol_file_addr = symbol->GetAddress().GetFileAddress();
- SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress (this,
- symbol_file_addr,
- &m_addr_indexes.front(),
- num_addr_indexes);
- if (info.match_index_ptr != NULL)
- {
- // We can figure out the address range of all symbols except the
- // last one by taking the delta between the current symbol and
- // the next symbol
-
- for (uint32_t addr_index = info.match_index_ptr - &m_addr_indexes.front() + 1;
- addr_index < num_addr_indexes;
- ++addr_index)
{
- Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]);
- if (next_symbol == NULL)
+ entry.SetRangeBase(pos->GetAddress().GetFileAddress());
+ entry.SetByteSize(pos->GetByteSize());
+ entry.data = std::distance(begin, pos);
+ m_file_addr_to_index.Append(entry);
+ }
+ }
+ const size_t num_entries = m_file_addr_to_index.GetSize();
+ if (num_entries > 0)
+ {
+ m_file_addr_to_index.Sort();
+ m_file_addr_to_index.CalculateSizesOfZeroByteSizeRanges();
+
+ // Now our last symbols might not have had sizes because there
+ // was no subsequent symbol to calculate the size from. If this is
+ // the case, then calculate the size by capping it at the end of the
+ // section in which the symbol resides
+ for (int i = num_entries - 1; i >= 0; --i)
+ {
+ const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
+ // As we iterate backwards, as soon as we find a symbol with a valid
+ // byte size, we are done
+ if (entry.GetByteSize() > 0)
+ break;
+
+ // Cap the size to the end of the section in which the symbol resides
+ SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (entry.GetRangeBase()));
+ if (section_sp)
{
- // No next symbol take the size to be the remaining bytes in the section
- // in which the symbol resides
- SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (symbol_file_addr));
- if (section_sp)
+ const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
+ const lldb::addr_t symbol_file_addr = entry.GetRangeBase();
+ if (end_section_file_addr > symbol_file_addr)
{
- const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
- if (end_section_file_addr > symbol_file_addr)
- {
- byte_size = end_section_file_addr - symbol_file_addr;
- symbol->SetByteSize(byte_size);
- symbol->SetSizeIsSynthesized(true);
- break;
- }
- }
- }
- else
- {
- const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
- if (next_file_addr > symbol_file_addr)
- {
- byte_size = next_file_addr - symbol_file_addr;
- symbol->SetByteSize(byte_size);
- symbol->SetSizeIsSynthesized(true);
- break;
+ Symbol &symbol = m_symbols[entry.data];
+
+ symbol.SetByteSize(end_section_file_addr - symbol_file_addr);
+ symbol.SetSizeIsSynthesized(true);
}
}
}
+ // Sort again in case the range size changes the ordering
+ m_file_addr_to_index.Sort();
}
}
- return byte_size;
+}
+
+void
+Symtab::CalculateSymbolSizes ()
+{
+ Mutex::Locker locker (m_mutex);
+
+ if (!m_symbols.empty())
+ {
+ if (!m_file_addr_to_index_computed)
+ InitAddressIndexes();
+
+ const size_t num_entries = m_file_addr_to_index.GetSize();
+
+ for (size_t i = 0; i < num_entries; ++i)
+ {
+ // The entries in the m_file_addr_to_index have calculated the sizes already
+ // so we will use this size if we need to.
+ const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
+
+ Symbol &symbol = m_symbols[entry.data];
+
+ // If the symbol size is already valid, no need to do anything
+ if (symbol.GetByteSizeIsValid())
+ continue;
+
+ const addr_t range_size = entry.GetByteSize();
+ if (range_size > 0)
+ {
+ symbol.SetByteSize(range_size);
+ symbol.SetSizeIsSynthesized(true);
+ }
+ }
+ }
}
Symbol *
@@ -1036,6 +1033,7 @@
{
Mutex::Locker locker (m_mutex);
+
SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 };
::bsearch (&info,
@@ -1074,10 +1072,13 @@
{
Mutex::Locker locker (m_mutex);
- if (!m_addr_indexes_computed)
+ if (!m_file_addr_to_index_computed)
InitAddressIndexes();
- return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size());
+ const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryThatContains(file_addr);
+ if (entry)
+ return SymbolAtIndex(entry->data);
+ return NULL;
}
void