@@ -131,6 +131,12 @@ class ReflectionContext
131
131
ChunkKind Kind;
132
132
};
133
133
134
+ struct AsyncTaskSlabInfo {
135
+ StoredPointer NextSlab;
136
+ StoredSize SlabSize;
137
+ std::vector<AsyncTaskAllocationChunk> Chunks;
138
+ };
139
+
134
140
explicit ReflectionContext (std::shared_ptr<MemoryReader> reader)
135
141
: super(std::move(reader), *this)
136
142
{}
@@ -1346,44 +1352,45 @@ class ReflectionContext
1346
1352
return llvm::None;
1347
1353
}
1348
1354
1349
- llvm::Optional<std::string> iterateAsyncTaskAllocations (
1350
- StoredPointer AsyncTaskPtr,
1351
- std::function<void (StoredPointer, unsigned , AsyncTaskAllocationChunk[])>
1352
- Call) {
1353
- using AsyncTask = AsyncTask<Runtime>;
1355
+ std::pair<llvm::Optional<std::string>, AsyncTaskSlabInfo>
1356
+ asyncTaskSlabAllocations (StoredPointer SlabPtr) {
1354
1357
using StackAllocator = StackAllocator<Runtime>;
1358
+ auto SlabBytes = getReader ().readBytes (
1359
+ RemoteAddress (SlabPtr), sizeof (typename StackAllocator::Slab));
1360
+ auto Slab = reinterpret_cast <const typename StackAllocator::Slab *>(
1361
+ SlabBytes.get ());
1362
+ if (!Slab)
1363
+ return {std::string (" failure reading slab" ), {}};
1364
+
1365
+ // For now, we won't try to walk the allocations in the slab, we'll just
1366
+ // provide the whole thing as one big chunk.
1367
+ size_t HeaderSize =
1368
+ llvm::alignTo (sizeof (*Slab), llvm::Align (MaximumAlignment));
1369
+ AsyncTaskAllocationChunk Chunk;
1370
+
1371
+ Chunk.Start = SlabPtr + HeaderSize;
1372
+ Chunk.Length = Slab->CurrentOffset ;
1373
+ Chunk.Kind = AsyncTaskAllocationChunk::ChunkKind::Unknown;
1374
+
1375
+ // Total slab size is the slab's capacity plus the slab struct itself.
1376
+ StoredPointer SlabSize = Slab->Capacity + sizeof (*Slab);
1377
+
1378
+ return {llvm::None, {Slab->Next , SlabSize, {Chunk}}};
1379
+ }
1380
+
1381
+ std::pair<llvm::Optional<std::string>, StoredPointer>
1382
+ asyncTaskSlabPtr (StoredPointer AsyncTaskPtr) {
1383
+ using AsyncTask = AsyncTask<Runtime>;
1355
1384
1356
1385
auto AsyncTaskBytes =
1357
1386
getReader ().readBytes (RemoteAddress (AsyncTaskPtr), sizeof (AsyncTask));
1358
1387
auto *AsyncTaskObj =
1359
1388
reinterpret_cast <const AsyncTask *>(AsyncTaskBytes.get ());
1360
1389
if (!AsyncTaskObj)
1361
- return std::string (" failure reading async task" );
1390
+ return { std::string (" failure reading async task" ), 0 } ;
1362
1391
1363
1392
StoredPointer SlabPtr = AsyncTaskObj->PrivateStorage .Allocator .FirstSlab ;
1364
- while (SlabPtr) {
1365
- auto SlabBytes = getReader ().readBytes (
1366
- RemoteAddress (SlabPtr), sizeof (typename StackAllocator::Slab));
1367
- auto Slab = reinterpret_cast <const typename StackAllocator::Slab *>(
1368
- SlabBytes.get ());
1369
- if (!Slab)
1370
- return std::string (" failure reading slab" );
1371
-
1372
- // For now, we won't try to walk the allocations in the slab, we'll just
1373
- // provide the whole thing as one big chunk.
1374
- size_t HeaderSize =
1375
- llvm::alignTo (sizeof (*Slab), llvm::Align (alignof (std::max_align_t )));
1376
- AsyncTaskAllocationChunk Chunk;
1377
-
1378
- Chunk.Start = SlabPtr + HeaderSize;
1379
- Chunk.Length = Slab->CurrentOffset ;
1380
- Chunk.Kind = AsyncTaskAllocationChunk::ChunkKind::Unknown;
1381
- Call (SlabPtr, 1 , &Chunk);
1382
-
1383
- SlabPtr = Slab->Next ;
1384
- }
1385
-
1386
- return llvm::None;
1393
+ return {llvm::None, SlabPtr};
1387
1394
}
1388
1395
1389
1396
private:
0 commit comments