[lldb][NFC] Fix all formatting errors in .cpp file headers
Summary:
A *.cpp file header in LLDB (and in LLDB) should like this:
```
//===-- TestUtilities.cpp -------------------------------------------------===//
```
However in LLDB most of our source files have arbitrary changes to this format and
these changes are spreading through LLDB as folks usually just use the existing
source files as templates for their new files (most notably the unnecessary
editor language indicator `-*- C++ -*-` is spreading and in every review
someone is pointing out that this is wrong, resulting in people pointing out that this
is done in the same way in other files).
This patch removes most of these inconsistencies including the editor language indicators,
all the different missing/additional '-' characters, files that center the file name, missing
trailing `===//` (mostly caused by clang-format breaking the line).
Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D73258
2020-01-24 15:23:27 +08:00
|
|
|
//===-- Symtab.cpp --------------------------------------------------------===//
|
2010-06-09 00:52:24 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2010-06-09 00:52:24 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include <map>
|
2015-09-02 09:59:14 +08:00
|
|
|
#include <set>
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
#include "lldb/Core/Module.h"
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
#include "lldb/Core/RichManglingContext.h"
|
2017-06-29 22:32:17 +08:00
|
|
|
#include "lldb/Core/Section.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Symbol/ObjectFile.h"
|
2015-02-26 06:41:34 +08:00
|
|
|
#include "lldb/Symbol/Symbol.h"
|
2013-01-08 08:01:36 +08:00
|
|
|
#include "lldb/Symbol/SymbolContext.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Symbol/Symtab.h"
|
2021-06-11 05:55:25 +08:00
|
|
|
#include "lldb/Target/Language.h"
|
2017-02-03 05:39:50 +08:00
|
|
|
#include "lldb/Utility/RegularExpression.h"
|
|
|
|
#include "lldb/Utility/Stream.h"
|
2017-06-29 22:32:17 +08:00
|
|
|
#include "lldb/Utility/Timer.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
2016-05-19 13:13:57 +08:00
|
|
|
Symtab::Symtab(ObjectFile *objfile)
|
2020-01-13 19:03:14 +08:00
|
|
|
: m_objfile(objfile), m_symbols(), m_file_addr_to_index(*this),
|
2021-06-04 03:14:20 +08:00
|
|
|
m_name_to_symbol_indices(), m_mutex(),
|
|
|
|
m_file_addr_to_index_computed(false), m_name_indexes_computed(false) {
|
|
|
|
m_name_to_symbol_indices.emplace(std::make_pair(
|
|
|
|
lldb::eFunctionNameTypeNone, UniqueCStringMap<uint32_t>()));
|
|
|
|
m_name_to_symbol_indices.emplace(std::make_pair(
|
|
|
|
lldb::eFunctionNameTypeBase, UniqueCStringMap<uint32_t>()));
|
|
|
|
m_name_to_symbol_indices.emplace(std::make_pair(
|
|
|
|
lldb::eFunctionNameTypeMethod, UniqueCStringMap<uint32_t>()));
|
|
|
|
m_name_to_symbol_indices.emplace(std::make_pair(
|
|
|
|
lldb::eFunctionNameTypeSelector, UniqueCStringMap<uint32_t>()));
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2021-07-03 02:27:37 +08:00
|
|
|
Symtab::~Symtab() = default;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2013-01-26 02:06:21 +08:00
|
|
|
void Symtab::Reserve(size_t count) {
|
2010-10-08 12:20:14 +08:00
|
|
|
// Clients should grab the mutex from this symbol table and lock it manually
|
|
|
|
// when calling this function to avoid performance issues.
|
2010-06-09 00:52:24 +08:00
|
|
|
m_symbols.reserve(count);
|
|
|
|
}
|
|
|
|
|
2013-01-26 02:06:21 +08:00
|
|
|
Symbol *Symtab::Resize(size_t count) {
|
2010-10-08 12:20:14 +08:00
|
|
|
// Clients should grab the mutex from this symbol table and lock it manually
|
|
|
|
// when calling this function to avoid performance issues.
|
2010-06-09 00:52:24 +08:00
|
|
|
m_symbols.resize(count);
|
2016-02-10 08:06:50 +08:00
|
|
|
return m_symbols.empty() ? nullptr : &m_symbols[0];
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Symtab::AddSymbol(const Symbol &symbol) {
|
2010-10-08 12:20:14 +08:00
|
|
|
// Clients should grab the mutex from this symbol table and lock it manually
|
|
|
|
// when calling this function to avoid performance issues.
|
2010-06-09 00:52:24 +08:00
|
|
|
uint32_t symbol_idx = m_symbols.size();
|
2021-06-04 03:14:20 +08:00
|
|
|
auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
|
|
|
|
name_to_index.Clear();
|
2013-07-10 09:23:25 +08:00
|
|
|
m_file_addr_to_index.Clear();
|
2010-06-09 00:52:24 +08:00
|
|
|
m_symbols.push_back(symbol);
|
2013-07-10 09:23:25 +08:00
|
|
|
m_file_addr_to_index_computed = false;
|
2010-10-08 12:20:14 +08:00
|
|
|
m_name_indexes_computed = false;
|
2010-06-09 00:52:24 +08:00
|
|
|
return symbol_idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Symtab::GetNumSymbols() const {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2010-06-09 00:52:24 +08:00
|
|
|
return m_symbols.size();
|
|
|
|
}
|
|
|
|
|
2014-08-22 10:46:46 +08:00
|
|
|
void Symtab::SectionFileAddressesChanged() {
|
2021-06-04 03:14:20 +08:00
|
|
|
auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
|
|
|
|
name_to_index.Clear();
|
2014-08-22 10:46:46 +08:00
|
|
|
m_file_addr_to_index_computed = false;
|
|
|
|
}
|
|
|
|
|
2019-11-07 22:47:01 +08:00
|
|
|
void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order,
|
|
|
|
Mangled::NamePreference name_preference) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-05-19 13:13:57 +08:00
|
|
|
// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
|
2010-06-09 00:52:24 +08:00
|
|
|
s->Indent();
|
|
|
|
const FileSpec &file_spec = m_objfile->GetFileSpec();
|
2014-04-20 21:17:36 +08:00
|
|
|
const char *object_name = nullptr;
|
2010-06-09 00:52:24 +08:00
|
|
|
if (m_objfile->GetModule())
|
|
|
|
object_name = m_objfile->GetModule()->GetObjectName().GetCString();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (file_spec)
|
2014-03-04 03:15:20 +08:00
|
|
|
s->Printf("Symtab, file = %s%s%s%s, num_symbols = %" PRIu64,
|
2013-04-30 01:25:54 +08:00
|
|
|
file_spec.GetPath().c_str(), object_name ? "(" : "",
|
2010-06-09 00:52:24 +08:00
|
|
|
object_name ? object_name : "", object_name ? ")" : "",
|
2014-03-04 03:15:20 +08:00
|
|
|
(uint64_t)m_symbols.size());
|
2010-06-09 00:52:24 +08:00
|
|
|
else
|
2014-03-04 03:15:20 +08:00
|
|
|
s->Printf("Symtab, num_symbols = %" PRIu64 "", (uint64_t)m_symbols.size());
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (!m_symbols.empty()) {
|
2010-10-08 12:20:14 +08:00
|
|
|
switch (sort_order) {
|
|
|
|
case eSortOrderNone: {
|
|
|
|
s->PutCString(":\n");
|
|
|
|
DumpSymbolHeader(s);
|
|
|
|
const_iterator begin = m_symbols.begin();
|
|
|
|
const_iterator end = m_symbols.end();
|
|
|
|
for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) {
|
|
|
|
s->Indent();
|
2019-11-07 22:47:01 +08:00
|
|
|
pos->Dump(s, target, std::distance(begin, pos), name_preference);
|
2010-10-08 12:20:14 +08:00
|
|
|
}
|
|
|
|
} break;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-10-08 12:20:14 +08:00
|
|
|
case eSortOrderByName: {
|
2018-05-01 00:49:04 +08:00
|
|
|
// Although we maintain a lookup by exact name map, the table isn't
|
|
|
|
// sorted by name. So we must make the ordered symbol list up ourselves.
|
2010-10-08 12:20:14 +08:00
|
|
|
s->PutCString(" (sorted by name):\n");
|
|
|
|
DumpSymbolHeader(s);
|
2019-11-28 20:41:18 +08:00
|
|
|
|
|
|
|
std::multimap<llvm::StringRef, const Symbol *> name_map;
|
2010-10-08 12:20:14 +08:00
|
|
|
for (const_iterator pos = m_symbols.begin(), end = m_symbols.end();
|
|
|
|
pos != end; ++pos) {
|
2015-07-09 06:32:23 +08:00
|
|
|
const char *name = pos->GetName().AsCString();
|
2010-10-08 12:20:14 +08:00
|
|
|
if (name && name[0])
|
|
|
|
name_map.insert(std::make_pair(name, &(*pos)));
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-11-28 20:41:18 +08:00
|
|
|
for (const auto &name_to_symbol : name_map) {
|
|
|
|
const Symbol *symbol = name_to_symbol.second;
|
2010-10-08 12:20:14 +08:00
|
|
|
s->Indent();
|
2019-11-28 20:41:18 +08:00
|
|
|
symbol->Dump(s, target, symbol - &m_symbols[0], name_preference);
|
2010-10-08 12:20:14 +08:00
|
|
|
}
|
|
|
|
} break;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-10-08 12:20:14 +08:00
|
|
|
case eSortOrderByAddress:
|
|
|
|
s->PutCString(" (sorted by address):\n");
|
|
|
|
DumpSymbolHeader(s);
|
2013-07-10 09:23:25 +08:00
|
|
|
if (!m_file_addr_to_index_computed)
|
2010-10-08 12:20:14 +08:00
|
|
|
InitAddressIndexes();
|
2013-07-10 09:23:25 +08:00
|
|
|
const size_t num_entries = m_file_addr_to_index.GetSize();
|
|
|
|
for (size_t i = 0; i < num_entries; ++i) {
|
|
|
|
s->Indent();
|
|
|
|
const uint32_t symbol_idx = m_file_addr_to_index.GetEntryRef(i).data;
|
2019-11-07 22:47:01 +08:00
|
|
|
m_symbols[symbol_idx].Dump(s, target, symbol_idx, name_preference);
|
2010-10-08 12:20:14 +08:00
|
|
|
}
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2018-10-02 01:08:51 +08:00
|
|
|
} else {
|
|
|
|
s->PutCString("\n");
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2019-11-07 22:47:01 +08:00
|
|
|
void Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t> &indexes,
|
|
|
|
Mangled::NamePreference name_preference) const {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
const size_t num_symbols = GetNumSymbols();
|
2010-10-08 12:20:14 +08:00
|
|
|
// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
|
2010-06-09 00:52:24 +08:00
|
|
|
s->Indent();
|
2014-03-04 03:15:20 +08:00
|
|
|
s->Printf("Symtab %" PRIu64 " symbol indexes (%" PRIu64 " symbols total):\n",
|
|
|
|
(uint64_t)indexes.size(), (uint64_t)m_symbols.size());
|
2010-06-09 00:52:24 +08:00
|
|
|
s->IndentMore();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (!indexes.empty()) {
|
|
|
|
std::vector<uint32_t>::const_iterator pos;
|
|
|
|
std::vector<uint32_t>::const_iterator end = indexes.end();
|
|
|
|
DumpSymbolHeader(s);
|
|
|
|
for (pos = indexes.begin(); pos != end; ++pos) {
|
2013-01-26 02:06:21 +08:00
|
|
|
size_t idx = *pos;
|
2010-06-09 00:52:24 +08:00
|
|
|
if (idx < num_symbols) {
|
|
|
|
s->Indent();
|
2019-11-07 22:47:01 +08:00
|
|
|
m_symbols[idx].Dump(s, target, idx, name_preference);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
s->IndentLess();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Symtab::DumpSymbolHeader(Stream *s) {
|
|
|
|
s->Indent(" Debug symbol\n");
|
|
|
|
s->Indent(" |Synthetic symbol\n");
|
|
|
|
s->Indent(" ||Externally Visible\n");
|
|
|
|
s->Indent(" |||\n");
|
2015-02-26 01:22:05 +08:00
|
|
|
s->Indent("Index UserID DSX Type File Address/Value Load "
|
|
|
|
"Address Size Flags Name\n");
|
|
|
|
s->Indent("------- ------ --- --------------- ------------------ "
|
|
|
|
"------------------ ------------------ ---------- "
|
|
|
|
"----------------------------------\n");
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2010-09-08 01:36:17 +08:00
|
|
|
static int CompareSymbolID(const void *key, const void *p) {
|
2015-05-13 08:25:54 +08:00
|
|
|
const user_id_t match_uid = *(const user_id_t *)key;
|
|
|
|
const user_id_t symbol_uid = ((const Symbol *)p)->GetID();
|
2010-09-08 01:36:17 +08:00
|
|
|
if (match_uid < symbol_uid)
|
|
|
|
return -1;
|
|
|
|
if (match_uid > symbol_uid)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Symbol *Symtab::FindSymbolByID(lldb::user_id_t symbol_uid) const {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2010-09-08 01:36:17 +08:00
|
|
|
Symbol *symbol =
|
|
|
|
(Symbol *)::bsearch(&symbol_uid, &m_symbols[0], m_symbols.size(),
|
2015-05-13 08:25:54 +08:00
|
|
|
sizeof(m_symbols[0]), CompareSymbolID);
|
2010-09-08 01:36:17 +08:00
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
|
2013-01-26 02:06:21 +08:00
|
|
|
Symbol *Symtab::SymbolAtIndex(size_t idx) {
|
2010-10-08 12:20:14 +08:00
|
|
|
// Clients should grab the mutex from this symbol table and lock it manually
|
|
|
|
// when calling this function to avoid performance issues.
|
2010-06-09 00:52:24 +08:00
|
|
|
if (idx < m_symbols.size())
|
|
|
|
return &m_symbols[idx];
|
2014-04-20 21:17:36 +08:00
|
|
|
return nullptr;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2013-01-26 02:06:21 +08:00
|
|
|
const Symbol *Symtab::SymbolAtIndex(size_t idx) const {
|
2010-10-08 12:20:14 +08:00
|
|
|
// Clients should grab the mutex from this symbol table and lock it manually
|
|
|
|
// when calling this function to avoid performance issues.
|
2010-06-09 00:52:24 +08:00
|
|
|
if (idx < m_symbols.size())
|
|
|
|
return &m_symbols[idx];
|
2014-04-20 21:17:36 +08:00
|
|
|
return nullptr;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
static bool lldb_skip_name(llvm::StringRef mangled,
|
|
|
|
Mangled::ManglingScheme scheme) {
|
|
|
|
switch (scheme) {
|
|
|
|
case Mangled::eManglingSchemeItanium: {
|
|
|
|
if (mangled.size() < 3 || !mangled.startswith("_Z"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Avoid the following types of symbols in the index.
|
|
|
|
switch (mangled[2]) {
|
|
|
|
case 'G': // guard variables
|
|
|
|
case 'T': // virtual tables, VTT structures, typeinfo structures + names
|
|
|
|
case 'Z': // named local entities (if we eventually handle
|
|
|
|
// eSymbolTypeData, we will want this back)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Include this name in the index.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// No filters for this scheme yet. Include all names in indexing.
|
|
|
|
case Mangled::eManglingSchemeMSVC:
|
[lldb] Enable Rust v0 symbol demangling
Rust's v0 name mangling scheme [1] is easy to disambiguate from other
name mangling schemes because symbols always start with `_R`. The llvm
Demangle library supports demangling the Rust v0 scheme. Use it to
demangle Rust symbols.
Added unit tests that check simple symbols. Ran LLDB built with this
patch to debug some Rust programs compiled with the v0 name mangling
scheme. Confirmed symbol names were demangled as expected.
Note: enabling the new name mangling scheme requires a nightly
toolchain:
```
$ cat main.rs
fn main() {
println!("Hello world!");
}
$ $(rustup which --toolchain nightly rustc) -Z symbol-mangling-version=v0 main.rs -g
$ /home/asm/hacking/llvm/build/bin/lldb ./main --one-line 'b main.rs:2'
(lldb) target create "./main"
Current executable set to '/home/asm/hacking/llvm/rust/main' (x86_64).
(lldb) b main.rs:2
Breakpoint 1: where = main`main::main + 4 at main.rs:2:5, address = 0x00000000000076a4
(lldb) r
Process 948449 launched: '/home/asm/hacking/llvm/rust/main' (x86_64)
warning: (x86_64) /lib64/libgcc_s.so.1 No LZMA support found for reading .gnu_debugdata section
Process 948449 stopped
* thread #1, name = 'main', stop reason = breakpoint 1.1
frame #0: 0x000055555555b6a4 main`main::main at main.rs:2:5
1 fn main() {
-> 2 println!("Hello world!");
3 }
(lldb) bt
error: need to add support for DW_TAG_base_type '()' encoded with DW_ATE = 0x7, bit_size = 0
* thread #1, name = 'main', stop reason = breakpoint 1.1
* frame #0: 0x000055555555b6a4 main`main::main at main.rs:2:5
frame #1: 0x000055555555b78b main`<fn() as core::ops::function::FnOnce<()>>::call_once((null)=(main`main::main at main.rs:1), (null)=<unavailable>) at function.rs:227:5
frame #2: 0x000055555555b66e main`std::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>(f=(main`main::main at main.rs:1)) at backtrace.rs:125:18
frame #3: 0x000055555555b851 main`std::rt::lang_start::<()>::{closure#0} at rt.rs:49:18
frame #4: 0x000055555556c9f9 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] core::ops::function::impls::_$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::h04259e4a34d07c2f at function.rs:259:13
frame #5: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panicking::try::do_call::hb8da45704d5cfbbf at panicking.rs:401:40
frame #6: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panicking::try::h4beadc19a78fec52 at panicking.rs:365:19
frame #7: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panic::catch_unwind::hc58016cd36ba81a4 at panic.rs:433:14
frame #8: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a at rt.rs:34:21
frame #9: 0x000055555555b830 main`std::rt::lang_start::<()>(main=(main`main::main at main.rs:1), argc=1, argv=0x00007fffffffcb18) at rt.rs:48:5
frame #10: 0x000055555555b6fc main`main + 28
frame #11: 0x00007ffff73f2493 libc.so.6`__libc_start_main + 243
frame #12: 0x000055555555b59e main`_start + 46
(lldb)
```
[1]: https://github.com/rust-lang/rust/issues/60705
Reviewed By: clayborg, teemperor
Differential Revision: https://reviews.llvm.org/D104054
2021-06-21 23:56:55 +08:00
|
|
|
case Mangled::eManglingSchemeRustV0:
|
2021-11-11 17:42:14 +08:00
|
|
|
case Mangled::eManglingSchemeD:
|
[lldb] Enable Rust v0 symbol demangling
Rust's v0 name mangling scheme [1] is easy to disambiguate from other
name mangling schemes because symbols always start with `_R`. The llvm
Demangle library supports demangling the Rust v0 scheme. Use it to
demangle Rust symbols.
Added unit tests that check simple symbols. Ran LLDB built with this
patch to debug some Rust programs compiled with the v0 name mangling
scheme. Confirmed symbol names were demangled as expected.
Note: enabling the new name mangling scheme requires a nightly
toolchain:
```
$ cat main.rs
fn main() {
println!("Hello world!");
}
$ $(rustup which --toolchain nightly rustc) -Z symbol-mangling-version=v0 main.rs -g
$ /home/asm/hacking/llvm/build/bin/lldb ./main --one-line 'b main.rs:2'
(lldb) target create "./main"
Current executable set to '/home/asm/hacking/llvm/rust/main' (x86_64).
(lldb) b main.rs:2
Breakpoint 1: where = main`main::main + 4 at main.rs:2:5, address = 0x00000000000076a4
(lldb) r
Process 948449 launched: '/home/asm/hacking/llvm/rust/main' (x86_64)
warning: (x86_64) /lib64/libgcc_s.so.1 No LZMA support found for reading .gnu_debugdata section
Process 948449 stopped
* thread #1, name = 'main', stop reason = breakpoint 1.1
frame #0: 0x000055555555b6a4 main`main::main at main.rs:2:5
1 fn main() {
-> 2 println!("Hello world!");
3 }
(lldb) bt
error: need to add support for DW_TAG_base_type '()' encoded with DW_ATE = 0x7, bit_size = 0
* thread #1, name = 'main', stop reason = breakpoint 1.1
* frame #0: 0x000055555555b6a4 main`main::main at main.rs:2:5
frame #1: 0x000055555555b78b main`<fn() as core::ops::function::FnOnce<()>>::call_once((null)=(main`main::main at main.rs:1), (null)=<unavailable>) at function.rs:227:5
frame #2: 0x000055555555b66e main`std::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>(f=(main`main::main at main.rs:1)) at backtrace.rs:125:18
frame #3: 0x000055555555b851 main`std::rt::lang_start::<()>::{closure#0} at rt.rs:49:18
frame #4: 0x000055555556c9f9 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] core::ops::function::impls::_$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::h04259e4a34d07c2f at function.rs:259:13
frame #5: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panicking::try::do_call::hb8da45704d5cfbbf at panicking.rs:401:40
frame #6: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panicking::try::h4beadc19a78fec52 at panicking.rs:365:19
frame #7: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panic::catch_unwind::hc58016cd36ba81a4 at panic.rs:433:14
frame #8: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a at rt.rs:34:21
frame #9: 0x000055555555b830 main`std::rt::lang_start::<()>(main=(main`main::main at main.rs:1), argc=1, argv=0x00007fffffffcb18) at rt.rs:48:5
frame #10: 0x000055555555b6fc main`main + 28
frame #11: 0x00007ffff73f2493 libc.so.6`__libc_start_main + 243
frame #12: 0x000055555555b59e main`_start + 46
(lldb)
```
[1]: https://github.com/rust-lang/rust/issues/60705
Reviewed By: clayborg, teemperor
Differential Revision: https://reviews.llvm.org/D104054
2021-06-21 23:56:55 +08:00
|
|
|
return false;
|
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
// Don't try and demangle things we can't categorize.
|
|
|
|
case Mangled::eManglingSchemeNone:
|
|
|
|
return true;
|
|
|
|
}
|
2018-09-03 20:57:54 +08:00
|
|
|
llvm_unreachable("unknown scheme!");
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
void Symtab::InitNameIndexes() {
|
2010-10-08 12:20:14 +08:00
|
|
|
// Protected function, no need to lock mutex...
|
|
|
|
if (!m_name_indexes_computed) {
|
|
|
|
m_name_indexes_computed = true;
|
2021-10-22 07:01:00 +08:00
|
|
|
ElapsedTime elapsed(m_objfile->GetModule()->GetSymtabIndexTime());
|
2020-12-22 05:41:57 +08:00
|
|
|
LLDB_SCOPED_TIMER();
|
2021-06-04 03:14:20 +08:00
|
|
|
|
2021-06-11 05:55:25 +08:00
|
|
|
// Collect all loaded language plugins.
|
|
|
|
std::vector<Language *> languages;
|
|
|
|
Language::ForEach([&languages](Language *l) {
|
|
|
|
languages.push_back(l);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
2021-06-04 03:14:20 +08:00
|
|
|
auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
|
|
|
|
auto &basename_to_index =
|
|
|
|
GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
|
|
|
|
auto &method_to_index =
|
|
|
|
GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
|
|
|
|
auto &selector_to_index =
|
|
|
|
GetNameToSymbolIndexMap(lldb::eFunctionNameTypeSelector);
|
2010-10-08 12:20:14 +08:00
|
|
|
// Create the name index vector to be able to quickly search by name
|
2013-04-03 10:00:15 +08:00
|
|
|
const size_t num_symbols = m_symbols.size();
|
2021-06-04 03:14:20 +08:00
|
|
|
name_to_index.Reserve(num_symbols);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
// The "const char *" in "class_contexts" and backlog::value_type::second
|
|
|
|
// must come from a ConstString::GetCString()
|
2013-04-03 10:00:15 +08:00
|
|
|
std::set<const char *> class_contexts;
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
std::vector<std::pair<NameToIndexMap::Entry, const char *>> backlog;
|
|
|
|
backlog.reserve(num_symbols / 2);
|
|
|
|
|
|
|
|
// Instantiation of the demangler is expensive, so better use a single one
|
|
|
|
// for all entries during batch processing.
|
|
|
|
RichManglingContext rmc;
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
for (uint32_t value = 0; value < num_symbols; ++value) {
|
|
|
|
Symbol *symbol = &m_symbols[value];
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// Don't let trampolines get into the lookup by name map If we ever need
|
|
|
|
// the trampoline symbols to be searchable by name we can remove this and
|
|
|
|
// then possibly add a new bool to any of the Symtab functions that
|
2021-07-13 01:03:46 +08:00
|
|
|
// lookup symbols by name to indicate if they want trampolines. We also
|
|
|
|
// don't want any synthetic symbols with auto generated names in the
|
|
|
|
// name lookups.
|
|
|
|
if (symbol->IsTrampoline() || symbol->IsSyntheticWithAutoGeneratedName())
|
2013-04-03 10:00:15 +08:00
|
|
|
continue;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
// If the symbol's name string matched a Mangled::ManglingScheme, it is
|
|
|
|
// stored in the mangled field.
|
|
|
|
Mangled &mangled = symbol->GetMangled();
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
if (ConstString name = mangled.GetMangledName()) {
|
2021-06-04 03:14:20 +08:00
|
|
|
name_to_index.Append(name, value);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-04-03 10:00:15 +08:00
|
|
|
if (symbol->ContainsLinkerAnnotations()) {
|
|
|
|
// If the symbol has linker annotations, also add the version without
|
2016-10-07 05:22:44 +08:00
|
|
|
// the annotations.
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
ConstString stripped = ConstString(
|
|
|
|
m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef()));
|
2021-06-04 03:14:20 +08:00
|
|
|
name_to_index.Append(stripped, value);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-03-04 18:25:22 +08:00
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
const SymbolType type = symbol->GetType();
|
|
|
|
if (type == eSymbolTypeCode || type == eSymbolTypeResolver) {
|
|
|
|
if (mangled.DemangleWithRichManglingInfo(rmc, lldb_skip_name))
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
RegisterMangledNameEntry(value, class_contexts, backlog, rmc);
|
2010-10-08 12:20:14 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
// Symbol name strings that didn't match a Mangled::ManglingScheme, are
|
|
|
|
// stored in the demangled field.
|
2020-01-31 13:55:18 +08:00
|
|
|
if (ConstString name = mangled.GetDemangledName()) {
|
2021-06-04 03:14:20 +08:00
|
|
|
name_to_index.Append(name, value);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-04-03 10:00:15 +08:00
|
|
|
if (symbol->ContainsLinkerAnnotations()) {
|
|
|
|
// If the symbol has linker annotations, also add the version without
|
2016-10-07 05:22:44 +08:00
|
|
|
// the annotations.
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
name = ConstString(
|
|
|
|
m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef()));
|
2021-06-04 03:14:20 +08:00
|
|
|
name_to_index.Append(name, value);
|
2013-04-03 10:00:15 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
// If the demangled name turns out to be an ObjC name, and is a category
|
|
|
|
// name, add the version without categories to the index too.
|
2021-06-11 05:55:25 +08:00
|
|
|
for (Language *lang : languages) {
|
|
|
|
for (auto variant : lang->GetMethodNameVariants(name)) {
|
|
|
|
if (variant.GetType() & lldb::eFunctionNameTypeSelector)
|
|
|
|
selector_to_index.Append(variant.GetName(), value);
|
|
|
|
else if (variant.GetType() & lldb::eFunctionNameTypeFull)
|
|
|
|
name_to_index.Append(variant.GetName(), value);
|
|
|
|
else if (variant.GetType() & lldb::eFunctionNameTypeMethod)
|
|
|
|
method_to_index.Append(variant.GetName(), value);
|
|
|
|
else if (variant.GetType() & lldb::eFunctionNameTypeBase)
|
|
|
|
basename_to_index.Append(variant.GetName(), value);
|
|
|
|
}
|
2013-04-03 10:00:15 +08:00
|
|
|
}
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
for (const auto &record : backlog) {
|
|
|
|
RegisterBacklogEntry(record.first, record.second, class_contexts);
|
2011-12-04 04:02:42 +08:00
|
|
|
}
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
|
2021-06-04 03:14:20 +08:00
|
|
|
name_to_index.Sort();
|
|
|
|
name_to_index.SizeToFit();
|
|
|
|
selector_to_index.Sort();
|
|
|
|
selector_to_index.SizeToFit();
|
|
|
|
basename_to_index.Sort();
|
|
|
|
basename_to_index.SizeToFit();
|
|
|
|
method_to_index.Sort();
|
|
|
|
method_to_index.SizeToFit();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2011-12-04 04:02:42 +08:00
|
|
|
}
|
|
|
|
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
void Symtab::RegisterMangledNameEntry(
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
uint32_t value, std::set<const char *> &class_contexts,
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog,
|
|
|
|
RichManglingContext &rmc) {
|
|
|
|
// Only register functions that have a base name.
|
|
|
|
rmc.ParseFunctionBaseName();
|
|
|
|
llvm::StringRef base_name = rmc.GetBufferRef();
|
|
|
|
if (base_name.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// The base name will be our entry's name.
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
NameToIndexMap::Entry entry(ConstString(base_name), value);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
|
|
|
|
rmc.ParseFunctionDeclContextName();
|
|
|
|
llvm::StringRef decl_context = rmc.GetBufferRef();
|
|
|
|
|
|
|
|
// Register functions with no context.
|
|
|
|
if (decl_context.empty()) {
|
|
|
|
// This has to be a basename
|
2021-06-04 03:14:20 +08:00
|
|
|
auto &basename_to_index =
|
|
|
|
GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
|
|
|
|
basename_to_index.Append(entry);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
// If there is no context (no namespaces or class scopes that come before
|
|
|
|
// the function name) then this also could be a fullname.
|
2021-06-04 03:14:20 +08:00
|
|
|
auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
|
|
|
|
name_to_index.Append(entry);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure we have a pool-string pointer and see if we already know the
|
|
|
|
// context name.
|
|
|
|
const char *decl_context_ccstr = ConstString(decl_context).GetCString();
|
|
|
|
auto it = class_contexts.find(decl_context_ccstr);
|
|
|
|
|
2021-06-04 03:14:20 +08:00
|
|
|
auto &method_to_index =
|
|
|
|
GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
// Register constructors and destructors. They are methods and create
|
|
|
|
// declaration contexts.
|
|
|
|
if (rmc.IsCtorOrDtor()) {
|
2021-06-04 03:14:20 +08:00
|
|
|
method_to_index.Append(entry);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
if (it == class_contexts.end())
|
|
|
|
class_contexts.insert(it, decl_context_ccstr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register regular methods with a known declaration context.
|
|
|
|
if (it != class_contexts.end()) {
|
2021-06-04 03:14:20 +08:00
|
|
|
method_to_index.Append(entry);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Regular methods in unknown declaration contexts are put to the backlog. We
|
|
|
|
// will revisit them once we processed all remaining symbols.
|
|
|
|
backlog.push_back(std::make_pair(entry, decl_context_ccstr));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Symtab::RegisterBacklogEntry(
|
|
|
|
const NameToIndexMap::Entry &entry, const char *decl_context,
|
|
|
|
const std::set<const char *> &class_contexts) {
|
2021-06-04 03:14:20 +08:00
|
|
|
auto &method_to_index =
|
|
|
|
GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
auto it = class_contexts.find(decl_context);
|
|
|
|
if (it != class_contexts.end()) {
|
2021-06-04 03:14:20 +08:00
|
|
|
method_to_index.Append(entry);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
} else {
|
|
|
|
// If we got here, we have something that had a context (was inside
|
|
|
|
// a namespace or class) yet we don't know the entry
|
2021-06-04 03:14:20 +08:00
|
|
|
method_to_index.Append(entry);
|
|
|
|
auto &basename_to_index =
|
|
|
|
GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
|
|
|
|
basename_to_index.Append(entry);
|
Use rich mangling information in Symtab::InitNameIndexes()
Summary:
I set up a new review, because not all the code I touched was marked as a change in old one anymore.
In preparation for this review, there were two earlier ones:
* https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes
* https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function
Primary goals for this patch are:
(1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index.
(2) Provide a uniform interface.
(3) Improve indexing performance.
The central implementation in this patch is our new function for explicit demangling:
```
const RichManglingInfo *
Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *)
```
It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are:
* `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`).
* `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing.
The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`.
Future potential:
* `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.)
* The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages.
One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get<ParserT>()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess).
First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think.
Reviewers: labath, jingham, JDevlieghere, erik.pilkington
Subscribers: zturner, clayborg, mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D50071
llvm-svn: 339291
2018-08-09 05:57:37 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-28 08:51:06 +08:00
|
|
|
void Symtab::PreloadSymbols() {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
|
|
|
InitNameIndexes();
|
|
|
|
}
|
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes,
|
|
|
|
bool add_demangled, bool add_mangled,
|
|
|
|
NameToIndexMap &name_to_index_map) const {
|
2020-12-22 05:41:57 +08:00
|
|
|
LLDB_SCOPED_TIMER();
|
2010-09-11 11:13:28 +08:00
|
|
|
if (add_demangled || add_mangled) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
// Create the name index vector to be able to quickly search by name
|
|
|
|
const size_t num_indexes = indexes.size();
|
2013-07-10 09:23:25 +08:00
|
|
|
for (size_t i = 0; i < num_indexes; ++i) {
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
uint32_t value = indexes[i];
|
2010-06-09 00:52:24 +08:00
|
|
|
assert(i < m_symbols.size());
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
const Symbol *symbol = &m_symbols[value];
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-04 04:02:42 +08:00
|
|
|
const Mangled &mangled = symbol->GetMangled();
|
|
|
|
if (add_demangled) {
|
2020-01-31 13:55:18 +08:00
|
|
|
if (ConstString name = mangled.GetDemangledName())
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
name_to_index_map.Append(name, value);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2011-12-04 04:02:42 +08:00
|
|
|
if (add_mangled) {
|
Make UniqueCStringMap work with non-default-constructible types and other improvements/cleanups
Summary:
The motivation for this was me wanting to make the validity of dwarf
DIERefs explicit (via llvm::Optional<DIERef>). This meant that the class
would no longer have a default constructor. As the DIERef was being
stored in a UniqueCStringMap, this meant that this container (like all
standard containers) needed to work with non-default-constructible types
too.
This part is achieved by removing the default constructors for the map
entry types, and providing appropriate comparison overloads so that we
can search for map entries without constructing a dummy entry. While
doing that, I took the opportunity to modernize the code, and add some
tests. Functions that were completely unused are deleted.
This required also some changes in the Symtab code, as it was default
constructing map entries, which was not impossible even though its
value type was default-constructible. Technically, these changes could
be avoided with some SFINAE on the entry type, but I felt that the code
is cleaner this way anyway.
Reviewers: JDevlieghere, sgraenitz
Subscribers: mgorny, aprantl, lldb-commits
Differential Revision: https://reviews.llvm.org/D63268
llvm-svn: 363357
2019-06-14 14:33:31 +08:00
|
|
|
if (ConstString name = mangled.GetMangledName())
|
|
|
|
name_to_index_map.Append(name, value);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
uint32_t Symtab::AppendSymbolIndexesWithType(SymbolType symbol_type,
|
|
|
|
std::vector<uint32_t> &indexes,
|
2011-01-20 14:08:59 +08:00
|
|
|
uint32_t start_idx,
|
2010-06-09 00:52:24 +08:00
|
|
|
uint32_t end_index) const {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
|
|
|
|
|
|
|
uint32_t prev_size = indexes.size();
|
|
|
|
|
2011-01-20 14:08:59 +08:00
|
|
|
const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-01-20 14:08:59 +08:00
|
|
|
for (uint32_t i = start_idx; i < count; ++i) {
|
2010-06-09 00:52:24 +08:00
|
|
|
if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type)
|
|
|
|
indexes.push_back(i);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
return indexes.size() - prev_size;
|
|
|
|
}
|
|
|
|
|
2011-01-20 14:08:59 +08:00
|
|
|
uint32_t Symtab::AppendSymbolIndexesWithTypeAndFlagsValue(
|
|
|
|
SymbolType symbol_type, uint32_t flags_value,
|
|
|
|
std::vector<uint32_t> &indexes, uint32_t start_idx,
|
|
|
|
uint32_t end_index) const {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2011-01-20 14:08:59 +08:00
|
|
|
|
|
|
|
uint32_t prev_size = indexes.size();
|
|
|
|
|
|
|
|
const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);
|
|
|
|
|
|
|
|
for (uint32_t i = start_idx; i < count; ++i) {
|
|
|
|
if ((symbol_type == eSymbolTypeAny ||
|
|
|
|
m_symbols[i].GetType() == symbol_type) &&
|
|
|
|
m_symbols[i].GetFlags() == flags_value)
|
|
|
|
indexes.push_back(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
return indexes.size() - prev_size;
|
|
|
|
}
|
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
uint32_t Symtab::AppendSymbolIndexesWithType(SymbolType symbol_type,
|
|
|
|
Debug symbol_debug_type,
|
|
|
|
Visibility symbol_visibility,
|
|
|
|
std::vector<uint32_t> &indexes,
|
|
|
|
uint32_t start_idx,
|
|
|
|
uint32_t end_index) const {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
uint32_t prev_size = indexes.size();
|
|
|
|
|
|
|
|
const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);
|
|
|
|
|
|
|
|
for (uint32_t i = start_idx; i < count; ++i) {
|
|
|
|
if (symbol_type == eSymbolTypeAny ||
|
|
|
|
m_symbols[i].GetType() == symbol_type) {
|
|
|
|
if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
|
|
|
|
indexes.push_back(i);
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
|
|
|
|
return indexes.size() - prev_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Symtab::GetIndexForSymbol(const Symbol *symbol) const {
|
2015-02-26 06:41:34 +08:00
|
|
|
if (!m_symbols.empty()) {
|
|
|
|
const Symbol *first_symbol = &m_symbols[0];
|
|
|
|
if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size())
|
|
|
|
return symbol - first_symbol;
|
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
struct SymbolSortInfo {
|
|
|
|
const bool sort_by_load_addr;
|
|
|
|
const Symbol *symbols;
|
|
|
|
};
|
|
|
|
|
2010-06-17 01:34:05 +08:00
|
|
|
namespace {
|
|
|
|
struct SymbolIndexComparator {
|
|
|
|
const std::vector<Symbol> &symbols;
|
2012-05-01 09:34:15 +08:00
|
|
|
std::vector<lldb::addr_t> &addr_cache;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-05-01 09:34:15 +08:00
|
|
|
// Getting from the symbol to the Address to the File Address involves some
|
2018-05-01 00:49:04 +08:00
|
|
|
// work. Since there are potentially many symbols here, and we're using this
|
|
|
|
// for sorting so we're going to be computing the address many times, cache
|
|
|
|
// that in addr_cache. The array passed in has to be the same size as the
|
|
|
|
// symbols array passed into the member variable symbols, and should be
|
|
|
|
// initialized with LLDB_INVALID_ADDRESS.
|
2012-05-01 09:34:15 +08:00
|
|
|
// NOTE: You have to make addr_cache externally and pass it in because
|
2015-06-26 05:46:34 +08:00
|
|
|
// std::stable_sort
|
2010-06-17 01:34:05 +08:00
|
|
|
// makes copies of the comparator it is initially passed in, and you end up
|
2018-05-01 00:49:04 +08:00
|
|
|
// spending huge amounts of time copying this array...
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-17 01:34:05 +08:00
|
|
|
SymbolIndexComparator(const std::vector<Symbol> &s,
|
|
|
|
std::vector<lldb::addr_t> &a)
|
2012-05-01 09:34:15 +08:00
|
|
|
: symbols(s), addr_cache(a) {
|
2010-06-17 01:34:05 +08:00
|
|
|
assert(symbols.size() == addr_cache.size());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-17 01:34:05 +08:00
|
|
|
bool operator()(uint32_t index_a, uint32_t index_b) {
|
2012-05-01 09:34:15 +08:00
|
|
|
addr_t value_a = addr_cache[index_a];
|
2010-06-17 01:34:05 +08:00
|
|
|
if (value_a == LLDB_INVALID_ADDRESS) {
|
|
|
|
value_a = symbols[index_a].GetAddressRef().GetFileAddress();
|
|
|
|
addr_cache[index_a] = value_a;
|
2010-06-11 07:36:31 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
addr_t value_b = addr_cache[index_b];
|
|
|
|
if (value_b == LLDB_INVALID_ADDRESS) {
|
|
|
|
value_b = symbols[index_b].GetAddressRef().GetFileAddress();
|
2016-05-19 13:13:57 +08:00
|
|
|
addr_cache[index_b] = value_b;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (value_a == value_b) {
|
2010-06-17 08:51:12 +08:00
|
|
|
// The if the values are equal, use the original symbol user ID
|
2012-05-01 09:34:15 +08:00
|
|
|
lldb::user_id_t uid_a = symbols[index_a].GetID();
|
|
|
|
lldb::user_id_t uid_b = symbols[index_b].GetID();
|
|
|
|
if (uid_a < uid_b)
|
2010-06-09 00:52:24 +08:00
|
|
|
return true;
|
|
|
|
if (uid_a > uid_b)
|
2010-06-17 01:34:05 +08:00
|
|
|
return false;
|
2010-06-09 00:52:24 +08:00
|
|
|
return false;
|
|
|
|
} else if (value_a < value_b)
|
|
|
|
return true;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-17 01:34:05 +08:00
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
};
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
void Symtab::SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
|
|
|
|
bool remove_duplicates) const {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2020-12-22 05:41:57 +08:00
|
|
|
LLDB_SCOPED_TIMER();
|
2011-09-11 08:20:09 +08:00
|
|
|
// No need to sort if we have zero or one items...
|
2010-10-08 12:20:14 +08:00
|
|
|
if (indexes.size() <= 1)
|
2010-06-09 00:52:24 +08:00
|
|
|
return;
|
|
|
|
|
2011-09-11 08:20:09 +08:00
|
|
|
// Sort the indexes in place using std::stable_sort.
|
2019-01-09 07:25:06 +08:00
|
|
|
// NOTE: The use of std::stable_sort instead of llvm::sort here is strictly
|
|
|
|
// for performance, not correctness. The indexes vector tends to be "close"
|
|
|
|
// to sorted, which the stable sort handles better.
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
std::vector<lldb::addr_t> addr_cache(m_symbols.size(), LLDB_INVALID_ADDRESS);
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2011-09-11 08:20:09 +08:00
|
|
|
SymbolIndexComparator comparator(m_symbols, addr_cache);
|
2010-09-11 11:13:28 +08:00
|
|
|
std::stable_sort(indexes.begin(), indexes.end(), comparator);
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
// Remove any duplicates if requested
|
2017-08-01 09:29:55 +08:00
|
|
|
if (remove_duplicates) {
|
|
|
|
auto last = std::unique(indexes.begin(), indexes.end());
|
|
|
|
indexes.erase(last, indexes.end());
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2021-07-13 01:03:46 +08:00
|
|
|
uint32_t Symtab::GetNameIndexes(ConstString symbol_name,
|
|
|
|
std::vector<uint32_t> &indexes) {
|
|
|
|
auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
|
|
|
|
const uint32_t count = name_to_index.GetValues(symbol_name, indexes);
|
|
|
|
if (count)
|
|
|
|
return count;
|
|
|
|
// Synthetic symbol names are not added to the name indexes, but they start
|
|
|
|
// with a prefix and end with a the symbol UserID. This allows users to find
|
|
|
|
// these symbols without having to add them to the name indexes. These
|
|
|
|
// queries will not happen very often since the names don't mean anything, so
|
|
|
|
// performance is not paramount in this case.
|
|
|
|
llvm::StringRef name = symbol_name.GetStringRef();
|
|
|
|
// String the synthetic prefix if the name starts with it.
|
|
|
|
if (!name.consume_front(Symbol::GetSyntheticSymbolPrefix()))
|
|
|
|
return 0; // Not a synthetic symbol name
|
|
|
|
|
|
|
|
// Extract the user ID from the symbol name
|
|
|
|
unsigned long long uid = 0;
|
|
|
|
if (getAsUnsignedInteger(name, /*Radix=*/10, uid))
|
|
|
|
return 0; // Failed to extract the user ID as an integer
|
|
|
|
Symbol *symbol = FindSymbolByID(uid);
|
|
|
|
if (symbol == nullptr)
|
|
|
|
return 0;
|
|
|
|
const uint32_t symbol_idx = GetIndexForSymbol(symbol);
|
|
|
|
if (symbol_idx == UINT32_MAX)
|
|
|
|
return 0;
|
|
|
|
indexes.push_back(symbol_idx);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-03-07 05:22:25 +08:00
|
|
|
uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name,
|
2010-09-11 11:13:28 +08:00
|
|
|
std::vector<uint32_t> &indexes) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2020-12-22 05:41:57 +08:00
|
|
|
LLDB_SCOPED_TIMER();
|
2010-09-11 11:13:28 +08:00
|
|
|
if (symbol_name) {
|
|
|
|
if (!m_name_indexes_computed)
|
|
|
|
InitNameIndexes();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2021-07-13 01:03:46 +08:00
|
|
|
return GetNameIndexes(symbol_name, indexes);
|
2010-09-11 11:13:28 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-03-07 05:22:25 +08:00
|
|
|
uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name,
|
2010-09-11 11:13:28 +08:00
|
|
|
Debug symbol_debug_type,
|
|
|
|
Visibility symbol_visibility,
|
2010-06-09 00:52:24 +08:00
|
|
|
std::vector<uint32_t> &indexes) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2010-09-11 11:13:28 +08:00
|
|
|
|
2020-12-22 05:41:57 +08:00
|
|
|
LLDB_SCOPED_TIMER();
|
2010-06-09 00:52:24 +08:00
|
|
|
if (symbol_name) {
|
|
|
|
const size_t old_size = indexes.size();
|
|
|
|
if (!m_name_indexes_computed)
|
|
|
|
InitNameIndexes();
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2011-09-11 08:20:09 +08:00
|
|
|
std::vector<uint32_t> all_name_indexes;
|
2016-01-26 08:58:09 +08:00
|
|
|
const size_t name_match_count =
|
2021-07-13 01:03:46 +08:00
|
|
|
GetNameIndexes(symbol_name, all_name_indexes);
|
2016-01-26 08:58:09 +08:00
|
|
|
for (size_t i = 0; i < name_match_count; ++i) {
|
2011-09-11 08:20:09 +08:00
|
|
|
if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type,
|
|
|
|
symbol_visibility))
|
|
|
|
indexes.push_back(all_name_indexes[i]);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
return indexes.size() - old_size;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
return 0;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
uint32_t
|
2019-03-07 05:22:25 +08:00
|
|
|
Symtab::AppendSymbolIndexesWithNameAndType(ConstString symbol_name,
|
2010-09-11 11:13:28 +08:00
|
|
|
SymbolType symbol_type,
|
|
|
|
std::vector<uint32_t> &indexes) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0) {
|
|
|
|
std::vector<uint32_t>::iterator pos = indexes.begin();
|
2013-06-20 03:04:53 +08:00
|
|
|
while (pos != indexes.end()) {
|
2010-09-11 11:13:28 +08:00
|
|
|
if (symbol_type == eSymbolTypeAny ||
|
|
|
|
m_symbols[*pos].GetType() == symbol_type)
|
2015-07-09 06:32:23 +08:00
|
|
|
++pos;
|
|
|
|
else
|
2010-09-11 11:13:28 +08:00
|
|
|
pos = indexes.erase(pos);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
return indexes.size();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
uint32_t Symtab::AppendSymbolIndexesWithNameAndType(
|
2019-03-07 05:22:25 +08:00
|
|
|
ConstString symbol_name, SymbolType symbol_type,
|
2010-09-11 11:13:28 +08:00
|
|
|
Debug symbol_debug_type, Visibility symbol_visibility,
|
2010-06-09 00:52:24 +08:00
|
|
|
std::vector<uint32_t> &indexes) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type,
|
2013-01-26 02:06:21 +08:00
|
|
|
symbol_visibility, indexes) > 0) {
|
|
|
|
std::vector<uint32_t>::iterator pos = indexes.begin();
|
2010-06-09 00:52:24 +08:00
|
|
|
while (pos != indexes.end()) {
|
|
|
|
if (symbol_type == eSymbolTypeAny ||
|
|
|
|
m_symbols[*pos].GetType() == symbol_type)
|
2016-09-07 04:57:50 +08:00
|
|
|
++pos;
|
|
|
|
else
|
2010-09-11 11:13:28 +08:00
|
|
|
pos = indexes.erase(pos);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2014-04-20 21:17:36 +08:00
|
|
|
return indexes.size();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
|
|
|
|
const RegularExpression ®exp, SymbolType symbol_type,
|
|
|
|
std::vector<uint32_t> &indexes) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
uint32_t prev_size = indexes.size();
|
|
|
|
uint32_t sym_end = m_symbols.size();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
for (uint32_t i = 0; i < sym_end; i++) {
|
|
|
|
if (symbol_type == eSymbolTypeAny ||
|
|
|
|
m_symbols[i].GetType() == symbol_type) {
|
|
|
|
const char *name = m_symbols[i].GetName().AsCString();
|
2010-06-09 00:52:24 +08:00
|
|
|
if (name) {
|
2010-09-11 11:13:28 +08:00
|
|
|
if (regexp.Execute(name))
|
|
|
|
indexes.push_back(i);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
return indexes.size() - prev_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
|
|
|
|
const RegularExpression ®exp, SymbolType symbol_type,
|
|
|
|
Debug symbol_debug_type, Visibility symbol_visibility,
|
|
|
|
std::vector<uint32_t> &indexes) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
uint32_t prev_size = indexes.size();
|
2010-06-09 00:52:24 +08:00
|
|
|
uint32_t sym_end = m_symbols.size();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
for (uint32_t i = 0; i < sym_end; i++) {
|
|
|
|
if (symbol_type == eSymbolTypeAny ||
|
2010-06-09 00:52:24 +08:00
|
|
|
m_symbols[i].GetType() == symbol_type) {
|
2018-12-15 08:15:33 +08:00
|
|
|
if (!CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
|
2010-09-11 11:13:28 +08:00
|
|
|
continue;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
const char *name = m_symbols[i].GetName().AsCString();
|
|
|
|
if (name) {
|
2010-10-08 12:20:14 +08:00
|
|
|
if (regexp.Execute(name))
|
|
|
|
indexes.push_back(i);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
return indexes.size() - prev_size;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-09-11 11:13:28 +08:00
|
|
|
|
|
|
|
Symbol *Symtab::FindSymbolWithType(SymbolType symbol_type,
|
|
|
|
Debug symbol_debug_type,
|
|
|
|
Visibility symbol_visibility,
|
|
|
|
uint32_t &start_idx) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
const size_t count = m_symbols.size();
|
2013-01-26 02:06:21 +08:00
|
|
|
for (size_t idx = start_idx; idx < count; ++idx) {
|
2010-09-11 11:13:28 +08:00
|
|
|
if (symbol_type == eSymbolTypeAny ||
|
2010-06-09 00:52:24 +08:00
|
|
|
m_symbols[idx].GetType() == symbol_type) {
|
2010-09-11 11:13:28 +08:00
|
|
|
if (CheckSymbolAtIndex(idx, symbol_debug_type, symbol_visibility)) {
|
|
|
|
start_idx = idx;
|
|
|
|
return &m_symbols[idx];
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2019-10-18 03:56:40 +08:00
|
|
|
void
|
2019-03-07 05:22:25 +08:00
|
|
|
Symtab::FindAllSymbolsWithNameAndType(ConstString name,
|
2010-09-11 11:13:28 +08:00
|
|
|
SymbolType symbol_type,
|
|
|
|
std::vector<uint32_t> &symbol_indexes) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2020-12-22 05:41:57 +08:00
|
|
|
LLDB_SCOPED_TIMER();
|
2018-05-01 00:49:04 +08:00
|
|
|
// Initialize all of the lookup by name indexes before converting NAME to a
|
|
|
|
// uniqued string NAME_STR below.
|
2010-09-11 11:13:28 +08:00
|
|
|
if (!m_name_indexes_computed)
|
2010-06-09 00:52:24 +08:00
|
|
|
InitNameIndexes();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
if (name) {
|
2018-05-01 00:49:04 +08:00
|
|
|
// The string table did have a string that matched, but we need to check
|
|
|
|
// the symbols and match the symbol_type if any was given.
|
2010-09-11 11:13:28 +08:00
|
|
|
AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_indexes);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2019-10-18 03:56:40 +08:00
|
|
|
void Symtab::FindAllSymbolsWithNameAndType(
|
2019-03-07 05:22:25 +08:00
|
|
|
ConstString name, SymbolType symbol_type, Debug symbol_debug_type,
|
2010-09-11 11:13:28 +08:00
|
|
|
Visibility symbol_visibility, std::vector<uint32_t> &symbol_indexes) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2020-12-22 05:41:57 +08:00
|
|
|
LLDB_SCOPED_TIMER();
|
2018-05-01 00:49:04 +08:00
|
|
|
// Initialize all of the lookup by name indexes before converting NAME to a
|
|
|
|
// uniqued string NAME_STR below.
|
2010-10-08 12:20:14 +08:00
|
|
|
if (!m_name_indexes_computed)
|
2010-06-09 00:52:24 +08:00
|
|
|
InitNameIndexes();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
if (name) {
|
2018-05-01 00:49:04 +08:00
|
|
|
// The string table did have a string that matched, but we need to check
|
|
|
|
// the symbols and match the symbol_type if any was given.
|
2010-09-11 11:13:28 +08:00
|
|
|
AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
|
|
|
|
symbol_visibility, symbol_indexes);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2019-10-18 03:56:40 +08:00
|
|
|
void Symtab::FindAllSymbolsMatchingRexExAndType(
|
2010-09-11 11:13:28 +08:00
|
|
|
const RegularExpression ®ex, SymbolType symbol_type,
|
|
|
|
Debug symbol_debug_type, Visibility symbol_visibility,
|
2010-06-09 00:52:24 +08:00
|
|
|
std::vector<uint32_t> &symbol_indexes) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2010-09-11 11:13:28 +08:00
|
|
|
AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type,
|
2011-09-11 08:20:09 +08:00
|
|
|
symbol_visibility, symbol_indexes);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2019-03-07 05:22:25 +08:00
|
|
|
Symbol *Symtab::FindFirstSymbolWithNameAndType(ConstString name,
|
2010-09-11 11:13:28 +08:00
|
|
|
SymbolType symbol_type,
|
|
|
|
Debug symbol_debug_type,
|
|
|
|
Visibility symbol_visibility) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2020-12-22 05:41:57 +08:00
|
|
|
LLDB_SCOPED_TIMER();
|
2010-10-08 12:20:14 +08:00
|
|
|
if (!m_name_indexes_computed)
|
2010-06-09 00:52:24 +08:00
|
|
|
InitNameIndexes();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (name) {
|
|
|
|
std::vector<uint32_t> matching_indexes;
|
2018-05-01 00:49:04 +08:00
|
|
|
// The string table did have a string that matched, but we need to check
|
|
|
|
// the symbols and match the symbol_type if any was given.
|
2010-09-11 11:13:28 +08:00
|
|
|
if (AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
|
|
|
|
symbol_visibility,
|
|
|
|
matching_indexes)) {
|
2010-06-09 00:52:24 +08:00
|
|
|
std::vector<uint32_t>::const_iterator pos, end = matching_indexes.end();
|
|
|
|
for (pos = matching_indexes.begin(); pos != end; ++pos) {
|
|
|
|
Symbol *symbol = SymbolAtIndex(*pos);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (symbol->Compare(name, symbol_type))
|
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2014-04-20 21:17:36 +08:00
|
|
|
return nullptr;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
const Symtab *symtab;
|
|
|
|
const addr_t file_addr;
|
|
|
|
Symbol *match_symbol;
|
|
|
|
const uint32_t *match_index_ptr;
|
|
|
|
addr_t match_offset;
|
|
|
|
} SymbolSearchInfo;
|
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// Add all the section file start address & size to the RangeVector, recusively
|
|
|
|
// adding any children sections.
|
2016-04-13 12:32:49 +08:00
|
|
|
static void AddSectionsToRangeMap(SectionList *sectlist,
|
|
|
|
RangeVector<addr_t, addr_t> §ion_ranges) {
|
|
|
|
const int num_sections = sectlist->GetNumSections(0);
|
|
|
|
for (int i = 0; i < num_sections; i++) {
|
|
|
|
SectionSP sect_sp = sectlist->GetSectionAtIndex(i);
|
|
|
|
if (sect_sp) {
|
|
|
|
SectionList &child_sectlist = sect_sp->GetChildren();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-04-13 12:32:49 +08:00
|
|
|
// If this section has children, add the children to the RangeVector.
|
|
|
|
// Else add this section to the RangeVector.
|
|
|
|
if (child_sectlist.GetNumSections(0) > 0) {
|
|
|
|
AddSectionsToRangeMap(&child_sectlist, section_ranges);
|
|
|
|
} else {
|
|
|
|
size_t size = sect_sp->GetByteSize();
|
2016-04-23 06:35:08 +08:00
|
|
|
if (size > 0) {
|
|
|
|
addr_t base_addr = sect_sp->GetFileAddress();
|
|
|
|
RangeVector<addr_t, addr_t>::Entry entry;
|
|
|
|
entry.SetRangeBase(base_addr);
|
|
|
|
entry.SetByteSize(size);
|
|
|
|
section_ranges.Append(entry);
|
2016-04-13 12:32:49 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2016-04-13 12:32:49 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2016-04-13 12:32:49 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
void Symtab::InitAddressIndexes() {
|
2010-10-08 12:20:14 +08:00
|
|
|
// Protected function, no need to lock mutex...
|
2013-07-10 09:23:25 +08:00
|
|
|
if (!m_file_addr_to_index_computed && !m_symbols.empty()) {
|
|
|
|
m_file_addr_to_index_computed = true;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-07-10 09:23:25 +08:00
|
|
|
FileRangeToIndexMap::Entry entry;
|
2010-10-08 12:20:14 +08:00
|
|
|
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()) {
|
2012-03-08 05:03:09 +08:00
|
|
|
entry.SetRangeBase(pos->GetAddressRef().GetFileAddress());
|
2013-07-10 09:23:25 +08:00
|
|
|
entry.SetByteSize(pos->GetByteSize());
|
|
|
|
entry.data = std::distance(begin, pos);
|
2016-04-13 12:32:49 +08:00
|
|
|
m_file_addr_to_index.Append(entry);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
2013-07-10 09:23:25 +08:00
|
|
|
const size_t num_entries = m_file_addr_to_index.GetSize();
|
|
|
|
if (num_entries > 0) {
|
|
|
|
m_file_addr_to_index.Sort();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-04-13 12:32:49 +08:00
|
|
|
// Create a RangeVector with the start & size of all the sections for
|
|
|
|
// this objfile. We'll need to check this for any FileRangeToIndexMap
|
2018-05-01 00:49:04 +08:00
|
|
|
// entries with an uninitialized size, which could potentially be a large
|
|
|
|
// number so reconstituting the weak pointer is busywork when it is
|
|
|
|
// invariant information.
|
2016-04-13 12:32:49 +08:00
|
|
|
SectionList *sectlist = m_objfile->GetSectionList();
|
|
|
|
RangeVector<addr_t, addr_t> section_ranges;
|
2012-03-08 05:03:09 +08:00
|
|
|
if (sectlist) {
|
2016-04-13 12:32:49 +08:00
|
|
|
AddSectionsToRangeMap(sectlist, section_ranges);
|
2015-06-26 05:46:34 +08:00
|
|
|
section_ranges.Sort();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2016-04-13 12:32:49 +08:00
|
|
|
// Iterate through the FileRangeToIndexMap and fill in the size for any
|
|
|
|
// entries that didn't already have a size from the Symbol (e.g. if we
|
2015-06-26 05:46:34 +08:00
|
|
|
// have a plain linker symbol with an address only, instead of debug info
|
|
|
|
// where we get an address and a size and a type, etc.)
|
2016-04-13 21:32:06 +08:00
|
|
|
for (size_t i = 0; i < num_entries; i++) {
|
2016-04-13 12:32:49 +08:00
|
|
|
FileRangeToIndexMap::Entry *entry =
|
2015-06-26 05:46:34 +08:00
|
|
|
m_file_addr_to_index.GetMutableEntryAtIndex(i);
|
2019-11-12 21:48:32 +08:00
|
|
|
if (entry->GetByteSize() == 0) {
|
|
|
|
addr_t curr_base_addr = entry->GetRangeBase();
|
2016-04-13 12:32:49 +08:00
|
|
|
const RangeVector<addr_t, addr_t>::Entry *containing_section =
|
2013-07-10 09:23:25 +08:00
|
|
|
section_ranges.FindEntryThatContains(curr_base_addr);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-07-10 09:23:25 +08:00
|
|
|
// Use the end of the section as the default max size of the symbol
|
2016-04-13 12:32:49 +08:00
|
|
|
addr_t sym_size = 0;
|
|
|
|
if (containing_section) {
|
|
|
|
sym_size =
|
2013-07-10 09:23:25 +08:00
|
|
|
containing_section->GetByteSize() -
|
|
|
|
(entry->GetRangeBase() - containing_section->GetRangeBase());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2016-04-13 21:32:06 +08:00
|
|
|
for (size_t j = i; j < num_entries; j++) {
|
2013-07-10 09:23:25 +08:00
|
|
|
FileRangeToIndexMap::Entry *next_entry =
|
|
|
|
m_file_addr_to_index.GetMutableEntryAtIndex(j);
|
2016-04-13 12:32:49 +08:00
|
|
|
addr_t next_base_addr = next_entry->GetRangeBase();
|
|
|
|
if (next_base_addr > curr_base_addr) {
|
|
|
|
addr_t size_to_next_symbol = next_base_addr - curr_base_addr;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// Take the difference between this symbol and the next one as
|
|
|
|
// its size, if it is less than the size of the section.
|
2016-04-13 12:32:49 +08:00
|
|
|
if (sym_size == 0 || size_to_next_symbol < sym_size) {
|
|
|
|
sym_size = size_to_next_symbol;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
break;
|
2013-07-10 09:23:25 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2016-04-13 12:32:49 +08:00
|
|
|
if (sym_size > 0) {
|
|
|
|
entry->SetByteSize(sym_size);
|
|
|
|
Symbol &symbol = m_symbols[entry->data];
|
|
|
|
symbol.SetByteSize(sym_size);
|
2013-07-10 09:23:25 +08:00
|
|
|
symbol.SetSizeIsSynthesized(true);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-10-08 12:20:14 +08:00
|
|
|
}
|
2013-07-10 09:23:25 +08:00
|
|
|
}
|
2016-02-18 19:12:18 +08:00
|
|
|
|
2016-04-13 12:32:49 +08:00
|
|
|
// Sort again in case the range size changes the ordering
|
|
|
|
m_file_addr_to_index.Sort();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2013-07-10 09:23:25 +08:00
|
|
|
void Symtab::CalculateSymbolSizes() {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2019-01-04 18:11:25 +08:00
|
|
|
// Size computation happens inside InitAddressIndexes.
|
|
|
|
InitAddressIndexes();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Symbol *Symtab::FindSymbolAtFileAddress(addr_t file_addr) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2013-07-10 09:23:25 +08:00
|
|
|
if (!m_file_addr_to_index_computed)
|
2010-06-09 00:52:24 +08:00
|
|
|
InitAddressIndexes();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-18 19:12:18 +08:00
|
|
|
const FileRangeToIndexMap::Entry *entry =
|
|
|
|
m_file_addr_to_index.FindEntryStartsAt(file_addr);
|
|
|
|
if (entry) {
|
2016-01-19 18:24:51 +08:00
|
|
|
Symbol *symbol = SymbolAtIndex(entry->data);
|
|
|
|
if (symbol->GetFileAddress() == file_addr)
|
|
|
|
return symbol;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2014-04-20 21:17:36 +08:00
|
|
|
return nullptr;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-10-08 12:20:14 +08:00
|
|
|
|
2013-07-10 09:23:25 +08:00
|
|
|
Symbol *Symtab::FindSymbolContainingFileAddress(addr_t file_addr) {
|
2010-06-09 00:52:24 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
|
|
|
|
2013-07-10 09:23:25 +08:00
|
|
|
if (!m_file_addr_to_index_computed)
|
2010-06-09 00:52:24 +08:00
|
|
|
InitAddressIndexes();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-07-10 09:23:25 +08:00
|
|
|
const FileRangeToIndexMap::Entry *entry =
|
|
|
|
m_file_addr_to_index.FindEntryThatContains(file_addr);
|
|
|
|
if (entry) {
|
2016-01-19 18:24:51 +08:00
|
|
|
Symbol *symbol = SymbolAtIndex(entry->data);
|
|
|
|
if (symbol->ContainsFileAddress(file_addr))
|
|
|
|
return symbol;
|
|
|
|
}
|
2014-04-20 21:17:36 +08:00
|
|
|
return nullptr;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-01-26 08:58:09 +08:00
|
|
|
void Symtab::ForEachSymbolContainingFileAddress(
|
|
|
|
addr_t file_addr, std::function<bool(Symbol *)> const &callback) {
|
2016-05-19 13:13:57 +08:00
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
2016-01-23 18:36:06 +08:00
|
|
|
|
|
|
|
if (!m_file_addr_to_index_computed)
|
|
|
|
InitAddressIndexes();
|
|
|
|
|
|
|
|
std::vector<uint32_t> all_addr_indexes;
|
|
|
|
|
|
|
|
// Get all symbols with file_addr
|
2016-01-26 08:58:09 +08:00
|
|
|
const size_t addr_match_count =
|
|
|
|
m_file_addr_to_index.FindEntryIndexesThatContain(file_addr,
|
|
|
|
all_addr_indexes);
|
2016-01-23 18:36:06 +08:00
|
|
|
|
2016-01-26 08:58:09 +08:00
|
|
|
for (size_t i = 0; i < addr_match_count; ++i) {
|
2016-02-18 19:12:18 +08:00
|
|
|
Symbol *symbol = SymbolAtIndex(all_addr_indexes[i]);
|
|
|
|
if (symbol->ContainsFileAddress(file_addr)) {
|
|
|
|
if (!callback(symbol))
|
|
|
|
break;
|
2016-01-23 18:36:06 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2016-01-23 18:36:06 +08:00
|
|
|
}
|
|
|
|
|
2013-01-08 08:01:36 +08:00
|
|
|
void Symtab::SymbolIndicesToSymbolContextList(
|
|
|
|
std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list) {
|
|
|
|
// No need to protect this call using m_mutex all other method calls are
|
|
|
|
// already thread safe.
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-04-03 10:00:15 +08:00
|
|
|
const bool merge_symbol_into_function = true;
|
2013-01-08 08:01:36 +08:00
|
|
|
size_t num_indices = symbol_indexes.size();
|
|
|
|
if (num_indices > 0) {
|
|
|
|
SymbolContext sc;
|
|
|
|
sc.module_sp = m_objfile->GetModule();
|
|
|
|
for (size_t i = 0; i < num_indices; i++) {
|
|
|
|
sc.symbol = SymbolAtIndex(symbol_indexes[i]);
|
|
|
|
if (sc.symbol)
|
2013-04-03 10:00:15 +08:00
|
|
|
sc_list.AppendIfUnique(sc, merge_symbol_into_function);
|
2013-01-08 08:01:36 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2013-01-08 08:01:36 +08:00
|
|
|
}
|
|
|
|
|
2019-10-18 03:56:40 +08:00
|
|
|
void Symtab::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
|
|
|
|
SymbolContextList &sc_list) {
|
2013-01-08 08:01:36 +08:00
|
|
|
std::vector<uint32_t> symbol_indexes;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-04-03 10:00:15 +08:00
|
|
|
// eFunctionNameTypeAuto should be pre-resolved by a call to
|
2016-10-01 04:38:33 +08:00
|
|
|
// Module::LookupInfo::LookupInfo()
|
2013-04-23 01:02:04 +08:00
|
|
|
assert((name_type_mask & eFunctionNameTypeAuto) == 0);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-04-23 01:02:04 +08:00
|
|
|
if (name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull)) {
|
|
|
|
std::vector<uint32_t> temp_symbol_indexes;
|
|
|
|
FindAllSymbolsWithNameAndType(name, eSymbolTypeAny, temp_symbol_indexes);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-04-23 01:02:04 +08:00
|
|
|
unsigned temp_symbol_indexes_size = temp_symbol_indexes.size();
|
2013-04-03 10:00:15 +08:00
|
|
|
if (temp_symbol_indexes_size > 0) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
|
|
|
for (unsigned i = 0; i < temp_symbol_indexes_size; i++) {
|
|
|
|
SymbolContext sym_ctx;
|
|
|
|
sym_ctx.symbol = SymbolAtIndex(temp_symbol_indexes[i]);
|
|
|
|
if (sym_ctx.symbol) {
|
|
|
|
switch (sym_ctx.symbol->GetType()) {
|
|
|
|
case eSymbolTypeCode:
|
2013-04-23 01:02:04 +08:00
|
|
|
case eSymbolTypeResolver:
|
2013-04-03 10:00:15 +08:00
|
|
|
case eSymbolTypeReExported:
|
2021-11-09 09:01:21 +08:00
|
|
|
case eSymbolTypeAbsolute:
|
2013-04-03 10:00:15 +08:00
|
|
|
symbol_indexes.push_back(temp_symbol_indexes[i]);
|
|
|
|
break;
|
|
|
|
default:
|
2014-04-20 21:17:36 +08:00
|
|
|
break;
|
2013-04-03 10:00:15 +08:00
|
|
|
}
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2013-04-03 10:00:15 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2013-04-03 10:00:15 +08:00
|
|
|
|
2021-06-04 03:14:20 +08:00
|
|
|
if (!m_name_indexes_computed)
|
|
|
|
InitNameIndexes();
|
2013-01-08 08:01:36 +08:00
|
|
|
|
2021-06-04 03:14:20 +08:00
|
|
|
for (lldb::FunctionNameType type :
|
|
|
|
{lldb::eFunctionNameTypeBase, lldb::eFunctionNameTypeMethod,
|
|
|
|
lldb::eFunctionNameTypeSelector}) {
|
|
|
|
if (name_type_mask & type) {
|
|
|
|
auto map = GetNameToSymbolIndexMap(type);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-04-03 10:00:15 +08:00
|
|
|
const UniqueCStringMap<uint32_t>::Entry *match;
|
2021-06-04 03:14:20 +08:00
|
|
|
for (match = map.FindFirstValueForName(name); match != nullptr;
|
|
|
|
match = map.FindNextValueForName(match)) {
|
2013-04-03 10:00:15 +08:00
|
|
|
symbol_indexes.push_back(match->value);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-10 09:23:25 +08:00
|
|
|
if (!symbol_indexes.empty()) {
|
2019-01-09 07:25:06 +08:00
|
|
|
llvm::sort(symbol_indexes.begin(), symbol_indexes.end());
|
2013-01-08 08:01:36 +08:00
|
|
|
symbol_indexes.erase(
|
|
|
|
std::unique(symbol_indexes.begin(), symbol_indexes.end()),
|
|
|
|
symbol_indexes.end());
|
|
|
|
SymbolIndicesToSymbolContextList(symbol_indexes, sc_list);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2013-01-08 08:01:36 +08:00
|
|
|
}
|
|
|
|
|
2015-02-26 06:41:34 +08:00
|
|
|
const Symbol *Symtab::GetParent(Symbol *child_symbol) const {
|
|
|
|
uint32_t child_idx = GetIndexForSymbol(child_symbol);
|
|
|
|
if (child_idx != UINT32_MAX && child_idx > 0) {
|
|
|
|
for (uint32_t idx = child_idx - 1; idx != UINT32_MAX; --idx) {
|
|
|
|
const Symbol *symbol = SymbolAtIndex(idx);
|
|
|
|
const uint32_t sibling_idx = symbol->GetSiblingIndex();
|
|
|
|
if (sibling_idx != UINT32_MAX && sibling_idx > child_idx)
|
|
|
|
return symbol;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
[lldb] NFC modernize codebase with modernize-use-nullptr
Summary:
NFC = [[ https://llvm.org/docs/Lexicon.html#nfc | Non functional change ]]
This commit is the result of modernizing the LLDB codebase by using
`nullptr` instread of `0` or `NULL`. See
https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nullptr.html
for more information.
This is the command I ran and I to fix and format the code base:
```
run-clang-tidy.py \
-header-filter='.*' \
-checks='-*,modernize-use-nullptr' \
-fix ~/dev/llvm-project/lldb/.* \
-format \
-style LLVM \
-p ~/llvm-builds/debug-ninja-gcc
```
NOTE: There were also changes to `llvm/utils/unittest` but I did not
include them because I felt that maybe this library shall be updated in
isolation somehow.
NOTE: I know this is a rather large commit but it is a nobrainer in most
parts.
Reviewers: martong, espindola, shafik, #lldb, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: arsenm, jvesely, nhaehnle, hiraditya, JDevlieghere, teemperor, rnkovacs, emaste, kubamracek, nemanjai, ki.stfu, javed.absar, arichardson, kbarton, jrtc27, MaskRay, atanasyan, dexonsmith, arphaman, jfb, jsji, jdoerfert, lldb-commits, llvm-commits
Tags: #lldb, #llvm
Differential Revision: https://reviews.llvm.org/D61847
llvm-svn: 361484
2019-05-23 19:14:47 +08:00
|
|
|
return nullptr;
|
2015-02-26 06:41:34 +08:00
|
|
|
}
|