summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Utility/Reproducer.h46
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp27
-rw-r--r--lldb/source/Utility/Reproducer.cpp26
3 files changed, 43 insertions, 56 deletions
diff --git a/lldb/include/lldb/Utility/Reproducer.h b/lldb/include/lldb/Utility/Reproducer.h
index ea315ad771a..03bd2910ebc 100644
--- a/lldb/include/lldb/Utility/Reproducer.h
+++ b/lldb/include/lldb/Utility/Reproducer.h
@@ -31,24 +31,14 @@ enum class ReproducerMode {
Off,
};
-/// Abstraction for information associated with a provider. This information
-/// is serialized into an index which is used by the loader.
-struct ProviderInfo {
- std::string name;
- std::vector<std::string> files;
-};
-
/// The provider defines an interface for generating files needed for
-/// reproducing. The provider must populate its ProviderInfo to communicate
-/// its name and files to the index, before registering with the generator,
-/// i.e. in the constructor.
+/// reproducing.
///
/// Different components will implement different providers.
class ProviderBase {
public:
virtual ~ProviderBase() = default;
- const ProviderInfo &GetInfo() const { return m_info; }
const FileSpec &GetRoot() const { return m_root; }
/// The Keep method is called when it is decided that we need to keep the
@@ -65,11 +55,12 @@ public:
// Returns the class ID for the dynamic type of this Provider instance.
virtual const void *DynamicClassID() const = 0;
+ virtual llvm::StringRef GetName() const = 0;
+ virtual llvm::StringRef GetFile() const = 0;
+
protected:
ProviderBase(const FileSpec &root) : m_root(root) {}
- /// Every provider keeps track of its own files.
- ProviderInfo m_info;
private:
/// Every provider knows where to dump its potential files.
FileSpec m_root;
@@ -84,6 +75,9 @@ public:
const void *DynamicClassID() const override { return &ThisProviderT::ID; }
+ llvm::StringRef GetName() const override { return ThisProviderT::info::name; }
+ llvm::StringRef GetFile() const override { return ThisProviderT::info::file; }
+
protected:
using ProviderBase::ProviderBase; // Inherit constructor.
};
@@ -152,14 +146,22 @@ class Loader final {
public:
Loader(const FileSpec &root);
- llvm::Optional<ProviderInfo> GetProviderInfo(llvm::StringRef name);
+ template <typename T> FileSpec GetFile() {
+ if (!HasFile(T::file))
+ return {};
+
+ return GetRoot().CopyByAppendingPathComponent(T::file);
+ }
+
llvm::Error LoadIndex();
const FileSpec &GetRoot() const { return m_root; }
private:
- llvm::StringMap<ProviderInfo> m_provider_info;
+ bool HasFile(llvm::StringRef file);
+
FileSpec m_root;
+ std::vector<std::string> m_files;
bool m_loaded;
};
@@ -198,18 +200,4 @@ private:
} // namespace repro
} // namespace lldb_private
-LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(lldb_private::repro::ProviderInfo)
-
-namespace llvm {
-namespace yaml {
-
-template <> struct MappingTraits<lldb_private::repro::ProviderInfo> {
- static void mapping(IO &io, lldb_private::repro::ProviderInfo &info) {
- io.mapRequired("name", info.name);
- io.mapOptional("files", info.files);
- }
-};
-} // namespace yaml
-} // namespace llvm
-
#endif // LLDB_UTILITY_REPRODUCER_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 797f63d537a..00bdd74eecb 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -157,17 +157,24 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
return g_settings_sp;
}
+struct ProcessGDBRemoteInfo {
+ static const char *name;
+ static const char *file;
+};
+
+const char *ProcessGDBRemoteInfo::name = "gdb-remote";
+const char *ProcessGDBRemoteInfo::file = "gdb-remote.yaml";
+
class ProcessGDBRemoteProvider
: public repro::Provider<ProcessGDBRemoteProvider> {
public:
+ typedef ProcessGDBRemoteInfo info;
+
ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {
- m_info.name = "gdb-remote";
- m_info.files.push_back("gdb-remote.yaml");
}
raw_ostream *GetHistoryStream() {
- FileSpec history_file =
- GetRoot().CopyByAppendingPathComponent("gdb-remote.yaml");
+ FileSpec history_file = GetRoot().CopyByAppendingPathComponent(info::file);
std::error_code EC;
m_stream_up = llvm::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
@@ -3432,16 +3439,10 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
if (!loader)
return Status("No loader provided.");
- auto provider_info = loader->GetProviderInfo("gdb-remote");
- if (!provider_info)
- return Status("No provider for gdb-remote.");
-
- if (provider_info->files.empty())
- return Status("Provider for gdb-remote contains no files.");
-
// Construct replay history path.
- FileSpec history_file = loader->GetRoot().CopyByAppendingPathComponent(
- provider_info->files.front());
+ FileSpec history_file = loader->GetFile<ProcessGDBRemoteInfo>();
+ if (!history_file)
+ return Status("No provider for gdb-remote.");
// Enable replay mode.
m_replay_mode = true;
diff --git a/lldb/source/Utility/Reproducer.cpp b/lldb/source/Utility/Reproducer.cpp
index 6e85ba41767..d012faf9d76 100644
--- a/lldb/source/Utility/Reproducer.cpp
+++ b/lldb/source/Utility/Reproducer.cpp
@@ -178,10 +178,13 @@ void Generator::AddProvidersToIndex() {
sys::fs::OpenFlags::F_None);
yaml::Output yout(*strm);
+ std::vector<std::string> files;
+ files.reserve(m_providers.size());
for (auto &provider : m_providers) {
- auto &provider_info = provider.second->GetInfo();
- yout << const_cast<ProviderInfo &>(provider_info);
+ files.emplace_back(provider.second->GetFile());
}
+
+ yout << files;
}
Loader::Loader(const FileSpec &root) : m_root(root), m_loaded(false) {}
@@ -196,29 +199,24 @@ llvm::Error Loader::LoadIndex() {
if (auto err = error_or_file.getError())
return make_error<StringError>("unable to load reproducer index", err);
- std::vector<ProviderInfo> provider_info;
yaml::Input yin((*error_or_file)->getBuffer());
- yin >> provider_info;
-
+ yin >> m_files;
if (auto err = yin.error())
return make_error<StringError>("unable to read reproducer index", err);
- for (auto &info : provider_info)
- m_provider_info[info.name] = info;
+ // Sort files to speed up search.
+ llvm::sort(m_files);
+ // Remember that we've loaded the index.
m_loaded = true;
return llvm::Error::success();
}
-llvm::Optional<ProviderInfo> Loader::GetProviderInfo(StringRef name) {
+bool Loader::HasFile(StringRef file) {
assert(m_loaded);
-
- auto it = m_provider_info.find(name);
- if (it == m_provider_info.end())
- return llvm::None;
-
- return it->second;
+ auto it = std::lower_bound(m_files.begin(), m_files.end(), file.str());
+ return (it != m_files.end()) && (*it == file);
}
void ProviderBase::anchor() {}
OpenPOWER on IntegriCloud