aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h')
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h216
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