diff options
Diffstat (limited to 'contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h')
-rw-r--r-- | contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h b/contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h new file mode 100644 index 000000000000..3016c531f674 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h @@ -0,0 +1,216 @@ +//===-- DataFileCache.h -----------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_CORE_DATAFILECACHE_H +#define LLDB_CORE_DATAFILECACHE_H + +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/UUID.h" +#include "lldb/lldb-forward.h" +#include "llvm/Support/Caching.h" +#include <mutex> + +namespace lldb_private { + +/// This class enables data to be cached into a directory using the llvm +/// caching code. Data can be stored and accessed using a unique string key. +/// The data will be stored in the directory that is specified in the +/// DataFileCache constructor. The data will be stored in files that start with +/// "llvmcache-<key>" where <key> is the key name specified when getting to +/// setting cached data. +/// +/// Sample code for how to use the cache: +/// +/// DataFileCache cache("/tmp/lldb-test-cache"); +/// StringRef key("Key1"); +/// auto mem_buffer_up = cache.GetCachedData(key); +/// if (mem_buffer_up) { +/// printf("cached data:\n%s", mem_buffer_up->getBufferStart()); +/// } else { +/// std::vector<uint8_t> data = { 'h', 'e', 'l', 'l', 'o', '\n' }; +/// cache.SetCachedData(key, data); +/// } + +class DataFileCache { +public: + /// Create a data file cache in the directory path that is specified. + /// + /// Data will be cached in files created in this directory when clients call + /// DataFileCache::SetCacheData. + DataFileCache(llvm::StringRef path); + + /// Get cached data from the cache directory for the specified key. + /// + /// Keys must be unique for any given data. This function attempts to see if + /// the data is available for the specified key and will return a valid memory + /// buffer is data is available. + /// + /// \param key + /// The unique string key that identifies data being cached. + /// + /// \return + /// A valid unique pointer to a memory buffer if the data is available, or + /// a unique pointer that contains NULL if the data is not available. + std::unique_ptr<llvm::MemoryBuffer> GetCachedData(llvm::StringRef key); + + /// Set cached data for the specified key. + /// + /// Setting the cached data will save a file in the cache directory to contain + /// the specified data. + /// + /// \param key + /// The unique string key that identifies data being cached. + /// + /// \return + /// True if the data was successfully cached, false otherwise. + bool SetCachedData(llvm::StringRef key, llvm::ArrayRef<uint8_t> data); + + /// Remove the cache file associated with the key. + Status RemoveCacheFile(llvm::StringRef key); + +private: + /// Return the cache file that is associated with the key. + FileSpec GetCacheFilePath(llvm::StringRef key); + + llvm::FileCache m_cache_callback; + FileSpec m_cache_dir; + std::mutex m_mutex; + std::unique_ptr<llvm::MemoryBuffer> m_mem_buff_up; + bool m_take_ownership = false; +}; + +/// A signature for a given file on disk. +/// +/// Any files that are cached in the LLDB index cached need some data that +/// uniquely identifies a file on disk and this information should be written +/// into each cache file so we can validate if the cache file still matches +/// the file we are trying to load cached data for. Objects can fill out this +/// signature and then encode and decode them to validate the signatures +/// match. If they do not match, the cache file on disk should be removed as +/// it is out of date. +struct CacheSignature { + /// UUID of object file or module. + llvm::Optional<UUID> m_uuid = llvm::None; + /// Modification time of file on disk. + llvm::Optional<std::time_t> m_mod_time = llvm::None; + /// If this describes a .o file with a BSD archive, the BSD archive's + /// modification time will be in m_mod_time, and the .o file's modification + /// time will be in this m_obj_mod_time. + llvm::Optional<std::time_t> m_obj_mod_time = llvm::None; + + CacheSignature() = default; + + /// Create a signature from a module. + CacheSignature(lldb_private::Module *module); + + /// Create a signature from an object file. + CacheSignature(lldb_private::ObjectFile *objfile); + + void Clear() { + m_uuid = llvm::None; + m_mod_time = llvm::None; + m_obj_mod_time = llvm::None; + } + + /// Return true if any of the signature member variables have valid values. + bool IsValid() const { + return m_uuid.hasValue() || m_mod_time.hasValue() || + m_obj_mod_time.hasValue(); + } + + /// Check if two signatures are the same. + bool operator!=(const CacheSignature &rhs) { + if (m_uuid != rhs.m_uuid) + return true; + if (m_mod_time != rhs.m_mod_time) + return true; + if (m_obj_mod_time != rhs.m_obj_mod_time) + return true; + return false; + } + /// Encode this object into a data encoder object. + /// + /// This allows this object to be serialized to disk. The CacheSignature + /// object must have at least one member variable that has a value in order to + /// be serialized so that we can match this data to when the cached file is + /// loaded at a later time. + /// + /// \param encoder + /// A data encoder object that serialized bytes will be encoded into. + /// + /// \return + /// True if a signature was encoded, and false if there were no member + /// variables that had value. False indicates this data should not be + /// cached to disk because we were unable to encode a valid signature. + bool Encode(DataEncoder &encoder); + + /// Decode a serialized version of this object from data. + /// + /// \param data + /// The decoder object that references the serialized data. + /// + /// \param offset_ptr + /// A pointer that contains the offset from which the data will be decoded + /// from that gets updated as data gets decoded. + /// + /// \return + /// True if the signature was successfully decoded, false otherwise. + bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr); +}; + +/// Many cache files require string tables to store data efficiently. This +/// class helps create string tables. +class ConstStringTable { +public: + ConstStringTable() = default; + /// Add a string into the string table. + /// + /// Add a string to the string table will only add the same string one time + /// and will return the offset in the string table buffer to that string. + /// String tables are easy to build with ConstString objects since most LLDB + /// classes for symbol or debug info use them already and they provide + /// permanent storage for the string. + /// + /// \param s + /// The string to insert into the string table. + /// + /// \return + /// The byte offset from the start of the string table for the inserted + /// string. Duplicate strings that get inserted will return the same + /// byte offset. + uint32_t Add(ConstString s); + + bool Encode(DataEncoder &encoder); + +private: + std::vector<ConstString> m_strings; + std::map<ConstString, uint32_t> m_string_to_offset; + /// Skip one byte to start the string table off with an empty string. + uint32_t m_next_offset = 1; +}; + +/// Many cache files require string tables to store data efficiently. This +/// class helps give out strings from a string table that was read from a +/// cache file. +class StringTableReader { +public: + StringTableReader() = default; + + llvm::StringRef Get(uint32_t offset) const; + + bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr); + +protected: + /// All of the strings in the string table are contained in m_data. + llvm::StringRef m_data; +}; + +} // namespace lldb_private + +#endif // LLDB_CORE_DATAFILECACHE_H |