LLDB mainline
DataFileCache.h
Go to the documentation of this file.
1//===-- DataFileCache.h -----------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_CORE_DATAFILECACHE_H
10#define LLDB_CORE_DATAFILECACHE_H
11
13#include "lldb/Utility/Status.h"
14#include "lldb/Utility/UUID.h"
15#include "lldb/lldb-forward.h"
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/Support/CachePruning.h"
18#include "llvm/Support/Caching.h"
19#include "llvm/Support/MemoryBuffer.h"
20
21#include <mutex>
22#include <optional>
23
24namespace lldb_private {
25
26/// This class enables data to be cached into a directory using the llvm
27/// caching code. Data can be stored and accessed using a unique string key.
28/// The data will be stored in the directory that is specified in the
29/// DataFileCache constructor. The data will be stored in files that start with
30/// "llvmcache-<key>" where <key> is the key name specified when getting to
31/// setting cached data.
32///
33/// Sample code for how to use the cache:
34///
35/// DataFileCache cache("/tmp/lldb-test-cache");
36/// StringRef key("Key1");
37/// auto mem_buffer_up = cache.GetCachedData(key);
38/// if (mem_buffer_up) {
39/// printf("cached data:\n%s", mem_buffer_up->getBufferStart());
40/// } else {
41/// std::vector<uint8_t> data = { 'h', 'e', 'l', 'l', 'o', '\n' };
42/// cache.SetCachedData(key, data);
43/// }
44
46public:
47 /// Create a data file cache in the directory path that is specified, using
48 /// the specified policy.
49 ///
50 /// Data will be cached in files created in this directory when clients call
51 /// DataFileCache::SetCacheData.
52 DataFileCache(llvm::StringRef path,
53 llvm::CachePruningPolicy policy =
55
56 /// Gets the default LLDB index cache policy, which is controlled by the
57 /// "LLDBIndexCache" family of settings.
58 static llvm::CachePruningPolicy GetLLDBIndexCachePolicy();
59
60 /// Get cached data from the cache directory for the specified key.
61 ///
62 /// Keys must be unique for any given data. This function attempts to see if
63 /// the data is available for the specified key and will return a valid memory
64 /// buffer is data is available.
65 ///
66 /// \param key
67 /// The unique string key that identifies data being cached.
68 ///
69 /// \return
70 /// A valid unique pointer to a memory buffer if the data is available, or
71 /// a unique pointer that contains NULL if the data is not available.
72 std::unique_ptr<llvm::MemoryBuffer> GetCachedData(llvm::StringRef key);
73
74 /// Set cached data for the specified key.
75 ///
76 /// Setting the cached data will save a file in the cache directory to contain
77 /// the specified data.
78 ///
79 /// \param key
80 /// The unique string key that identifies data being cached.
81 ///
82 /// \return
83 /// True if the data was successfully cached, false otherwise.
84 bool SetCachedData(llvm::StringRef key, llvm::ArrayRef<uint8_t> data);
85
86 /// Remove the cache file associated with the key.
87 Status RemoveCacheFile(llvm::StringRef key);
88
89private:
90 /// Return the cache file that is associated with the key.
91 FileSpec GetCacheFilePath(llvm::StringRef key);
92
93 llvm::FileCache m_cache_callback;
95 std::mutex m_mutex;
96 std::unique_ptr<llvm::MemoryBuffer> m_mem_buff_up;
97 bool m_take_ownership = false;
98};
99
100/// A signature for a given file on disk.
101///
102/// There are two hashes for each file in the LLDB Index Cache. One
103/// hash uniquely identifies the binary, incorporating the name/filepath,
104/// triple, architecture -- things that do not change as the same binary
105/// is recompiled with update code. ObjectFile::GetCacheHash() and
106/// Module::GetHash() provide these hashes.
107///
108/// The second hash, calculated in this class, is based on the mod date
109/// and UUID of the binary and does change on every recompile of the same
110/// binary.
111///
112/// The two hashes allow us to identify a file uniquely in the LLDB Index
113/// Cache and re-use the cache if the existing entry is a match for both.
114/// It also allows us to remove the entry for a previous build of a specific
115/// file, and save the new recompiled binary's symbol table in the LLDB Index
116/// Cache in its place.
118 /// UUID of object file or module.
119 std::optional<UUID> m_uuid;
120 /// Modification time of file on disk.
121 std::optional<std::time_t> m_mod_time;
122 /// If this describes a .o file with a BSD archive, the BSD archive's
123 /// modification time will be in m_mod_time, and the .o file's modification
124 /// time will be in this m_obj_mod_time.
125 std::optional<std::time_t> m_obj_mod_time;
126
127 CacheSignature() = default;
128
129 /// Create a signature from a module.
131
132 /// Create a signature from an object file.
134
135 void Clear() {
136 m_uuid = std::nullopt;
137 m_mod_time = std::nullopt;
138 m_obj_mod_time = std::nullopt;
139 }
140
141 /// Return true only if the CacheSignature is valid.
142 ///
143 /// Cache signatures are considered valid only if there is a UUID in the file
144 /// that can uniquely identify the file. Some build systems play with
145 /// modification times of file so we can not trust them without using valid
146 /// unique idenifier like the UUID being valid.
147 bool IsValid() const { return m_uuid.has_value(); }
148
149 /// Check if two signatures are the same.
150 bool operator==(const CacheSignature &rhs) const {
151 return m_uuid == rhs.m_uuid && m_mod_time == rhs.m_mod_time &&
153 }
154
155 /// Check if two signatures differ.
156 bool operator!=(const CacheSignature &rhs) const { return !(*this == rhs); }
157 /// Encode this object into a data encoder object.
158 ///
159 /// This allows this object to be serialized to disk. The CacheSignature
160 /// object must have at least one member variable that has a value in order to
161 /// be serialized so that we can match this data to when the cached file is
162 /// loaded at a later time.
163 ///
164 /// \param encoder
165 /// A data encoder object that serialized bytes will be encoded into.
166 ///
167 /// \return
168 /// True if a signature was encoded, and false if there were no member
169 /// variables that had value. False indicates this data should not be
170 /// cached to disk because we were unable to encode a valid signature.
171 bool Encode(DataEncoder &encoder) const;
172
173 /// Decode a serialized version of this object from data.
174 ///
175 /// \param data
176 /// The decoder object that references the serialized data.
177 ///
178 /// \param offset_ptr
179 /// A pointer that contains the offset from which the data will be decoded
180 /// from that gets updated as data gets decoded.
181 ///
182 /// \return
183 /// True if the signature was successfully decoded, false otherwise.
184 bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
185};
186
187/// Many cache files require string tables to store data efficiently. This
188/// class helps create string tables.
190public:
191 ConstStringTable() = default;
192 /// Add a string into the string table.
193 ///
194 /// Add a string to the string table will only add the same string one time
195 /// and will return the offset in the string table buffer to that string.
196 /// String tables are easy to build with ConstString objects since most LLDB
197 /// classes for symbol or debug info use them already and they provide
198 /// permanent storage for the string.
199 ///
200 /// \param s
201 /// The string to insert into the string table.
202 ///
203 /// \return
204 /// The byte offset from the start of the string table for the inserted
205 /// string. Duplicate strings that get inserted will return the same
206 /// byte offset.
207 uint32_t Add(ConstString s);
208
209 bool Encode(DataEncoder &encoder);
210
211private:
212 std::vector<ConstString> m_strings;
213 llvm::DenseMap<ConstString, uint32_t> m_string_to_offset;
214 /// Skip one byte to start the string table off with an empty string.
215 uint32_t m_next_offset = 1;
216};
217
218/// Many cache files require string tables to store data efficiently. This
219/// class helps give out strings from a string table that was read from a
220/// cache file.
222public:
223 StringTableReader() = default;
224
225 llvm::StringRef Get(uint32_t offset) const;
226
227 bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
228
229protected:
230 /// All of the strings in the string table are contained in m_data.
231 llvm::StringRef m_data;
232};
233
234} // namespace lldb_private
235
236#endif // LLDB_CORE_DATAFILECACHE_H
bool Encode(DataEncoder &encoder)
std::vector< ConstString > m_strings
llvm::DenseMap< ConstString, uint32_t > m_string_to_offset
uint32_t Add(ConstString s)
Add a string into the string table.
uint32_t m_next_offset
Skip one byte to start the string table off with an empty string.
A uniqued constant string class.
Definition ConstString.h:40
An binary data encoding class.
Definition DataEncoder.h:42
An data extractor class.
FileSpec GetCacheFilePath(llvm::StringRef key)
Return the cache file that is associated with the key.
std::unique_ptr< llvm::MemoryBuffer > GetCachedData(llvm::StringRef key)
Get cached data from the cache directory for the specified key.
bool SetCachedData(llvm::StringRef key, llvm::ArrayRef< uint8_t > data)
Set cached data for the specified key.
llvm::FileCache m_cache_callback
std::unique_ptr< llvm::MemoryBuffer > m_mem_buff_up
DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy policy=DataFileCache::GetLLDBIndexCachePolicy())
Create a data file cache in the directory path that is specified, using the specified policy.
static llvm::CachePruningPolicy GetLLDBIndexCachePolicy()
Gets the default LLDB index cache policy, which is controlled by the "LLDBIndexCache" family of setti...
Status RemoveCacheFile(llvm::StringRef key)
Remove the cache file associated with the key.
A file utility class.
Definition FileSpec.h:57
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:91
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
An error handling class.
Definition Status.h:118
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr)
llvm::StringRef m_data
All of the strings in the string table are contained in m_data.
llvm::StringRef Get(uint32_t offset) const
A class that represents a running process on the host machine.
uint64_t offset_t
Definition lldb-types.h:85
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr)
Decode a serialized version of this object from data.
bool operator==(const CacheSignature &rhs) const
Check if two signatures are the same.
bool operator!=(const CacheSignature &rhs) const
Check if two signatures differ.
bool Encode(DataEncoder &encoder) const
Encode this object into a data encoder object.
bool IsValid() const
Return true only if the CacheSignature is valid.
std::optional< std::time_t > m_mod_time
Modification time of file on disk.
std::optional< std::time_t > m_obj_mod_time
If this describes a .o file with a BSD archive, the BSD archive's modification time will be in m_mod_...
std::optional< UUID > m_uuid
UUID of object file or module.