Skip to content

Commit b455b8b

Browse files
Merge pull request #11626 from adrian-prantl/progress-reflection
[LLDB] Add progress updates for reflection metadata loading
2 parents 4e2047b + 377e888 commit b455b8b

File tree

4 files changed

+56
-9
lines changed

4 files changed

+56
-9
lines changed

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

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "swift/Demangling/Demangle.h"
2020
#include "llvm/Support/MathExtras.h"
21+
#include "llvm/Support/raw_ostream.h"
2122

2223
using namespace lldb;
2324
using namespace lldb_private;
@@ -416,16 +417,27 @@ bool LLDBMemoryReader::readString(swift::remote::RemoteAddress address,
416417
Log *log = GetLog(LLDBLog::Types);
417418

418419
auto format_string = [](const std::string &dest) {
419-
StreamString stream;
420-
for (auto c : dest) {
421-
if (c >= 32 && c <= 127) {
422-
stream << c;
423-
} else {
424-
stream << "\\0";
425-
stream.PutHex8(c);
426-
}
420+
std::string result;
421+
llvm::raw_string_ostream s(result);
422+
llvm::printEscapedString(dest, s);
423+
return result;
424+
};
425+
/// Very quickly (this is a high-firing event), copy a few
426+
/// human-readable bytes usable as detail in the progress update.
427+
auto short_string = [](const std::string &dest) {
428+
std::string result;
429+
result.reserve(24);
430+
size_t end = std::min<size_t>(dest.size(), 24);
431+
for (size_t i = 0; i < end; ++i) {
432+
signed char c = dest[i];
433+
result.append(1, c > 32 ? c : '.');
427434
}
428-
return std::string(stream.GetData());
435+
if (end < dest.size()) {
436+
result[21] = '.';
437+
result[22] = '.';
438+
result[23] = '.';
439+
}
440+
return result;
429441
};
430442
LLDB_LOGV(log, "[MemoryReader] asked to read string data at address {0:x}",
431443
address.getRawAddress());
@@ -463,6 +475,8 @@ bool LLDBMemoryReader::readString(swift::remote::RemoteAddress address,
463475
!readMetadataFromFileCacheEnabled() || !addr.IsSectionOffset();
464476
target.ReadCStringFromMemory(addr, dest, error, force_live_memory);
465477
if (error.Success()) {
478+
if (m_progress_callback)
479+
m_progress_callback(short_string(dest));
466480
LLDB_LOGV(log, "[MemoryReader] memory read returned string: \"{0}\"",
467481
format_string(dest));
468482
return true;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ class LLDBMemoryReader : public swift::remote::MemoryReader {
105105
/// Returns whether the filecache optimization is enabled or not.
106106
bool readMetadataFromFileCacheEnabled() const;
107107

108+
/// Set or clear the progress callback.
109+
void SetProgressCallback(
110+
std::function<void(llvm::StringRef)> progress_callback = {}) {
111+
m_progress_callback = progress_callback;
112+
}
113+
108114
protected:
109115
bool readRemoteAddressImpl(swift::remote::RemoteAddress address,
110116
swift::remote::RemoteAddress &out,
@@ -166,6 +172,8 @@ class LLDBMemoryReader : public swift::remote::MemoryReader {
166172
/// The set of modules where we should read memory from the symbol file's
167173
/// object file instead of the main object file.
168174
llvm::SmallSet<lldb::ModuleSP, 8> m_modules_with_metadata_in_symbol_obj_file;
175+
/// A callback to update a progress event.
176+
std::function<void(llvm::StringRef)> m_progress_callback;
169177
};
170178
} // namespace lldb_private
171179
#endif

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,22 @@ std::optional<uint64_t> SwiftLanguageRuntime::GetMemberVariableOffset(
608608

609609
namespace {
610610

611+
class ProgressRAII {
612+
Progress m_progress;
613+
LLDBMemoryReader &m_memory_reader;
614+
public:
615+
ProgressRAII(std::string title, Debugger *debugger,
616+
LLDBMemoryReader &memory_reader)
617+
: m_progress(title, {}, {}, debugger,
618+
Progress::kDefaultHighFrequencyReportTime),
619+
m_memory_reader(memory_reader) {
620+
m_memory_reader.SetProgressCallback([&](StringRef message) {
621+
m_progress.Increment(1, message.str());
622+
});
623+
}
624+
~ProgressRAII() { m_memory_reader.SetProgressCallback(); };
625+
};
626+
611627
CompilerType GetTypeFromTypeRef(TypeSystemSwiftTypeRef &ts,
612628
const swift::reflection::TypeRef *type_ref,
613629
swift::Mangle::ManglingFlavor flavor) {
@@ -3480,6 +3496,14 @@ SwiftLanguageRuntime::GetSwiftRuntimeTypeInfo(
34803496
if (!reflection_ctx)
34813497
return llvm::createStringError("no reflection context");
34823498

3499+
// On remove connections downloading reflection metadata can be a bottleneck.
3500+
auto flavor = GetManglingFlavor(type.GetMangledTypeName());
3501+
static std::string g_debuginfo = "Loading debug info";
3502+
static std::string g_reflection = "Loading reflection metadata";
3503+
ProgressRAII progress(
3504+
flavor == swift::Mangle::ManglingFlavor::Embedded ? g_debuginfo
3505+
: g_reflection,
3506+
&GetProcess().GetTarget().GetDebugger(), *GetMemoryReader());
34833507
LLDBTypeInfoProvider provider(*this, ts);
34843508
return reflection_ctx->GetTypeInfo(*type_ref_or_err, &provider,
34853509
ts.GetDescriptorFinder());

lldb/test/API/functionalities/progress_reporting/swift_progress_reporting/TestSwiftProgressReporting.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def test_swift_progress_report(self):
4141
"Importing dependencies for main.swift",
4242
"Importing dependencies for main.swift: Foundation",
4343
"Importing Swift standard library",
44+
"Loading reflection metadata",
4445
]
4546

4647
importing_swift_reports = []

0 commit comments

Comments
 (0)