Skip to content

Commit 0e859de

Browse files
Merge pull request #236 from adrian-prantl/lldb-perf
Cherry-pick LLDB performance improvements.
2 parents 771499d + 462dc61 commit 0e859de

File tree

28 files changed

+171
-115
lines changed

28 files changed

+171
-115
lines changed

lldb/include/lldb/Core/Mangled.h

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,7 @@ class Mangled {
4949
/// Default constructor.
5050
///
5151
/// Initialize with both mangled and demangled names empty.
52-
Mangled();
53-
54-
/// Construct with name.
55-
///
56-
/// Constructor with an optional string and a boolean indicating if it is
57-
/// the mangled version.
58-
///
59-
/// \param[in] name
60-
/// The already const name to copy into this object.
61-
///
62-
/// \param[in] is_mangled
63-
/// If \b true then \a name is a mangled name, if \b false then
64-
/// \a name is demangled.
65-
Mangled(ConstString name, bool is_mangled);
66-
Mangled(llvm::StringRef name, bool is_mangled);
52+
Mangled() = default;
6753

6854
/// Construct with name.
6955
///
@@ -76,12 +62,6 @@ class Mangled {
7662

7763
explicit Mangled(llvm::StringRef name);
7864

79-
/// Destructor
80-
///
81-
/// Releases its ref counts on the mangled and demangled strings that live
82-
/// in the global string pool.
83-
~Mangled();
84-
8565
/// Convert to pointer operator.
8666
///
8767
/// This allows code to check a Mangled object to see if it contains a valid

lldb/include/lldb/Symbol/Function.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class InlineFunctionInfo : public FunctionInfo {
140140
/// \param[in] call_decl_ptr
141141
/// Optional calling location declaration information that
142142
/// describes from where this inlined function was called.
143-
InlineFunctionInfo(const char *name, const char *mangled,
143+
InlineFunctionInfo(const char *name, llvm::StringRef mangled,
144144
const Declaration *decl_ptr,
145145
const Declaration *call_decl_ptr);
146146

lldb/include/lldb/Symbol/ObjectFile.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,22 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
6363
public:
6464
enum Type {
6565
eTypeInvalid = 0,
66-
eTypeCoreFile, /// A core file that has a checkpoint of a program's
67-
/// execution state
68-
eTypeExecutable, /// A normal executable
69-
eTypeDebugInfo, /// An object file that contains only debug information
70-
eTypeDynamicLinker, /// The platform's dynamic linker executable
71-
eTypeObjectFile, /// An intermediate object file
72-
eTypeSharedLibrary, /// A shared library that can be used during execution
73-
eTypeStubLibrary, /// A library that can be linked against but not used for
74-
/// execution
75-
eTypeJIT, /// JIT code that has symbols, sections and possibly debug info
66+
/// A core file that has a checkpoint of a program's execution state.
67+
eTypeCoreFile,
68+
/// A normal executable.
69+
eTypeExecutable,
70+
/// An object file that contains only debug information.
71+
eTypeDebugInfo,
72+
/// The platform's dynamic linker executable.
73+
eTypeDynamicLinker,
74+
/// An intermediate object file.
75+
eTypeObjectFile,
76+
/// A shared library that can be used during execution.
77+
eTypeSharedLibrary,
78+
/// A library that can be linked against but not used for execution.
79+
eTypeStubLibrary,
80+
/// JIT code that has symbols, sections and possibly debug info.
81+
eTypeJIT,
7682
eTypeUnknown
7783
};
7884

@@ -201,7 +207,7 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
201207
/// \b false otherwise and \a archive_file and \a archive_object
202208
/// are guaranteed to be remain unchanged.
203209
static bool SplitArchivePathWithObject(
204-
const char *path_with_object, lldb_private::FileSpec &archive_file,
210+
llvm::StringRef path_with_object, lldb_private::FileSpec &archive_file,
205211
lldb_private::ConstString &archive_object, bool must_exist);
206212

207213
// LLVM RTTI support

lldb/include/lldb/Symbol/Symbol.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ class Symbol : public SymbolContextScope {
2424
// drastically different meanings and sorting requirements.
2525
Symbol();
2626

27-
Symbol(uint32_t symID, const char *name, bool name_is_mangled,
28-
lldb::SymbolType type, bool external, bool is_debug,
29-
bool is_trampoline, bool is_artificial,
27+
Symbol(uint32_t symID, llvm::StringRef name, lldb::SymbolType type,
28+
bool external, bool is_debug, bool is_trampoline, bool is_artificial,
3029
const lldb::SectionSP &section_sp, lldb::addr_t value,
3130
lldb::addr_t size, bool size_is_valid,
3231
bool contains_linker_annotations, uint32_t flags);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# There is no guaranteed order in which the linker will order these
2+
# files, so we just have a lot of them to make it unlikely that we hit
3+
# the right one first by pure luck.
4+
5+
CXX_SOURCES := main.cpp a.cpp b.cpp c.cpp d.cpp e.cpp f.cpp g.cpp
6+
7+
include Makefile.rules
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
7+
class CPPAcceleratorTableTestCase(TestBase):
8+
9+
mydir = TestBase.compute_mydir(__file__)
10+
11+
@skipUnlessDarwin
12+
@skipIf(debug_info=no_match(["dwarf"]))
13+
def test(self):
14+
"""Test that type lookups fail early (performance)"""
15+
self.build()
16+
logfile = self.getBuildArtifact('dwarf.log')
17+
self.expect('log enable dwarf lookups -f' + logfile)
18+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
19+
self, 'break here', lldb.SBFileSpec('main.cpp'))
20+
# Pick one from the middle of the list to have a high chance
21+
# of it not being in the first file looked at.
22+
self.expect('frame variable inner_d')
23+
24+
log = open(logfile, 'r')
25+
n = 0
26+
for line in log:
27+
if re.findall(r'[abcdefg]\.o: FindByNameAndTag\(\)', line):
28+
self.assertTrue("d.o" in line)
29+
n += 1
30+
31+
self.assertEqual(n, 1, log)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "source.h"
2+
CLASS(A)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "source.h"
2+
CLASS(B)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "source.h"
2+
CLASS(C)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "source.h"
2+
CLASS(D)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "source.h"
2+
CLASS(E)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "source.h"
2+
CLASS(F)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "source.h"
2+
CLASS(G)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#define CLASS(NAME) \
2+
class NAME { \
3+
public: \
4+
struct Inner; \
5+
Inner *i = nullptr; \
6+
}; \
7+
NAME::Inner &getInner##NAME();
8+
9+
CLASS(A)
10+
CLASS(B)
11+
CLASS(C)
12+
CLASS(D)
13+
CLASS(E)
14+
CLASS(F)
15+
CLASS(G)
16+
17+
int main()
18+
{
19+
A::Inner &inner_a = getInnerA();
20+
B::Inner &inner_b = getInnerB();
21+
C::Inner &inner_c = getInnerC();
22+
D::Inner &inner_d = getInnerD();
23+
E::Inner &inner_e = getInnerE();
24+
F::Inner &inner_f = getInnerF();
25+
G::Inner &inner_g = getInnerG();
26+
27+
return 0; // break here
28+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#define CLASS(NAME) \
2+
class NAME { \
3+
public: \
4+
class Inner { \
5+
int j = #NAME[0]; \
6+
}; \
7+
Inner *i = nullptr; \
8+
}; \
9+
\
10+
static NAME::Inner inner; \
11+
static NAME obj; \
12+
NAME::Inner &getInner##NAME() { return inner; }

lldb/source/API/SBType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ const char *SBTypeMemberFunction::GetDemangledName() {
799799
if (m_opaque_sp) {
800800
ConstString mangled_str = m_opaque_sp->GetMangledName();
801801
if (mangled_str) {
802-
Mangled mangled(mangled_str, true);
802+
Mangled mangled(mangled_str);
803803
return mangled.GetDemangledName(mangled.GuessLanguage()).GetCString();
804804
}
805805
}

lldb/source/Core/Mangled.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,21 +124,6 @@ get_demangled_name_without_arguments(ConstString mangled,
124124
}
125125

126126
#pragma mark Mangled
127-
// Default constructor
128-
Mangled::Mangled() : m_mangled(), m_demangled() {}
129-
130-
// Constructor with an optional string and a boolean indicating if it is the
131-
// mangled version.
132-
Mangled::Mangled(ConstString s, bool mangled)
133-
: m_mangled(), m_demangled() {
134-
if (s)
135-
SetValue(s, mangled);
136-
}
137-
138-
Mangled::Mangled(llvm::StringRef name, bool is_mangled) {
139-
if (!name.empty())
140-
SetValue(ConstString(name), is_mangled);
141-
}
142127

143128
Mangled::Mangled(ConstString s) : m_mangled(), m_demangled() {
144129
if (s)
@@ -150,9 +135,6 @@ Mangled::Mangled(llvm::StringRef name) {
150135
SetValue(ConstString(name));
151136
}
152137

153-
// Destructor
154-
Mangled::~Mangled() {}
155-
156138
// Convert to pointer operator. This allows code to check any Mangled objects
157139
// to see if they contain anything valid using code such as:
158140
//

lldb/source/Expression/IRExecutionUnit.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ FindBestAlternateMangledName(ConstString demangled,
669669
std::vector<ConstString> param_matches;
670670
for (size_t i = 0; i < alternates.size(); i++) {
671671
ConstString alternate_mangled_name = alternates[i];
672-
Mangled mangled(alternate_mangled_name, true);
672+
Mangled mangled(alternate_mangled_name);
673673
ConstString demangled = mangled.GetDemangledName(lang_type);
674674

675675
CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
@@ -717,7 +717,7 @@ void IRExecutionUnit::CollectCandidateCPlusPlusNames(
717717
ConstString name = C_spec.name;
718718

719719
if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) {
720-
Mangled mangled(name, true);
720+
Mangled mangled(name);
721721
ConstString demangled =
722722
mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
723723

lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed {
360360
if (name.startswith("__Z"))
361361
name = name.drop_front();
362362

363-
Mangled mangled(name, true);
363+
Mangled mangled(name);
364364
if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) {
365365
ConstString demangled(
366366
mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));

lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,16 +2146,14 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
21462146

21472147
bool is_global = symbol.getBinding() == STB_GLOBAL;
21482148
uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
2149-
bool is_mangled = (symbol_name[0] == '_' && symbol_name[1] == 'Z');
2150-
21512149
llvm::StringRef symbol_ref(symbol_name);
21522150

21532151
// Symbol names may contain @VERSION suffixes. Find those and strip them
21542152
// temporarily.
21552153
size_t version_pos = symbol_ref.find('@');
21562154
bool has_suffix = version_pos != llvm::StringRef::npos;
21572155
llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
2158-
Mangled mangled(ConstString(symbol_bare), is_mangled);
2156+
Mangled mangled(symbol_bare);
21592157

21602158
// Now append the suffix back to mangled and unmangled names. Only do it if
21612159
// the demangling was successful (string is not empty).
@@ -2386,14 +2384,11 @@ static unsigned ParsePLTRelocations(
23862384
break;
23872385

23882386
const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
2389-
bool is_mangled =
2390-
symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
23912387
uint64_t plt_index = plt_offset + i * plt_entsize;
23922388

23932389
Symbol jump_symbol(
23942390
i + start_id, // Symbol table index
23952391
symbol_name, // symbol name.
2396-
is_mangled, // is the symbol name mangled?
23972392
eSymbolTypeTrampoline, // Type of this symbol
23982393
false, // Is this globally visible?
23992394
false, // Is this symbol debug info?
@@ -2781,7 +2776,6 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
27812776
Symbol eh_symbol(
27822777
symbol_id, // Symbol table index.
27832778
symbol_name, // Symbol name.
2784-
false, // Is the symbol name mangled?
27852779
eSymbolTypeCode, // Type of this symbol.
27862780
true, // Is this globally visible?
27872781
false, // Is this symbol debug info?

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

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,18 +1895,6 @@ class MachSymtabSectionInfo {
18951895
};
18961896

18971897
struct TrieEntry {
1898-
TrieEntry()
1899-
: name(), address(LLDB_INVALID_ADDRESS), flags(0), other(0),
1900-
import_name() {}
1901-
1902-
void Clear() {
1903-
name.Clear();
1904-
address = LLDB_INVALID_ADDRESS;
1905-
flags = 0;
1906-
other = 0;
1907-
import_name.Clear();
1908-
}
1909-
19101898
void Dump() const {
19111899
printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
19121900
static_cast<unsigned long long>(address),
@@ -1918,9 +1906,9 @@ struct TrieEntry {
19181906
printf("\n");
19191907
}
19201908
ConstString name;
1921-
uint64_t address;
1922-
uint64_t flags;
1923-
uint64_t other;
1909+
uint64_t address = LLDB_INVALID_ADDRESS;
1910+
uint64_t flags = 0;
1911+
uint64_t other = 0;
19241912
ConstString import_name;
19251913
};
19261914

lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,8 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
350350
return;
351351
}
352352
symbols.try_emplace(
353-
address, /*symID*/ 0, Mangled(name, /*is_mangled*/ false),
354-
eSymbolTypeCode, /*is_global*/ true, /*is_debug*/ false,
353+
address, /*symID*/ 0, Mangled(name), eSymbolTypeCode,
354+
/*is_global*/ true, /*is_debug*/ false,
355355
/*is_trampoline*/ false, /*is_artificial*/ false,
356356
AddressRange(section_sp, address - section_sp->GetFileAddress(),
357357
size.getValueOr(0)),

lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
110110
const bool has_qualified_name_hash =
111111
m_apple_types_up->GetHeader().header_data.ContainsAtom(
112112
DWARFMappedHash::eAtomTypeQualNameHash);
113+
113114
const ConstString type_name(context[0].name);
114115
const dw_tag_t tag = context[0].tag;
115116
if (has_tag && has_qualified_name_hash) {
@@ -119,12 +120,32 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
119120
m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
120121
m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
121122
type_name.GetStringRef(), tag, qualified_name_hash, offsets);
122-
} else if (has_tag) {
123+
return;
124+
}
125+
126+
if (has_tag) {
127+
// When searching for a scoped type (for example,
128+
// "std::vector<int>::const_iterator") searching for the innermost
129+
// name alone ("const_iterator") could yield many false
130+
// positives. By searching for the parent type ("vector<int>")
131+
// first we can avoid extracting type DIEs from object files that
132+
// would fail the filter anyway.
133+
if (!has_qualified_name_hash && (context.GetSize() > 1) &&
134+
(context[1].tag == DW_TAG_class_type ||
135+
context[1].tag == DW_TAG_structure_type)) {
136+
DIEArray class_matches;
137+
m_apple_types_up->FindByName(context[1].name, class_matches);
138+
if (class_matches.empty())
139+
return;
140+
}
141+
123142
if (log)
124143
m_module.LogMessage(log, "FindByNameAndTag()");
125144
m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
126-
} else
127-
m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
145+
return;
146+
}
147+
148+
m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
128149
}
129150

130151
void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {

0 commit comments

Comments
 (0)