Skip to content

Commit 59f1187

Browse files
authored
Merge pull request #5100 from augusto2112/swift-meta-cache
[lldb] Implement cache for swift typeref metadata
2 parents f6b60d5 + 80e10a6 commit 59f1187

File tree

14 files changed

+620
-30
lines changed

14 files changed

+620
-30
lines changed

lldb/include/lldb/Core/ModuleList.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ class ModuleListProperties : public Properties {
6565
bool GetSwiftValidateTypeSystem() const;
6666
SwiftModuleLoadingMode GetSwiftModuleLoadingMode() const;
6767
bool SetSwiftModuleLoadingMode(SwiftModuleLoadingMode);
68+
69+
bool GetEnableSwiftMetadataCache() const;
70+
uint64_t GetSwiftMetadataCacheMaxByteSize();
71+
uint64_t GetSwiftMetadataCacheExpirationDays();
72+
FileSpec GetSwiftMetadataCachePath() const;
73+
bool SetSwiftMetadataCachePath(const FileSpec &path);
6874
// END SWIFT
6975

7076
FileSpec GetClangModulesCachePath() const;

lldb/packages/Python/lldbsuite/test/lldbtest.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,12 @@ def setUpCommands(cls):
735735
'settings set symbols.clang-modules-cache-path "{}"'.format(
736736
configuration.lldb_module_cache_dir),
737737

738+
# Enable the swift metadata cache in order to speed up tests.
739+
'settings set symbols.enable-swift-metadata-cache true',
740+
741+
'settings set symbols.swift-metadata-cache-path "{}"'.format(
742+
configuration.lldb_module_cache_dir),
743+
738744
# Enable expensive validations in TypeSystemSwiftTypeRef.
739745
'settings set symbols.swift-validate-typesystem true',
740746

lldb/source/Core/CoreProperties.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,22 @@ let Definition = "modulelist" in {
3030
DefaultEnumValue<"eSwiftModuleLoadingModePreferSerialized">,
3131
EnumValues<"OptionEnumValues(g_swift_module_loading_mode_enums)">,
3232
Desc<"The module loading mode to use when loading modules for Swift.">;
33+
def EnableSwiftMetadataCache: Property<"enable-swift-metadata-cache", "Boolean">,
34+
Global,
35+
DefaultFalse,
36+
Desc<"Enable caching for Swift reflection metadata in LLDB.">;
37+
def SwiftMetadataCachePath: Property<"swift-metadata-cache-path", "FileSpec">,
38+
Global,
39+
DefaultStringValue<"">,
40+
Desc<"The path to LLDB's Swift reflection cache directory.">;
41+
def SwiftMetadataCacheMaxByteSize: Property<"swift-metadata-cache-max-byte-size", "UInt64">,
42+
Global,
43+
DefaultUnsignedValue<0>,
44+
Desc<"The maximum size for LLDB's Swift reflection cache directory in bytes. A value over the amount of available space on the disk will be reduced to the amount of available space. A value of 0 disables the absolute size-based pruning.">;
45+
def SwiftMetadataCacheExpirationDays: Property<"swift-metadata-cache-expiration-days", "UInt64">,
46+
Global,
47+
DefaultUnsignedValue<7>,
48+
Desc<"The expiration time in days for a Swift reflection cache file. When a file hasn't been accessed for the specified amount of days, it is removed from the cache. A value of 0 disables the expiration-based pruning.">;
3349
// END SWIFT
3450
def SymLinkPaths: Property<"debug-info-symlink-paths", "FileSpecList">,
3551
Global,

lldb/source/Core/ModuleList.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ ModuleListProperties::ModuleListProperties() {
108108

109109
// BEGIN SWIFT
110110
SetSwiftModuleLoadingMode(eSwiftModuleLoadingModePreferSerialized);
111+
112+
path.clear();
113+
if (llvm::sys::path::cache_directory(path)) {
114+
llvm::sys::path::append(path, "lldb");
115+
llvm::sys::path::append(path, "SwiftMetadataCache");
116+
lldbassert(SetLLDBIndexCachePath(FileSpec(path)));
117+
}
111118
// END SWIFT
112119

113120
path.clear();
@@ -194,6 +201,36 @@ bool ModuleListProperties::SetSwiftModuleLoadingMode(SwiftModuleLoadingMode mode
194201
return m_collection_sp->SetPropertyAtIndexAsEnumeration(
195202
nullptr, ePropertySwiftModuleLoadingMode, mode);
196203
}
204+
205+
FileSpec ModuleListProperties::GetSwiftMetadataCachePath() const {
206+
return m_collection_sp
207+
->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
208+
ePropertySwiftMetadataCachePath)
209+
->GetCurrentValue();
210+
}
211+
212+
bool ModuleListProperties::SetSwiftMetadataCachePath(const FileSpec &path) {
213+
return m_collection_sp->SetPropertyAtIndexAsFileSpec(
214+
nullptr, ePropertySwiftMetadataCachePath, path);
215+
}
216+
217+
bool ModuleListProperties::GetEnableSwiftMetadataCache() const {
218+
const uint32_t idx = ePropertyEnableSwiftMetadataCache;
219+
return m_collection_sp->GetPropertyAtIndexAsBoolean(
220+
nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
221+
}
222+
223+
uint64_t ModuleListProperties::GetSwiftMetadataCacheMaxByteSize() {
224+
const uint32_t idx = ePropertySwiftMetadataCacheMaxByteSize;
225+
return m_collection_sp->GetPropertyAtIndexAsUInt64(
226+
nullptr, idx, g_modulelist_properties[idx].default_uint_value);
227+
}
228+
229+
uint64_t ModuleListProperties::GetSwiftMetadataCacheExpirationDays() {
230+
const uint32_t idx = ePropertySwiftMetadataCacheExpirationDays;
231+
return m_collection_sp->GetPropertyAtIndexAsUInt64(
232+
nullptr, idx, g_modulelist_properties[idx].default_uint_value);
233+
}
197234
// END SWIFT
198235

199236
FileSpec ModuleListProperties::GetLLDBIndexCachePath() const {

lldb/source/Plugins/LanguageRuntime/Swift/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_lldb_library(lldbPluginSwiftLanguageRuntime PLUGIN
33
SwiftLanguageRuntime.cpp
44
SwiftLanguageRuntimeDynamicTypeResolution.cpp
55
SwiftLanguageRuntimeNames.cpp
6+
SwiftMetadataCache.cpp
67

78
LINK_LIBS
89
swiftAST

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "SwiftLanguageRuntime.h"
1414
#include "Plugins/LanguageRuntime/Swift/LLDBMemoryReader.h"
1515
#include "SwiftLanguageRuntimeImpl.h"
16+
#include "SwiftMetadataCache.h"
1617

1718
#include "Plugins/Process/Utility/RegisterContext_x86.h"
1819
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
@@ -442,6 +443,13 @@ SwiftLanguageRuntimeImpl::GetReflectionContext() {
442443
return m_reflection_ctx.get();
443444
}
444445

446+
SwiftMetadataCache *
447+
SwiftLanguageRuntimeImpl::GetSwiftMetadataCache() {
448+
if (!m_swift_metadata_cache.is_enabled())
449+
return {};
450+
return &m_swift_metadata_cache;
451+
}
452+
445453
void SwiftLanguageRuntimeImpl::SetupReflection() {
446454
LLDB_SCOPED_TIMER();
447455

@@ -481,13 +489,13 @@ void SwiftLanguageRuntimeImpl::SetupReflection() {
481489
"Initializing a 64-bit reflection context (%s) for \"%s\"",
482490
triple.str().c_str(), objc_interop_msg);
483491
m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext64(
484-
this->GetMemoryReader(), objc_interop);
492+
this->GetMemoryReader(), objc_interop, GetSwiftMetadataCache());
485493
} else if (triple.isArch32Bit()) {
486494
LLDB_LOGF(GetLog(LLDBLog::Types),
487495
"Initializing a 32-bit reflection context (%s) for \"%s\"",
488496
triple.str().c_str(), objc_interop_msg);
489497
m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext32(
490-
this->GetMemoryReader(), objc_interop);
498+
this->GetMemoryReader(), objc_interop, GetSwiftMetadataCache());
491499
} else {
492500
LLDB_LOGF(GetLog(LLDBLog::Types),
493501
"Could not initialize reflection context for \"%s\"",
@@ -649,7 +657,7 @@ bool SwiftLanguageRuntimeImpl::AddJitObjectFileToReflectionContext(
649657
if (!obj_file_format)
650658
return false;
651659

652-
return m_reflection_ctx->addImage(
660+
auto reflection_info_id = m_reflection_ctx->addImage(
653661
[&](swift::ReflectionSectionKind section_kind)
654662
-> std::pair<swift::remote::RemoteRef<void>, uint64_t> {
655663
auto section_name = obj_file_format->getSectionName(section_kind);
@@ -676,9 +684,13 @@ bool SwiftLanguageRuntimeImpl::AddJitObjectFileToReflectionContext(
676684
return {};
677685
},
678686
likely_module_names);
687+
// We don't care to cache modules generated by the jit, because they will
688+
// only be used by the current process.
689+
return reflection_info_id.hasValue();
679690
}
680691

681-
bool SwiftLanguageRuntimeImpl::AddObjectFileToReflectionContext(
692+
llvm::Optional<uint32_t>
693+
SwiftLanguageRuntimeImpl::AddObjectFileToReflectionContext(
682694
ModuleSP module,
683695
llvm::SmallVector<llvm::StringRef, 1> likely_module_names) {
684696
auto obj_format_type =
@@ -856,27 +868,35 @@ bool SwiftLanguageRuntimeImpl::AddModuleToReflectionContext(
856868

857869
auto read_from_file_cache =
858870
GetMemoryReader()->readMetadataFromFileCacheEnabled();
871+
872+
llvm::Optional<uint32_t> info_id;
859873
// When dealing with ELF, we need to pass in the contents of the on-disk
860874
// file, since the Section Header Table is not present in the child process
861875
if (obj_file->GetPluginName().equals("elf")) {
862876
DataExtractor extractor;
863877
auto size = obj_file->GetData(0, obj_file->GetByteSize(), extractor);
864878
const uint8_t *file_data = extractor.GetDataStart();
865879
llvm::sys::MemoryBlock file_buffer((void *)file_data, size);
866-
m_reflection_ctx->readELF(
880+
info_id = m_reflection_ctx->readELF(
867881
swift::remote::RemoteAddress(load_ptr),
868882
llvm::Optional<llvm::sys::MemoryBlock>(file_buffer),
869883
likely_module_names);
870884
} else if (read_from_file_cache &&
871885
obj_file->GetPluginName().equals("mach-o")) {
872-
if (!AddObjectFileToReflectionContext(module_sp, likely_module_names)) {
873-
m_reflection_ctx->addImage(swift::remote::RemoteAddress(load_ptr),
886+
info_id = AddObjectFileToReflectionContext(module_sp, likely_module_names);
887+
if (!info_id)
888+
info_id = m_reflection_ctx->addImage(swift::remote::RemoteAddress(load_ptr),
874889
likely_module_names);
875-
}
876890
} else {
877-
m_reflection_ctx->addImage(swift::remote::RemoteAddress(load_ptr),
891+
info_id = m_reflection_ctx->addImage(swift::remote::RemoteAddress(load_ptr),
878892
likely_module_names);
879893
}
894+
895+
if (info_id)
896+
if (auto *swift_metadata_cache = GetSwiftMetadataCache())
897+
swift_metadata_cache->registerModuleWithReflectionInfoID(module_sp,
898+
*info_id);
899+
880900
return true;
881901
}
882902

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "LLDBMemoryReader.h"
14-
#include "SwiftLanguageRuntimeImpl.h"
1514
#include "SwiftLanguageRuntime.h"
15+
#include "SwiftLanguageRuntimeImpl.h"
16+
#include "SwiftMetadataCache.h"
1617

1718
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
1819
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
@@ -24,12 +25,13 @@
2425
#include "lldb/Utility/LLDBLog.h"
2526
#include "lldb/Utility/Log.h"
2627
#include "lldb/Utility/Timer.h"
27-
#include "swift/AST/Types.h"
28+
#include "llvm/ADT/STLExtras.h"
2829

2930
#include "swift/AST/ASTContext.h"
3031
#include "swift/AST/ASTMangler.h"
3132
#include "swift/AST/ASTWalker.h"
3233
#include "swift/AST/Decl.h"
34+
#include "swift/AST/Types.h"
3335
#include "swift/Demangling/Demangle.h"
3436
#include "swift/Reflection/ReflectionContext.h"
3537
#include "swift/Reflection/TypeRefBuilder.h"
@@ -241,24 +243,25 @@ class TargetReflectionContext
241243

242244
public:
243245
TargetReflectionContext(
244-
std::shared_ptr<swift::reflection::MemoryReader> reader)
245-
: m_reflection_ctx(reader) {}
246+
std::shared_ptr<swift::reflection::MemoryReader> reader,
247+
SwiftMetadataCache *swift_metadata_cache)
248+
: m_reflection_ctx(reader, swift_metadata_cache) {}
246249

247-
bool addImage(
250+
llvm::Optional<uint32_t> addImage(
248251
llvm::function_ref<std::pair<swift::remote::RemoteRef<void>, uint64_t>(
249252
swift::ReflectionSectionKind)>
250253
find_section,
251254
llvm::SmallVector<llvm::StringRef, 1> likely_module_names) override {
252255
return m_reflection_ctx.addImage(find_section, likely_module_names);
253256
}
254257

255-
bool
258+
llvm::Optional<uint32_t>
256259
addImage(swift::remote::RemoteAddress image_start,
257260
llvm::SmallVector<llvm::StringRef, 1> likely_module_names) override {
258261
return m_reflection_ctx.addImage(image_start, likely_module_names);
259262
}
260263

261-
bool readELF(
264+
llvm::Optional<uint32_t> readELF(
262265
swift::remote::RemoteAddress ImageStart,
263266
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
264267
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) override {
@@ -361,30 +364,36 @@ class TargetReflectionContext
361364

362365
std::unique_ptr<SwiftLanguageRuntimeImpl::ReflectionContextInterface>
363366
SwiftLanguageRuntimeImpl::ReflectionContextInterface::CreateReflectionContext32(
364-
std::shared_ptr<swift::remote::MemoryReader> reader, bool ObjCInterop) {
367+
std::shared_ptr<swift::remote::MemoryReader> reader, bool ObjCInterop,
368+
SwiftMetadataCache *swift_metadata_cache) {
365369
using ReflectionContext32ObjCInterop =
366370
TargetReflectionContext<swift::reflection::ReflectionContext<
367371
swift::External<swift::WithObjCInterop<swift::RuntimeTarget<4>>>>>;
368372
using ReflectionContext32NoObjCInterop =
369373
TargetReflectionContext<swift::reflection::ReflectionContext<
370374
swift::External<swift::NoObjCInterop<swift::RuntimeTarget<4>>>>>;
371-
if (ObjCInterop)
372-
return std::make_unique<ReflectionContext32ObjCInterop>(reader);
373-
return std::make_unique<ReflectionContext32NoObjCInterop>(reader);
375+
if (ObjCInterop)
376+
return std::make_unique<ReflectionContext32ObjCInterop>(
377+
reader, swift_metadata_cache);
378+
return std::make_unique<ReflectionContext32NoObjCInterop>(
379+
reader, swift_metadata_cache);
374380
}
375381

376382
std::unique_ptr<SwiftLanguageRuntimeImpl::ReflectionContextInterface>
377383
SwiftLanguageRuntimeImpl::ReflectionContextInterface::CreateReflectionContext64(
378-
std::shared_ptr<swift::remote::MemoryReader> reader, bool ObjCInterop) {
384+
std::shared_ptr<swift::remote::MemoryReader> reader, bool ObjCInterop,
385+
SwiftMetadataCache *swift_metadata_cache) {
379386
using ReflectionContext64ObjCInterop =
380387
TargetReflectionContext<swift::reflection::ReflectionContext<
381388
swift::External<swift::WithObjCInterop<swift::RuntimeTarget<8>>>>>;
382389
using ReflectionContext64NoObjCInterop =
383390
TargetReflectionContext<swift::reflection::ReflectionContext<
384391
swift::External<swift::NoObjCInterop<swift::RuntimeTarget<8>>>>>;
385392
if (ObjCInterop)
386-
return std::make_unique<ReflectionContext64ObjCInterop>(reader);
387-
return std::make_unique<ReflectionContext64NoObjCInterop>(reader);
393+
return std::make_unique<ReflectionContext64ObjCInterop>(
394+
reader, swift_metadata_cache);
395+
return std::make_unique<ReflectionContext64NoObjCInterop>(
396+
reader, swift_metadata_cache);
388397
}
389398

390399
SwiftLanguageRuntimeImpl::ReflectionContextInterface::

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "LLDBMemoryReader.h"
1717
#include "SwiftLanguageRuntime.h"
18+
#include "SwiftMetadataCache.h"
1819
#include "swift/Reflection/TypeLowering.h"
1920
#include "llvm/Support/Memory.h"
2021

@@ -201,24 +202,26 @@ class SwiftLanguageRuntimeImpl {
201202
/// Return a 32-bit reflection context.
202203
static std::unique_ptr<ReflectionContextInterface>
203204
CreateReflectionContext32(
204-
std::shared_ptr<swift::remote::MemoryReader> reader, bool ObjCInterop);
205+
std::shared_ptr<swift::remote::MemoryReader> reader, bool ObjCInterop,
206+
SwiftMetadataCache *swift_metadata_cache);
205207

206208
/// Return a 64-bit reflection context.
207209
static std::unique_ptr<ReflectionContextInterface>
208210
CreateReflectionContext64(
209-
std::shared_ptr<swift::remote::MemoryReader> reader, bool ObjCInterop);
211+
std::shared_ptr<swift::remote::MemoryReader> reader, bool ObjCInterop,
212+
SwiftMetadataCache *swift_metadata_cache);
210213

211214
virtual ~ReflectionContextInterface();
212215

213-
virtual bool addImage(
216+
virtual llvm::Optional<uint32_t> addImage(
214217
llvm::function_ref<std::pair<swift::remote::RemoteRef<void>, uint64_t>(
215218
swift::ReflectionSectionKind)>
216219
find_section,
217220
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
218-
virtual bool addImage(
221+
virtual llvm::Optional<uint32_t> addImage(
219222
swift::remote::RemoteAddress image_start,
220223
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
221-
virtual bool
224+
virtual llvm::Optional<uint32_t>
222225
readELF(swift::remote::RemoteAddress ImageStart,
223226
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
224227
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
@@ -365,6 +368,8 @@ class SwiftLanguageRuntimeImpl {
365368
/// Lazily initialize and return \p m_SwiftNativeNSErrorISA.
366369
llvm::Optional<lldb::addr_t> GetSwiftNativeNSErrorISA();
367370

371+
SwiftMetadataCache *GetSwiftMetadataCache();
372+
368373
/// These members are used to track and toggle the state of the "dynamic
369374
/// exclusivity enforcement flag" in the swift runtime. This flag is set to
370375
/// true when an LLDB expression starts running, and reset to its original
@@ -382,6 +387,8 @@ class SwiftLanguageRuntimeImpl {
382387
/// \{
383388
std::unique_ptr<ReflectionContextInterface> m_reflection_ctx;
384389

390+
SwiftMetadataCache m_swift_metadata_cache;
391+
385392
/// Record modules added through ModulesDidLoad, which are to be
386393
/// added to the reflection context once it's being initialized.
387394
ModuleList m_modules_to_add;
@@ -400,8 +407,9 @@ class SwiftLanguageRuntimeImpl {
400407

401408
/// Add the reflections sections to the reflection context by extracting
402409
/// the directly from the object file.
403-
/// \return true on success.
404-
bool AddObjectFileToReflectionContext(
410+
/// \return the info id of the newly registered reflection info on success, or
411+
/// llvm::None otherwise.
412+
llvm::Optional<uint32_t> AddObjectFileToReflectionContext(
405413
lldb::ModuleSP module,
406414
llvm::SmallVector<llvm::StringRef, 1> likely_module_names);
407415

0 commit comments

Comments
 (0)