Skip to content

Commit 57d6673

Browse files
authored
Merge pull request #7658 from augusto2112/refactor-get-reflection-context
[lldb][NFC] Expose GetReflectionContext in SwiftLanguageRuntime's API
2 parents a99755a + 41a8e85 commit 57d6673

File tree

7 files changed

+175
-120
lines changed

7 files changed

+175
-120
lines changed

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "ReflectionContextInterface.h"
1314
#include "SwiftLanguageRuntimeImpl.h"
1415
#include "lldb/Utility/LLDBLog.h"
1516
#include "lldb/Utility/Log.h"
@@ -25,7 +26,7 @@ namespace {
2526
/// 32-bit or 64-bit pointers, with and without ObjC interoperability.
2627
template <typename ReflectionContext>
2728
class TargetReflectionContext
28-
: public SwiftLanguageRuntimeImpl::ReflectionContextInterface {
29+
: public ReflectionContextInterface {
2930
ReflectionContext m_reflection_ctx;
3031
swift::reflection::TypeConverter m_type_converter;
3132

@@ -142,10 +143,9 @@ class TargetReflectionContext
142143
return m_reflection_ctx.getBuilder().lookupSuperclass(tr);
143144
}
144145

145-
bool ForEachSuperClassType(
146-
swift::remote::TypeInfoProvider *tip, lldb::addr_t pointer,
147-
std::function<bool(SwiftLanguageRuntimeImpl::SuperClassType)> fn)
148-
override {
146+
bool ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
147+
lldb::addr_t pointer,
148+
std::function<bool(SuperClassType)> fn) override {
149149
// Guard against faulty self-referential metadata.
150150
unsigned limit = 256;
151151
auto md_ptr = m_reflection_ctx.readMetadataFromInstance(pointer);
@@ -239,8 +239,8 @@ class TargetReflectionContext
239239
} // namespace
240240

241241
namespace lldb_private {
242-
std::unique_ptr<SwiftLanguageRuntimeImpl::ReflectionContextInterface>
243-
SwiftLanguageRuntimeImpl::ReflectionContextInterface::CreateReflectionContext(
242+
std::unique_ptr<ReflectionContextInterface>
243+
ReflectionContextInterface::CreateReflectionContext(
244244
uint8_t ptr_size, std::shared_ptr<swift::remote::MemoryReader> reader,
245245
bool ObjCInterop, SwiftMetadataCache *swift_metadata_cache) {
246246
using ReflectionContext32ObjCInterop =
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#ifndef liblldb_SwiftReflectionContextInterface_h_
2+
#define liblldb_SwiftReflectionContextInterface_h_
3+
4+
#include <mutex>
5+
6+
#include "lldb/lldb-types.h"
7+
#include "swift/ABI/ObjectFile.h"
8+
#include "swift/Remote/RemoteAddress.h"
9+
#include "swift/RemoteInspection/TypeRef.h"
10+
#include "llvm/ADT/Optional.h"
11+
#include "llvm/ADT/STLFunctionalExtras.h"
12+
#include "llvm/ADT/SmallVector.h"
13+
#include "llvm/ADT/StringRef.h"
14+
#include "llvm/Support/Memory.h"
15+
16+
namespace swift {
17+
namespace Demangle {
18+
class Demangler;
19+
} // namespace Demangle
20+
namespace reflection {
21+
class RecordTypeInfo;
22+
class TypeInfo;
23+
} // namespace reflection
24+
namespace remote {
25+
class MemoryReader;
26+
struct TypeInfoProvider;
27+
} // namespace remote
28+
} // namespace swift
29+
30+
namespace lldb_private {
31+
struct SwiftMetadataCache;
32+
33+
/// Returned by \ref ForEachSuperClassType. Not every user of \p
34+
/// ForEachSuperClassType needs all of these. By returning this
35+
/// object we call into the runtime only when needed.
36+
/// Using function objects to avoid instantiating ReflectionContext in this
37+
/// header.
38+
struct SuperClassType {
39+
std::function<const swift::reflection::RecordTypeInfo *()>
40+
get_record_type_info;
41+
std::function<const swift::reflection::TypeRef *()> get_typeref;
42+
};
43+
44+
/// An abstract interface to swift::reflection::ReflectionContext
45+
/// objects of varying pointer sizes. This class encapsulates all
46+
/// traffic to ReflectionContext and abstracts the detail that
47+
/// ReflectionContext is a template that needs to be specialized for
48+
/// a specific pointer width.
49+
class ReflectionContextInterface {
50+
public:
51+
/// Return a reflection context.
52+
static std::unique_ptr<ReflectionContextInterface> CreateReflectionContext(
53+
uint8_t pointer_size, std::shared_ptr<swift::remote::MemoryReader> reader,
54+
bool objc_interop, SwiftMetadataCache *swift_metadata_cache);
55+
56+
virtual ~ReflectionContextInterface() = default;
57+
58+
virtual llvm::Optional<uint32_t> AddImage(
59+
llvm::function_ref<std::pair<swift::remote::RemoteRef<void>, uint64_t>(
60+
swift::ReflectionSectionKind)>
61+
find_section,
62+
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
63+
virtual llvm::Optional<uint32_t>
64+
AddImage(swift::remote::RemoteAddress image_start,
65+
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
66+
virtual llvm::Optional<uint32_t>
67+
ReadELF(swift::remote::RemoteAddress ImageStart,
68+
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
69+
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
70+
virtual const swift::reflection::TypeRef *
71+
GetTypeRefOrNull(llvm::StringRef mangled_type_name) = 0;
72+
virtual const swift::reflection::TypeRef *
73+
GetTypeRefOrNull(swift::Demangle::Demangler &dem,
74+
swift::Demangle::NodePointer node) = 0;
75+
virtual const swift::reflection::TypeInfo *
76+
GetClassInstanceTypeInfo(const swift::reflection::TypeRef *type_ref,
77+
swift::remote::TypeInfoProvider *provider) = 0;
78+
virtual const swift::reflection::TypeInfo *
79+
GetTypeInfo(const swift::reflection::TypeRef *type_ref,
80+
swift::remote::TypeInfoProvider *provider) = 0;
81+
virtual const swift::reflection::TypeInfo *
82+
GetTypeInfoFromInstance(lldb::addr_t instance,
83+
swift::remote::TypeInfoProvider *provider) = 0;
84+
virtual swift::remote::MemoryReader &GetReader() = 0;
85+
virtual const swift::reflection::TypeRef *
86+
LookupSuperclass(const swift::reflection::TypeRef *tr) = 0;
87+
virtual bool
88+
ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
89+
lldb::addr_t pointer,
90+
std::function<bool(SuperClassType)> fn) = 0;
91+
virtual llvm::Optional<std::pair<const swift::reflection::TypeRef *,
92+
swift::remote::RemoteAddress>>
93+
ProjectExistentialAndUnwrapClass(
94+
swift::remote::RemoteAddress existential_addess,
95+
const swift::reflection::TypeRef &existential_tr) = 0;
96+
virtual llvm::Optional<int32_t>
97+
ProjectEnumValue(swift::remote::RemoteAddress enum_addr,
98+
const swift::reflection::TypeRef *enum_type_ref,
99+
swift::remote::TypeInfoProvider *provider) = 0;
100+
virtual const swift::reflection::TypeRef *
101+
ReadTypeFromMetadata(lldb::addr_t metadata_address,
102+
bool skip_artificial_subclasses = false) = 0;
103+
virtual const swift::reflection::TypeRef *
104+
ReadTypeFromInstance(lldb::addr_t instance_address,
105+
bool skip_artificial_subclasses = false) = 0;
106+
virtual llvm::Optional<bool> IsValueInlinedInExistentialContainer(
107+
swift::remote::RemoteAddress existential_address) = 0;
108+
virtual const swift::reflection::TypeRef *
109+
ApplySubstitutions(const swift::reflection::TypeRef *type_ref,
110+
swift::reflection::GenericArgumentMap substitutions) = 0;
111+
virtual swift::remote::RemoteAbsolutePointer
112+
StripSignedPointer(swift::remote::RemoteAbsolutePointer pointer) = 0;
113+
};
114+
115+
/// A wrapper around TargetReflectionContext, which holds a lock to ensure
116+
/// exclusive access.
117+
struct ThreadSafeReflectionContext {
118+
ThreadSafeReflectionContext(ReflectionContextInterface *reflection_ctx,
119+
std::recursive_mutex &mutex)
120+
: m_reflection_ctx(reflection_ctx), m_lock(mutex, std::adopt_lock) {}
121+
122+
static ThreadSafeReflectionContext MakeInvalid() {
123+
// This exists so we can create an "empty" reflection context in the stub
124+
// language runtime.
125+
static std::recursive_mutex mutex;
126+
return ThreadSafeReflectionContext(nullptr, mutex);
127+
}
128+
129+
ReflectionContextInterface *operator->() const { return m_reflection_ctx; }
130+
131+
operator bool() const { return m_reflection_ctx != nullptr; }
132+
133+
private:
134+
ReflectionContextInterface *m_reflection_ctx;
135+
// This lock operates on a recursive mutex because the initialization
136+
// of ReflectionContext recursive calls itself (see
137+
// SwiftLanguageRuntimeImpl::SetupReflection).
138+
std::lock_guard<std::recursive_mutex> m_lock;
139+
};
140+
141+
} // namespace lldb_private
142+
#endif

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "SwiftLanguageRuntime.h"
1414
#include "Plugins/LanguageRuntime/Swift/LLDBMemoryReader.h"
15+
#include "ReflectionContextInterface.h"
1516
#include "SwiftLanguageRuntimeImpl.h"
1617
#include "SwiftMetadataCache.h"
1718

@@ -233,6 +234,11 @@ class SwiftLanguageRuntimeStub {
233234
assert(false && "called into swift language runtime stub"); \
234235
} while (0)
235236

237+
ThreadSafeReflectionContext GetReflectionContext() {
238+
STUB_LOG();
239+
return ThreadSafeReflectionContext::MakeInvalid();
240+
}
241+
236242
bool GetDynamicTypeAndAddress(ValueObject &in_value,
237243
lldb::DynamicValueType use_dynamic,
238244
TypeAndOrName &class_type_or_name,
@@ -445,7 +451,7 @@ static bool HasReflectionInfo(ObjectFile *obj_file) {
445451
return hasReflectionSection;
446452
}
447453

448-
SwiftLanguageRuntimeImpl::ThreadSafeReflectionContext
454+
ThreadSafeReflectionContext
449455
SwiftLanguageRuntimeImpl::GetReflectionContext() {
450456
m_reflection_ctx_mutex.lock();
451457
SetupReflection();
@@ -2333,6 +2339,11 @@ void SwiftLanguageRuntime::Terminate() {
23332339
assert(m_impl || m_stub); \
23342340
return m_impl ? m_impl->METHOD(__VA_ARGS__) : m_stub->METHOD(__VA_ARGS__);
23352341

2342+
ThreadSafeReflectionContext
2343+
SwiftLanguageRuntime::GetReflectionContext() {
2344+
FORWARD(GetReflectionContext);
2345+
}
2346+
23362347
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
23372348
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
23382349
TypeAndOrName &class_type_or_name, Address &address,

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define liblldb_SwiftLanguageRuntime_h_
1515

1616
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
17+
#include "Plugins/LanguageRuntime/Swift/SwiftMetadataCache.h"
1718
#include "Plugins/TypeSystem/Swift/SwiftASTContext.h"
1819
#include "lldb/Breakpoint/BreakpointPrecondition.h"
1920
#include "lldb/Core/PluginInterface.h"
@@ -50,6 +51,7 @@ class TypeBase;
5051
} // namespace swift
5152

5253
namespace lldb_private {
54+
struct ThreadSafeReflectionContext;
5355

5456
/// Statically cast a CompilerType to a Swift type.
5557
swift::Type GetSwiftType(CompilerType type);
@@ -58,6 +60,7 @@ swift::CanType GetCanonicalSwiftType(CompilerType type);
5860

5961
class SwiftLanguageRuntimeStub;
6062
class SwiftLanguageRuntimeImpl;
63+
class ReflectionContextInterface;
6164

6265
class SwiftLanguageRuntime : public LanguageRuntime {
6366
protected:
@@ -73,6 +76,7 @@ class SwiftLanguageRuntime : public LanguageRuntime {
7376
std::unique_ptr<SwiftLanguageRuntimeImpl> m_impl;
7477

7578
public:
79+
ThreadSafeReflectionContext GetReflectionContext();
7680
static char ID;
7781

7882
bool isA(const void *ClassID) const override {

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "LLDBMemoryReader.h"
14+
#include "ReflectionContextInterface.h"
1415
#include "SwiftLanguageRuntime.h"
1516
#include "SwiftLanguageRuntimeImpl.h"
1617
#include "SwiftMetadataCache.h"
@@ -220,9 +221,6 @@ lldb::addr_t SwiftLanguageRuntime::MaybeMaskNonTrivialReferencePointer(
220221
return addr & ~mask;
221222
}
222223

223-
SwiftLanguageRuntimeImpl::ReflectionContextInterface::
224-
~ReflectionContextInterface() {}
225-
226224
const CompilerType &SwiftLanguageRuntimeImpl::GetBoxMetadataType() {
227225
if (m_box_metadata_type.IsValid())
228226
return m_box_metadata_type;

0 commit comments

Comments
 (0)