Skip to content

Commit da3753f

Browse files
committed
Invalidate the reflection metadata cache when new symbols are added.
Reflection context maintains several caches for TypeInfos and TypeRefs that also include types it got from LLDBTypeInforProvider, which reads types from DWARF. If new DWARF is available we need to invalidate these caches. rdar://122432501
1 parent e238ee5 commit da3753f

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) {
@@ -2359,6 +2360,10 @@ SwiftLanguageRuntime::GetReflectionContext() {
23592360
return m_stub->GetReflectionContext();
23602361
}
23612362

2363+
void SwiftLanguageRuntime::SymbolsDidLoad(const ModuleList &module_list) {
2364+
FORWARD(SymbolsDidLoad, module_list);
2365+
}
2366+
23622367
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
23632368
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
23642369
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
@@ -542,7 +542,7 @@ IsClangImportedType(NodePointer node,
542542
case Node::Kind::Enum:
543543
case Node::Kind::TypeAlias:
544544
if (!IsClangImportedType(node->getFirstChild(), decl_context))
545-
return false;
545+
return false;
546546

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

14901490
void TypeSystemSwiftTypeRefForExpressions::ModulesDidLoad(
14911491
ModuleList &module_list) {
1492+
++m_generation;
14921493
NotifyAllTypeSystems([&](TypeSystemSP ts_sp) {
14931494
if (auto swift_ast_ctx =
14941495
llvm::dyn_cast_or_null<SwiftASTContextForExpressions>(ts_sp.get()))
@@ -3163,9 +3164,9 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
31633164
child_is_deref_of_parent = false;
31643165
language_flags = 0;
31653166
auto fallback = [&]() -> CompilerType {
3166-
LLDB_LOGF(GetLog(LLDBLog::Types),
3167-
"Had to engage SwiftASTContext fallback for type %s.",
3168-
AsMangledName(type));
3167+
LLDB_LOG(GetLog(LLDBLog::Types),
3168+
"Had to engage SwiftASTContext fallback for type {0}, field #{1}.",
3169+
AsMangledName(type), idx);
31693170
if (auto *swift_ast_context =
31703171
GetSwiftASTContextFromExecutionContext(exe_ctx))
31713172
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)