diff options
| -rw-r--r-- | lldb/include/lldb/Utility/Reproducer.h | 46 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 27 | ||||
| -rw-r--r-- | lldb/source/Utility/Reproducer.cpp | 26 |
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() {} |

