Skip to content

Commit 05a060e

Browse files
Merge pull request #8181 from adrian-prantl/122432501
Invalidate the reflection metadata cache when new symbols are added.
2 parents 7ffcfbc + da3753f commit 05a060e

File tree

10 files changed

+128
-30
lines changed

10 files changed

+128
-30
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ class SwiftLanguageRuntimeStub {
277277
return {};
278278
}
279279

280+
void SymbolsDidLoad(const ModuleList &module_list) {}
280281
void ModulesDidLoad(const ModuleList &module_list) {}
281282

282283
bool IsStoredInlineInBuffer(CompilerType type) {
@@ -2353,6 +2354,10 @@ SwiftLanguageRuntime::GetReflectionContext() {
23532354
return m_stub->GetReflectionContext();
23542355
}
23552356

2357+
void SwiftLanguageRuntime::SymbolsDidLoad(const ModuleList &module_list) {
2358+
FORWARD(SymbolsDidLoad, module_list);
2359+
}
2360+
23562361
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
23572362
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
23582363
TypeAndOrName &class_type_or_name, Address &address,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class SwiftLanguageRuntime : public LanguageRuntime {
116116
return lldb::eLanguageTypeSwift;
117117
}
118118

119+
void SymbolsDidLoad(const ModuleList &module_list) override;
119120
void ModulesDidLoad(const ModuleList &module_list) override;
120121

121122
bool IsSymbolARuntimeThunk(const Symbol &symbol) override;

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

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -258,27 +258,44 @@ void SwiftLanguageRuntimeImpl::PopLocalBuffer() {
258258

259259
class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
260260
SwiftLanguageRuntimeImpl &m_runtime;
261-
TypeSystemSwift &m_typesystem;
261+
Status m_error;
262+
llvm::Optional<SwiftScratchContextReader> m_reader;
262263

263264
public:
264265
LLDBTypeInfoProvider(SwiftLanguageRuntimeImpl &runtime,
265-
TypeSystemSwift &typesystem)
266+
ExecutionContextScope *exe_scope)
266267
: m_runtime(runtime),
267-
// Always use the typeref type system so we have fewer cache
268-
// invalidations.
269-
m_typesystem(typesystem.GetTypeSystemSwiftTypeRef()) {}
268+
m_reader(m_runtime.GetProcess().GetTarget().GetSwiftScratchContext(
269+
m_error,
270+
exe_scope ? *exe_scope : m_runtime.GetProcess().GetTarget())) {}
271+
LLDBTypeInfoProvider(SwiftLanguageRuntimeImpl &runtime,
272+
ExecutionContext *exe_ctx)
273+
: m_runtime(runtime),
274+
m_reader(m_runtime.GetProcess().GetTarget().GetSwiftScratchContext(
275+
m_error, exe_ctx ? *exe_ctx->GetBestExecutionContextScope()
276+
: m_runtime.GetProcess().GetTarget())) {}
270277

271278
swift::remote::TypeInfoProvider::IdType getId() override {
272-
return (void *)&m_typesystem;
279+
if (m_reader)
280+
return (void *)((char *)m_reader->get() +
281+
m_reader->get()->GetGeneration() +
282+
m_runtime.GetGeneration());
283+
return (void *)0;
273284
}
274285

275286
const swift::reflection::TypeInfo *
276287
getTypeInfo(llvm::StringRef mangledName) override {
277288
// TODO: Should we cache the mangled name -> compiler type lookup, too?
278-
Log *log(GetLog(LLDBLog::Types));
279-
if (log)
280-
LLDB_LOG(log, "[LLDBTypeInfoProvider] Looking up debug type info for {0}",
281-
mangledName);
289+
LLDB_LOG(GetLog(LLDBLog::Types),
290+
"[LLDBTypeInfoProvider] Looking up debug type info for {0}",
291+
mangledName);
292+
293+
if (!m_reader) {
294+
LLDB_LOG(GetLog(LLDBLog::Types),
295+
"[LLDBTypeInfoProvider] no scratch context");
296+
return nullptr;
297+
}
298+
TypeSystemSwiftTypeRef &typesystem = *m_reader->get();
282299

283300
// Materialize a Clang type from the debug info.
284301
assert(swift::Demangle::getManglingPrefixLength(mangledName) == 0);
@@ -303,18 +320,18 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
303320
}
304321
#endif
305322
ConstString mangled(wrapped);
306-
CompilerType swift_type = m_typesystem.GetTypeFromMangledTypename(mangled);
323+
CompilerType swift_type = typesystem.GetTypeFromMangledTypename(mangled);
307324
auto ts = swift_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
308325
if (!ts)
309326
return nullptr;
310327
CompilerType clang_type;
311328
bool is_imported =
312329
ts->IsImportedType(swift_type.GetOpaqueQualType(), &clang_type);
313330
if (!is_imported || !clang_type) {
314-
if (log)
315-
LLDB_LOG(log,
316-
"[LLDBTypeInfoProvider] Could not find clang debug type info for {0}",
317-
mangledName);
331+
LLDB_LOG(GetLog(LLDBLog::Types),
332+
"[LLDBTypeInfoProvider] Could not find clang debug type info "
333+
"for {0}",
334+
mangledName);
318335
return nullptr;
319336
}
320337

@@ -344,10 +361,9 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
344361
CompilerType field_type = clang_type.GetFieldAtIndex(
345362
i, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
346363
if (is_bitfield_ptr) {
347-
Log *log(GetLog(LLDBLog::Types));
348-
if (log)
349-
log->Printf("[LLDBTypeInfoProvider] bitfield support is not yet "
350-
"implemented");
364+
LLDB_LOG(
365+
GetLog(LLDBLog::Types),
366+
"[LLDBTypeInfoProvider] bitfield support is not yet implemented");
351367
continue;
352368
}
353369
swift::reflection::FieldInfo field_info = {
@@ -724,7 +740,7 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
724740
if (!reflection_ctx)
725741
return {};
726742

727-
LLDBTypeInfoProvider tip(*this, *ts);
743+
LLDBTypeInfoProvider tip(*this, exe_scope);
728744
auto *cti = reflection_ctx->GetClassInstanceTypeInfo(
729745
tr, &tip, ts->GetDescriptorFinder());
730746
if (auto *rti =
@@ -801,7 +817,7 @@ SwiftLanguageRuntimeImpl::GetNumFields(CompilerType type,
801817
if (!reflection_ctx)
802818
return {};
803819

804-
LLDBTypeInfoProvider tip(*this, *ts);
820+
LLDBTypeInfoProvider tip(*this, exe_ctx);
805821
auto *cti = reflection_ctx->GetClassInstanceTypeInfo(
806822
tr, &tip, ts->GetDescriptorFinder());
807823
if (auto *rti = llvm::dyn_cast_or_null<RecordTypeInfo>(cti)) {
@@ -964,7 +980,7 @@ SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName(
964980
++idx;
965981
}
966982

967-
LLDBTypeInfoProvider tip(*this, *ts);
983+
LLDBTypeInfoProvider tip(*this, exe_ctx);
968984
// `current_tr` iterates the class hierarchy, from the current class, each
969985
// superclass, and ends on null.
970986
auto *current_tr = tr;
@@ -1083,7 +1099,7 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
10831099
if (!reflection_ctx)
10841100
return {};
10851101
// The indirect enum field should point to a closure context.
1086-
LLDBTypeInfoProvider tip(*this, *ts);
1102+
LLDBTypeInfoProvider tip(*this, &exe_ctx);
10871103
lldb::addr_t instance = MaskMaybeBridgedPointer(m_process, pointer);
10881104
auto *ti = reflection_ctx->GetTypeInfoFromInstance(
10891105
instance, &tip, ts->GetDescriptorFinder());
@@ -1261,7 +1277,7 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
12611277
return supers.size() >= 2;
12621278
};
12631279

1264-
LLDBTypeInfoProvider tip(*this, *instance_ts);
1280+
LLDBTypeInfoProvider tip(*this, &exe_ctx);
12651281
// Try out the instance pointer based super class traversal first, as its
12661282
// usually faster.
12671283
reflection_ctx->ForEachSuperClassType(&tip, ts->GetDescriptorFinder(),
@@ -1359,7 +1375,8 @@ bool SwiftLanguageRuntimeImpl::ForEachSuperClassType(
13591375
if (!ts)
13601376
return false;
13611377

1362-
LLDBTypeInfoProvider tip(*this, *ts);
1378+
ExecutionContext exe_ctx(instance.GetExecutionContextRef());
1379+
LLDBTypeInfoProvider tip(*this, &exe_ctx);
13631380
lldb::addr_t pointer = instance.GetPointerValue();
13641381
return reflection_ctx->ForEachSuperClassType(
13651382
&tip, ts->GetTypeSystemSwiftTypeRef().GetDescriptorFinder(),
@@ -2915,7 +2932,7 @@ SwiftLanguageRuntimeImpl::GetSwiftRuntimeTypeInfo(
29152932
if (!reflection_ctx)
29162933
return nullptr;
29172934

2918-
LLDBTypeInfoProvider provider(*this, *ts);
2935+
LLDBTypeInfoProvider provider(*this, exe_scope);
29192936
return reflection_ctx->GetTypeInfo(
29202937
type_ref, &provider,
29212938
ts->GetTypeSystemSwiftTypeRef().GetDescriptorFinder());

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class SwiftLanguageRuntimeImpl {
6464
std::unordered_map<std::string, std::vector<std::string>> m_enum_spec;
6565
};
6666

67+
unsigned GetGeneration() const { return m_generation; }
68+
void SymbolsDidLoad(const ModuleList &module_list) { ++m_generation; }
6769
void ModulesDidLoad(const ModuleList &module_list);
6870

6971
bool GetObjectDescription(Stream &str, ValueObject &object);
@@ -403,6 +405,8 @@ class SwiftLanguageRuntimeImpl {
403405
/// added to the reflection context once it's being initialized.
404406
ModuleList m_modules_to_add;
405407

408+
/// Increased every time SymbolsDidLoad is called.
409+
unsigned m_generation = 0;
406410
/// Add the image to the reflection context.
407411
/// \return true on success.
408412
bool AddModuleToReflectionContext(const lldb::ModuleSP &module_sp);

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ IsClangImportedType(NodePointer node,
543543
case Node::Kind::Enum:
544544
case Node::Kind::TypeAlias:
545545
if (!IsClangImportedType(node->getFirstChild(), decl_context))
546-
return false;
546+
return false;
547547

548548
// When C++ interop is enabled, Swift enums represent Swift namespaces.
549549
decl_context.push_back({node->getKind() == Node::Kind::Enum
@@ -1490,6 +1490,7 @@ void TypeSystemSwiftTypeRef::NotifyAllTypeSystems(
14901490

14911491
void TypeSystemSwiftTypeRefForExpressions::ModulesDidLoad(
14921492
ModuleList &module_list) {
1493+
++m_generation;
14931494
NotifyAllTypeSystems([&](TypeSystemSP ts_sp) {
14941495
if (auto swift_ast_ctx =
14951496
llvm::dyn_cast_or_null<SwiftASTContextForExpressions>(ts_sp.get()))
@@ -3171,9 +3172,9 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
31713172
child_is_deref_of_parent = false;
31723173
language_flags = 0;
31733174
auto fallback = [&]() -> CompilerType {
3174-
LLDB_LOGF(GetLog(LLDBLog::Types),
3175-
"Had to engage SwiftASTContext fallback for type %s.",
3176-
AsMangledName(type));
3175+
LLDB_LOG(GetLog(LLDBLog::Types),
3176+
"Had to engage SwiftASTContext fallback for type {0}, field #{1}.",
3177+
AsMangledName(type), idx);
31773178
if (auto *swift_ast_context =
31783179
GetSwiftASTContextFromExecutionContext(exe_ctx))
31793180
return swift_ast_context->GetChildCompilerTypeAtIndex(

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,10 +534,13 @@ class TypeSystemSwiftTypeRefForExpressions : public TypeSystemSwiftTypeRef {
534534
/// Forwards to SwiftASTContext.
535535
PersistentExpressionState *GetPersistentExpressionState() override;
536536
Status PerformCompileUnitImports(const SymbolContext &sc);
537+
/// Returns how often ModulesDidLoad was called/
538+
unsigned GetGeneration() const { return m_generation; }
537539

538540
friend class SwiftASTContextForExpressions;
539541
protected:
540542
lldb::TargetWP m_target_wp;
543+
unsigned m_generation = 0;
541544

542545
/// This exists to implement the PerformCompileUnitImports
543546
/// mechanism.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFT_BRIDGING_HEADER := bridging.h
3+
DISABLE_SWIFT_INTERFACE := YES
4+
HIDE_SWIFTMODULE := YES
5+
6+
include Makefile.rules
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
import unittest2
6+
import shutil
7+
import os
8+
9+
class TestSwiftLateSymbols(TestBase):
10+
@swiftTest
11+
@skipUnlessDarwin
12+
@skipIf(debug_info=no_match(["dsym"]))
13+
def test_any_object_type(self):
14+
"""Test the AnyObject type"""
15+
self.build()
16+
dsym = self.getBuildArtifact('a.out.dSYM')
17+
stash = self.getBuildArtifact('hidden.noindex')
18+
os.unlink(self.getBuildArtifact('main.swift.o'))
19+
os.makedirs(stash)
20+
shutil.move(dsym, stash)
21+
target, process, thread, bkpt = lldbutil.run_to_name_breakpoint(
22+
self, 'breakpoint')
23+
# return to main(), at a place where all variables are available
24+
thread.StepOut()
25+
26+
frame = thread.frames[0]
27+
var_object = frame.FindVariable("object", lldb.eNoDynamicValues)
28+
self.assertFalse(var_object.IsValid())
29+
30+
self.expect('add-dsym ' + stash + '/a.out.dSYM')
31+
frame = thread.frames[0]
32+
var_object = frame.FindVariable("object", lldb.eNoDynamicValues)
33+
self.assertTrue(var_object.IsValid())
34+
35+
lldbutil.check_variable(
36+
self,
37+
var_object,
38+
use_dynamic=False,
39+
typename="bridging.h.FromC")
40+
var_object_x = var_object.GetDynamicValue(
41+
lldb.eDynamicCanRunTarget).GetChildMemberWithName("i")
42+
lldbutil.check_variable(
43+
self,
44+
var_object_x,
45+
use_dynamic=False,
46+
value='23',
47+
typename="Swift.Int32")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct FromC {
2+
int i;
3+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
func use<T>(_ t: T) {}
2+
func breakpoint(_ object: FromC) {
3+
print("stop")
4+
}
5+
6+
func main() {
7+
var object = FromC(i: 23)
8+
breakpoint(object)
9+
}
10+
11+
main()

0 commit comments

Comments
 (0)