@@ -958,129 +958,175 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
958
958
class TaskGroupSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
959
959
public:
960
960
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
+ }
962
966
963
967
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 ();
965
972
}
966
973
967
974
bool MightHaveChildren () override { return true ; }
968
975
969
976
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 ())
971
981
return {};
972
982
973
983
if (auto valobj_sp = m_children[idx])
974
984
return valobj_sp;
975
985
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 ();
981
988
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 );
984
991
if (auto synthetic_sp = task_sp->GetSyntheticValue ())
985
992
task_sp = synthetic_sp;
986
993
987
- task_sp->SetName (ConstString ((" [" + Twine (idx) + " ]" ).str ()));
988
-
989
994
m_children[idx] = task_sp;
990
995
return task_sp;
991
996
}
992
997
993
998
size_t GetIndexOfChildWithName (ConstString name) override {
999
+ if (m_concurrency_version.value_or (0 ) != 1 )
1000
+ return m_backend.GetIndexOfChildWithName (name);
1001
+
994
1002
StringRef buf = name.GetStringRef ();
995
1003
size_t idx = 0 ;
996
- if (buf.consume_front (" [" ) && buf.consumeInteger (10 , idx))
1004
+ if (buf.consume_front (" [" ) && buf.consumeInteger (10 , idx) && buf == " ] " )
997
1005
return idx;
998
- return SIZE_T_MAX ;
1006
+ return UINT32_MAX ;
999
1007
}
1000
1008
1001
1009
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 ();
1009
1014
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);
1011
1051
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);
1014
1056
}
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 ;
1024
1066
}
1025
1067
1026
- m_ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(ts_or_err->get ());
1027
1068
return ChildCacheState::eRefetch;
1028
1069
}
1029
1070
1030
1071
private:
1072
+ // / Lightweight Task pointer wrapper, for the purpose of traversing to the
1073
+ // / Task's next sibling (via `ChildFragment::NextChild`).
1031
1074
struct Task {
1032
1075
ProcessSP process_sp;
1033
1076
addr_t addr;
1034
1077
1035
1078
operator bool () const { return addr && addr != LLDB_INVALID_ADDRESS; }
1036
1079
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); }
1049
1082
1050
1083
static constexpr offset_t AsyncTaskSize = sizeof (::swift::AsyncTask);
1051
1084
static constexpr offset_t ChildFragmentOffset = AsyncTaskSize;
1052
1085
static constexpr offset_t NextChildOffset = ChildFragmentOffset + 0x8 ;
1053
1086
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;
1058
1089
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};
1061
1093
}
1062
1094
};
1063
1095
1096
+ // / Lightweight wrapper around TaskGroup opaque pointers (`TaskGroupBase`),
1097
+ // / for the purpose of traversing its child tasks.
1064
1098
struct TaskGroupBase {
1065
1099
ProcessSP process_sp;
1066
1100
addr_t addr;
1067
1101
1068
1102
// FirstChild offset for a TaskGroupBase instance.
1069
1103
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
+ }
1070
1113
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;
1075
1116
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};
1078
1120
}
1079
1121
};
1080
1122
1081
1123
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.
1084
1130
std::vector<ValueObjectSP> m_children;
1085
1131
};
1086
1132
}
0 commit comments