Skip to content

Commit 0351dc5

Browse files
authored
[lldb] Do not use LC_FUNCTION_STARTS data to determine symbol size as symbols are created (#106791)
Summary: This improves the performance of ObjectFileMacho::ParseSymtab by removing eager and expensive work in favor of doing it later in a less-expensive fashion. Experiment: My goal was to understand LLDB's startup time. First, I produced a Debug build of LLDB (no dSYM) and a Release+NoAsserts build of LLDB. The Release build debugged the Debug build as it debugged a small C++ program. I found that ObjectFileMachO::ParseSymtab accounted for somewhere between 1.2 and 1.3 seconds consistently. After applying this change, I consistently measured a reduction of approximately 100ms, putting the time closer to 1.1s and 1.2s on average. Background: ObjectFileMachO::ParseSymtab will incrementally create symbols by parsing nlist entries from the symtab section of a MachO binary. As it does this, it eagerly tries to determine the size of symbols (e.g. how long a function is) using LC_FUNCTION_STARTS data (or eh_frame if LC_FUNCTION_STARTS is unavailable). Concretely, this is done by performing a binary search on the function starts array and calculating the distance to the next function or the end of the section (whichever is smaller). However, this work is unnecessary for 2 reasons: 1. If you have debug symbol entries (i.e. STABs), the size of a function is usually stored right after the function's entry. Performing this work right before parsing the next entry is unnecessary work. 2. Calculating symbol sizes for symbols of size 0 is already performed in `Symtab::InitAddressIndexes` after all the symbols are added to the Symtab. It also does this more efficiently by walking over a list of symbols sorted by address, so the work to calculate the size per symbol is constant instead of O(log n).
1 parent b6bf27e commit 0351dc5

File tree

1 file changed

+0
-63
lines changed

1 file changed

+0
-63
lines changed

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

-63
Original file line numberDiff line numberDiff line change
@@ -3768,7 +3768,6 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
37683768

37693769
SymbolType type = eSymbolTypeInvalid;
37703770
SectionSP symbol_section;
3771-
lldb::addr_t symbol_byte_size = 0;
37723771
bool add_nlist = true;
37733772
bool is_gsym = false;
37743773
bool demangled_is_synthesized = false;
@@ -4354,47 +4353,6 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
43544353

43554354
if (symbol_section) {
43564355
const addr_t section_file_addr = symbol_section->GetFileAddress();
4357-
if (symbol_byte_size == 0 && function_starts_count > 0) {
4358-
addr_t symbol_lookup_file_addr = nlist.n_value;
4359-
// Do an exact address match for non-ARM addresses, else get the
4360-
// closest since the symbol might be a thumb symbol which has an
4361-
// address with bit zero set.
4362-
FunctionStarts::Entry *func_start_entry =
4363-
function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
4364-
if (is_arm && func_start_entry) {
4365-
// Verify that the function start address is the symbol address
4366-
// (ARM) or the symbol address + 1 (thumb).
4367-
if (func_start_entry->addr != symbol_lookup_file_addr &&
4368-
func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
4369-
// Not the right entry, NULL it out...
4370-
func_start_entry = nullptr;
4371-
}
4372-
}
4373-
if (func_start_entry) {
4374-
func_start_entry->data = true;
4375-
4376-
addr_t symbol_file_addr = func_start_entry->addr;
4377-
if (is_arm)
4378-
symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
4379-
4380-
const FunctionStarts::Entry *next_func_start_entry =
4381-
function_starts.FindNextEntry(func_start_entry);
4382-
const addr_t section_end_file_addr =
4383-
section_file_addr + symbol_section->GetByteSize();
4384-
if (next_func_start_entry) {
4385-
addr_t next_symbol_file_addr = next_func_start_entry->addr;
4386-
// Be sure the clear the Thumb address bit when we calculate the
4387-
// size from the current and next address
4388-
if (is_arm)
4389-
next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
4390-
symbol_byte_size = std::min<lldb::addr_t>(
4391-
next_symbol_file_addr - symbol_file_addr,
4392-
section_end_file_addr - symbol_file_addr);
4393-
} else {
4394-
symbol_byte_size = section_end_file_addr - symbol_file_addr;
4395-
}
4396-
}
4397-
}
43984356
symbol_value -= section_file_addr;
43994357
}
44004358

@@ -4501,9 +4459,6 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
45014459
if (nlist.n_desc & N_WEAK_REF)
45024460
sym[sym_idx].SetIsWeak(true);
45034461

4504-
if (symbol_byte_size > 0)
4505-
sym[sym_idx].SetByteSize(symbol_byte_size);
4506-
45074462
if (demangled_is_synthesized)
45084463
sym[sym_idx].SetDemangledNameIsSynthesized(true);
45094464

@@ -4622,23 +4577,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
46224577
Address symbol_addr;
46234578
if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
46244579
SectionSP symbol_section(symbol_addr.GetSection());
4625-
uint32_t symbol_byte_size = 0;
46264580
if (symbol_section) {
4627-
const addr_t section_file_addr = symbol_section->GetFileAddress();
4628-
const FunctionStarts::Entry *next_func_start_entry =
4629-
function_starts.FindNextEntry(func_start_entry);
4630-
const addr_t section_end_file_addr =
4631-
section_file_addr + symbol_section->GetByteSize();
4632-
if (next_func_start_entry) {
4633-
addr_t next_symbol_file_addr = next_func_start_entry->addr;
4634-
if (is_arm)
4635-
next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
4636-
symbol_byte_size = std::min<lldb::addr_t>(
4637-
next_symbol_file_addr - symbol_file_addr,
4638-
section_end_file_addr - symbol_file_addr);
4639-
} else {
4640-
symbol_byte_size = section_end_file_addr - symbol_file_addr;
4641-
}
46424581
sym[sym_idx].SetID(synthetic_sym_id++);
46434582
// Don't set the name for any synthetic symbols, the Symbol
46444583
// object will generate one if needed when the name is accessed
@@ -4650,8 +4589,6 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
46504589
add_symbol_addr(symbol_addr.GetFileAddress());
46514590
if (symbol_flags)
46524591
sym[sym_idx].SetFlags(symbol_flags);
4653-
if (symbol_byte_size)
4654-
sym[sym_idx].SetByteSize(symbol_byte_size);
46554592
++sym_idx;
46564593
}
46574594
}

0 commit comments

Comments
 (0)