Skip to content

Commit 0d6142b

Browse files
committed
Refactoring and cleanups
1 parent 6df9e55 commit 0d6142b

File tree

1 file changed

+106
-60
lines changed

1 file changed

+106
-60
lines changed

lldb/source/Plugins/Language/Swift/SwiftFormatters.cpp

Lines changed: 106 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -958,129 +958,175 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
958958
class TaskGroupSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
959959
public:
960960
TaskGroupSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
961-
: SyntheticChildrenFrontEnd(*valobj_sp.get()) {}
961+
: SyntheticChildrenFrontEnd(*valobj_sp.get()) {
962+
if (auto process_sp = m_backend.GetProcessSP())
963+
m_concurrency_version =
964+
SwiftLanguageRuntime::FindConcurrencyDebugVersion(*process_sp);
965+
}
962966

963967
llvm::Expected<uint32_t> CalculateNumChildren() override {
964-
return m_group_tasks.size();
968+
if (m_concurrency_version.value_or(0) != 1)
969+
return m_backend.GetNumChildren();
970+
971+
return m_task_addrs.size();
965972
}
966973

967974
bool MightHaveChildren() override { return true; }
968975

969976
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override {
970-
if (!m_ts || idx >= m_group_tasks.size())
977+
if (m_concurrency_version.value_or(0) != 1)
978+
return m_backend.GetChildAtIndex(idx);
979+
980+
if (!m_task_type || idx >= m_task_addrs.size())
971981
return {};
972982

973983
if (auto valobj_sp = m_children[idx])
974984
return valobj_sp;
975985

976-
// TypeMangling for "Swift.UnsafeCurrentTask"
977-
CompilerType task_type =
978-
m_ts->GetTypeFromMangledTypename(ConstString("$sSctD"));
979-
980-
addr_t task_addr = m_group_tasks[idx];
986+
addr_t task_addr = m_task_addrs[idx];
987+
auto child_name = ("[" + Twine(idx) + "]").str();
981988
auto task_sp = ValueObject::CreateValueObjectFromAddress(
982-
"current_task", task_addr, m_backend.GetExecutionContextRef(),
983-
task_type, false);
989+
child_name, task_addr, m_backend.GetExecutionContextRef(), m_task_type,
990+
false);
984991
if (auto synthetic_sp = task_sp->GetSyntheticValue())
985992
task_sp = synthetic_sp;
986993

987-
task_sp->SetName(ConstString(("[" + Twine(idx) + "]").str()));
988-
989994
m_children[idx] = task_sp;
990995
return task_sp;
991996
}
992997

993998
size_t GetIndexOfChildWithName(ConstString name) override {
999+
if (m_concurrency_version.value_or(0) != 1)
1000+
return m_backend.GetIndexOfChildWithName(name);
1001+
9941002
StringRef buf = name.GetStringRef();
9951003
size_t idx = 0;
996-
if (buf.consume_front("[") && buf.consumeInteger(10, idx))
1004+
if (buf.consume_front("[") && buf.consumeInteger(10, idx) && buf == "]")
9971005
return idx;
998-
return SIZE_T_MAX;
1006+
return UINT32_MAX;
9991007
}
10001008

10011009
lldb::ChildCacheState Update() override {
1002-
// Get the (opaque) pointer to the `TaskGroupBase`.
1003-
auto opaque_group_ptr_sp = m_backend.GetChildMemberWithName("_group");
1004-
addr_t task_group_ptr =
1005-
opaque_group_ptr_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
1006-
ProcessSP process_sp = m_backend.GetProcessSP();
1007-
TaskGroupBase task_group{process_sp, task_group_ptr};
1008-
m_group_tasks.clear();
1010+
if (m_concurrency_version.value_or(0) != 1)
1011+
return ChildCacheState::eReuse;
1012+
1013+
m_task_addrs.clear();
10091014
m_children.clear();
1010-
auto current_task = task_group.getFirstChild();
1015+
1016+
if (!m_task_type)
1017+
if (auto target_sp = m_backend.GetTargetSP()) {
1018+
if (auto ts_or_err = target_sp->GetScratchTypeSystemForLanguage(
1019+
eLanguageTypeSwift)) {
1020+
if (auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
1021+
ts_or_err->get()))
1022+
// TypeMangling for "Swift.UnsafeCurrentTask"
1023+
m_task_type = ts->GetTypeFromMangledTypename(ConstString("$sSctD"));
1024+
} else {
1025+
LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters | LLDBLog::Types),
1026+
ts_or_err.takeError(),
1027+
"could not get Swift type system for Task synthetic "
1028+
"provider: {0}");
1029+
return ChildCacheState::eReuse;
1030+
}
1031+
}
1032+
1033+
if (!m_task_type)
1034+
return ChildCacheState::eReuse;
1035+
1036+
// Get the (opaque) pointer to the `TaskGroupBase`.
1037+
addr_t task_group_ptr = LLDB_INVALID_ADDRESS;
1038+
if (auto opaque_group_ptr_sp = m_backend.GetChildMemberWithName("_group"))
1039+
task_group_ptr =
1040+
opaque_group_ptr_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
1041+
1042+
TaskGroupBase task_group{m_backend.GetProcessSP(), task_group_ptr};
1043+
1044+
// Get the TaskGroup's child tasks by getting all tasks in the range
1045+
// [FirstChild, LastChild].
1046+
//
1047+
// Child tasks are connected together using ChildFragment::NextChild.
1048+
Status status;
1049+
auto current_task = task_group.getFirstChild(status);
1050+
auto last_task = task_group.getLastChild(status);
10111051
while (current_task) {
1012-
m_group_tasks.push_back(current_task.addr);
1013-
current_task = current_task.getNextTask();
1052+
m_task_addrs.push_back(current_task.addr);
1053+
if (current_task == last_task)
1054+
break;
1055+
current_task = current_task.getNextChild(status);
10141056
}
1015-
m_children.resize(m_group_tasks.size());
1016-
1017-
ExecutionContext exe_ctx{m_backend.GetExecutionContextRef()};
1018-
auto ts_or_err = exe_ctx.GetTargetRef().GetScratchTypeSystemForLanguage(
1019-
eLanguageTypeSwift);
1020-
if (auto error = ts_or_err.takeError()) {
1021-
// TODO: Log the error.
1022-
consumeError(std::move(error));
1023-
return ChildCacheState::eRefetch;
1057+
1058+
// Populate the child cache with null values.
1059+
m_children.resize(m_task_addrs.size());
1060+
1061+
if (status.Fail()) {
1062+
LLDB_LOG(GetLog(LLDBLog::DataFormatters | LLDBLog::Types),
1063+
"could not read TaskGroup's child task pointers: {0}",
1064+
status.AsCString());
1065+
return ChildCacheState::eReuse;
10241066
}
10251067

1026-
m_ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(ts_or_err->get());
10271068
return ChildCacheState::eRefetch;
10281069
}
10291070

10301071
private:
1072+
/// Lightweight Task pointer wrapper, for the purpose of traversing to the
1073+
/// Task's next sibling (via `ChildFragment::NextChild`).
10311074
struct Task {
10321075
ProcessSP process_sp;
10331076
addr_t addr;
10341077

10351078
operator bool() const { return addr && addr != LLDB_INVALID_ADDRESS; }
10361079

1037-
static constexpr offset_t JobFlagsOffset = 0x20;
1038-
static constexpr size_t JobFlagsSize = sizeof(uint32_t);
1039-
static constexpr uint32_t IsChildTaskMask = 1ULL << 26;
1040-
1041-
bool isChildTask() {
1042-
Status status;
1043-
auto flags = process_sp->ReadUnsignedIntegerFromMemory(
1044-
addr + JobFlagsOffset, JobFlagsSize, 0, status);
1045-
if (status.Success())
1046-
return flags & IsChildTaskMask;
1047-
return false;
1048-
}
1080+
bool operator==(const Task &other) const { return addr == other.addr; }
1081+
bool operator!=(const Task &other) const { return !(*this == other); }
10491082

10501083
static constexpr offset_t AsyncTaskSize = sizeof(::swift::AsyncTask);
10511084
static constexpr offset_t ChildFragmentOffset = AsyncTaskSize;
10521085
static constexpr offset_t NextChildOffset = ChildFragmentOffset + 0x8;
10531086

1054-
Task getNextTask() {
1055-
Status status;
1056-
auto next_task =
1057-
process_sp->ReadPointerFromMemory(addr + NextChildOffset, status);
1087+
Task getNextChild(Status &status) {
1088+
addr_t next_task = LLDB_INVALID_ADDRESS;
10581089
if (status.Success())
1059-
return {process_sp, next_task};
1060-
return {process_sp, LLDB_INVALID_ADDRESS};
1090+
next_task =
1091+
process_sp->ReadPointerFromMemory(addr + NextChildOffset, status);
1092+
return {process_sp, next_task};
10611093
}
10621094
};
10631095

1096+
/// Lightweight wrapper around TaskGroup opaque pointers (`TaskGroupBase`),
1097+
/// for the purpose of traversing its child tasks.
10641098
struct TaskGroupBase {
10651099
ProcessSP process_sp;
10661100
addr_t addr;
10671101

10681102
// FirstChild offset for a TaskGroupBase instance.
10691103
static constexpr offset_t FirstChildOffset = 0x18;
1104+
static constexpr offset_t LastChildOffset = 0x20;
1105+
1106+
Task getFirstChild(Status &status) {
1107+
addr_t first_child = LLDB_INVALID_ADDRESS;
1108+
if (status.Success())
1109+
first_child =
1110+
process_sp->ReadPointerFromMemory(addr + FirstChildOffset, status);
1111+
return {process_sp, first_child};
1112+
}
10701113

1071-
Task getFirstChild() {
1072-
Status status;
1073-
auto first_child =
1074-
process_sp->ReadPointerFromMemory(addr + FirstChildOffset, status);
1114+
Task getLastChild(Status &status) {
1115+
addr_t last_child = LLDB_INVALID_ADDRESS;
10751116
if (status.Success())
1076-
return {process_sp, first_child};
1077-
return {process_sp, LLDB_INVALID_PROCESS};
1117+
last_child =
1118+
process_sp->ReadPointerFromMemory(addr + LastChildOffset, status);
1119+
return {process_sp, last_child};
10781120
}
10791121
};
10801122

10811123
private:
1082-
TypeSystemSwiftTypeRef *m_ts;
1083-
std::vector<addr_t> m_group_tasks;
1124+
std::optional<uint32_t> m_concurrency_version;
1125+
// Type for Swift.UnsafeCurrentTask.
1126+
CompilerType m_task_type;
1127+
// The TaskGroup's list of child task addresses.
1128+
std::vector<addr_t> m_task_addrs;
1129+
// Cache and storage of constructed child values.
10841130
std::vector<ValueObjectSP> m_children;
10851131
};
10861132
}

0 commit comments

Comments
 (0)