|
33 | 33 | #include "lldb/lldb-enumerations.h"
|
34 | 34 | #include "swift/ABI/Task.h"
|
35 | 35 | #include "swift/AST/Types.h"
|
| 36 | +#include "swift/Concurrency/Actor.h" |
36 | 37 | #include "swift/Demangling/Demangle.h"
|
37 | 38 | #include "swift/Demangling/ManglingMacros.h"
|
38 | 39 | #include "llvm/ADT/STLExtras.h"
|
@@ -1321,6 +1322,25 @@ class TaskGroupSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
|
1321 | 1322 | std::vector<ValueObjectSP> m_children;
|
1322 | 1323 | };
|
1323 | 1324 |
|
| 1325 | +/// Offset of ActiveActorStatus from _$defaultActor_. |
| 1326 | +/// |
| 1327 | +/// DefaultActorImpl has the following (labeled) layout. |
| 1328 | +/// |
| 1329 | +/// DefaultActorImpl: |
| 1330 | +/// 0: HeapObject |
| 1331 | +/// $defaultActor: |
| 1332 | +/// 16/0: isDistributedRemoteActor |
| 1333 | +/// 17/1: <alignment padding> |
| 1334 | +/// 32/16: StatusStorage |
| 1335 | +/// |
| 1336 | +/// As shown, the $defaultActor field does not point to the start of the |
| 1337 | +/// DefaultActorImpl. |
| 1338 | +/// |
| 1339 | +/// The StatusStorage is at offset of +32 from the start of DefaultActorImpl, or |
| 1340 | +/// at +16 relative to $defaultActor. The formatters are based on $defaultActor, |
| 1341 | +/// and as such use the relative offset. |
| 1342 | +static constexpr offset_t ActiveActorStatusOffset = 16; |
| 1343 | + |
1324 | 1344 | class ActorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
|
1325 | 1345 | public:
|
1326 | 1346 | ActorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
|
@@ -1458,20 +1478,6 @@ class ActorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
|
1458 | 1478 | ProcessSP process_sp;
|
1459 | 1479 | addr_t addr;
|
1460 | 1480 |
|
1461 |
| - // `$defaultActor`'s offset within the actor object. |
1462 |
| - // |
1463 |
| - // The $defaultActor field does not point to the start of DefaultActorImpl, |
1464 |
| - // it has as an address that points past the HeapObject layout. |
1465 |
| - static constexpr offset_t DefaultActorFieldOffset = 16; |
1466 |
| - // ActiveActorStatus's offset within DefaultActorImpl. |
1467 |
| - // |
1468 |
| - // ActiveActorStatus is declared alignas(2*sizeof(void*)). The layout of |
1469 |
| - // DefaultActorImpl puts the status record after HeapObject (size 16), and |
1470 |
| - // its first field (bool size 1), an offset of +32 from the start of the |
1471 |
| - // actor. This offset is relative to DefaultActorImpl, but this code needs |
1472 |
| - // an offset relative to the $defaultActor field, and is adjusted as such. |
1473 |
| - static constexpr offset_t ActiveActorStatusOffset = |
1474 |
| - 32 - DefaultActorFieldOffset; |
1475 | 1481 | // FirstJob's offset within ActiveActorStatus.
|
1476 | 1482 | static constexpr offset_t FirstJobOffset = ActiveActorStatusOffset + 8;
|
1477 | 1483 |
|
@@ -1865,6 +1871,37 @@ bool lldb_private::formatters::swift::Task_SummaryProvider(
|
1865 | 1871 | return true;
|
1866 | 1872 | }
|
1867 | 1873 |
|
| 1874 | +bool lldb_private::formatters::swift::Actor_SummaryProvider( |
| 1875 | + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { |
| 1876 | + static constexpr offset_t FlagsOffset = ActiveActorStatusOffset; |
| 1877 | + auto addr = valobj.GetLoadAddress(); |
| 1878 | + if (addr == LLDB_INVALID_ADDRESS) |
| 1879 | + return false; |
| 1880 | + |
| 1881 | + auto flags_addr = addr + FlagsOffset; |
| 1882 | + Status status; |
| 1883 | + uint64_t flags = 0; |
| 1884 | + if (auto process_sp = valobj.GetProcessSP()) |
| 1885 | + flags = process_sp->ReadUnsignedIntegerFromMemory(flags_addr, 4, 0, status); |
| 1886 | + |
| 1887 | + if (status.Fail()) { |
| 1888 | + stream.PutCString("<could not read actor state>"); |
| 1889 | + return true; |
| 1890 | + } |
| 1891 | + |
| 1892 | + using namespace ::swift::concurrency::ActorFlagConstants; |
| 1893 | + uint8_t state = flags & ActorStateMask; |
| 1894 | + static_assert(Zombie_ReadyForDeallocation == 3); |
| 1895 | + if (state > Zombie_ReadyForDeallocation) { |
| 1896 | + stream << "<unknown actor state: " << Twine(state).str() << ">"; |
| 1897 | + return true; |
| 1898 | + } |
| 1899 | + |
| 1900 | + static const StringRef states[] = {"idle", "scheduled", "running", "zombie"}; |
| 1901 | + stream.PutCString(states[state]); |
| 1902 | + return true; |
| 1903 | +} |
| 1904 | + |
1868 | 1905 | namespace {
|
1869 | 1906 |
|
1870 | 1907 | /// Enumerate the kinds of SIMD elements.
|
|
0 commit comments