Skip to content

Commit d104e12

Browse files
authored
Merge pull request #40236 from apple/revert-40071-remote-mirror-async-slab-inspection
2 parents f13ef4e + 3c9c564 commit d104e12

File tree

13 files changed

+92
-201
lines changed

13 files changed

+92
-201
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,6 @@ class ReflectionContext
131131
ChunkKind Kind;
132132
};
133133

134-
struct AsyncTaskSlabInfo {
135-
StoredPointer NextSlab;
136-
StoredSize SlabSize;
137-
std::vector<AsyncTaskAllocationChunk> Chunks;
138-
};
139-
140134
explicit ReflectionContext(std::shared_ptr<MemoryReader> reader)
141135
: super(std::move(reader), *this)
142136
{}
@@ -1352,45 +1346,44 @@ class ReflectionContext
13521346
return llvm::None;
13531347
}
13541348

1355-
std::pair<llvm::Optional<std::string>, AsyncTaskSlabInfo>
1356-
asyncTaskSlabAllocations(StoredPointer SlabPtr) {
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(alignof(std::max_align_t)));
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) {
1349+
llvm::Optional<std::string> iterateAsyncTaskAllocations(
1350+
StoredPointer AsyncTaskPtr,
1351+
std::function<void(StoredPointer, unsigned, AsyncTaskAllocationChunk[])>
1352+
Call) {
13831353
using AsyncTask = AsyncTask<Runtime>;
1354+
using StackAllocator = StackAllocator<Runtime>;
13841355

13851356
auto AsyncTaskBytes =
13861357
getReader().readBytes(RemoteAddress(AsyncTaskPtr), sizeof(AsyncTask));
13871358
auto *AsyncTaskObj =
13881359
reinterpret_cast<const AsyncTask *>(AsyncTaskBytes.get());
13891360
if (!AsyncTaskObj)
1390-
return {std::string("failure reading async task"), 0};
1361+
return std::string("failure reading async task");
13911362

13921363
StoredPointer SlabPtr = AsyncTaskObj->PrivateStorage.Allocator.FirstSlab;
1393-
return {llvm::None, SlabPtr};
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;
13941387
}
13951388

13961389
private:

include/swift/Reflection/RuntimeInternals.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ struct StackAllocator {
8686
bool FirstSlabIsPreallocated;
8787

8888
struct Slab {
89-
typename Runtime::StoredPointer Metadata;
9089
typename Runtime::StoredPointer Next;
9190
uint32_t Capacity;
9291
uint32_t CurrentOffset;

include/swift/Remote/MetadataReader.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,21 +2242,25 @@ class MetadataReader {
22422242
return false;
22432243
};
22442244

2245+
bool isTypeContext = false;
22452246
switch (auto contextKind = descriptor->getKind()) {
22462247
case ContextDescriptorKind::Class:
22472248
if (!getContextName())
22482249
return nullptr;
22492250
nodeKind = Demangle::Node::Kind::Class;
2251+
isTypeContext = true;
22502252
break;
22512253
case ContextDescriptorKind::Struct:
22522254
if (!getContextName())
22532255
return nullptr;
22542256
nodeKind = Demangle::Node::Kind::Structure;
2257+
isTypeContext = true;
22552258
break;
22562259
case ContextDescriptorKind::Enum:
22572260
if (!getContextName())
22582261
return nullptr;
22592262
nodeKind = Demangle::Node::Kind::Enum;
2263+
isTypeContext = true;
22602264
break;
22612265
case ContextDescriptorKind::Protocol: {
22622266
if (!getContextName())

include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ extern unsigned long long swift_reflection_classIsSwiftMask;
4444
/// first attempted fix to use the right AsyncTask layout.
4545
/// 1 - Indicates that swift_reflection_iterateAsyncTaskAllocations has been
4646
/// actually fixed to use the right AsyncTask layout.
47-
/// 2 - swift_reflection_iterateAsyncTaskAllocations has been replaced by
48-
/// swift_reflection_asyncTaskSlabPointer and
49-
/// swift_reflection_asyncTaskSlabAllocations.
5047
SWIFT_REMOTE_MIRROR_LINKAGE extern uint32_t swift_reflection_libraryVersion;
5148

5249
/// Get the metadata version supported by the Remote Mirror library.
@@ -398,40 +395,33 @@ const char *swift_reflection_iterateMetadataAllocationBacktraces(
398395
SwiftReflectionContextRef ContextRef,
399396
swift_metadataAllocationBacktraceIterator Call, void *ContextPtr);
400397

401-
/// Get the first allocation slab for a given async task object.
398+
/// Allocation iterator passed to swift_reflection_iterateAsyncTaskAllocations
399+
typedef void (*swift_asyncTaskAllocationIterator)(
400+
swift_reflection_ptr_t AllocationPtr, unsigned Count,
401+
swift_async_task_allocation_chunk_t Chunks[], void *ContextPtr);
402+
403+
/// Iterate over the allocations associated with the given async task object.
402404
/// This object must have an isa value equal to
403405
/// _swift_concurrency_debug_asyncTaskMetadata.
404406
///
405-
/// It is possible that the async task object hasn't allocated a slab yet, in
406-
/// which case the slab pointer will be NULL. If non-NULL, the returned slab
407-
/// pointer may be a separate heap allocation, or it may be interior to some
408-
/// allocation used by the task.
409-
SWIFT_REMOTE_MIRROR_LINKAGE
410-
swift_async_task_slab_return_t
411-
swift_reflection_asyncTaskSlabPointer(SwiftReflectionContextRef ContextRef,
412-
swift_reflection_ptr_t AsyncTaskPtr);
413-
414-
/// Iterate over the allocations in the given async task allocator slab.
415-
/// This allocation must have an "isa" value (scare quotes because it's not a
416-
/// real object) equal to _swift_concurrency_debug_asyncTaskSlabMetadata.
417-
///
418-
/// Calls the passed in Call function for each allocation in the slab. The
419-
/// function is passed the allocation pointer and an array of chunks. Each chunk
420-
/// consists of a start, length, and kind for that chunk of the allocated
421-
/// memory. Any regions of the allocation that are not covered by a chunk are
422-
/// unallocated or garbage. The chunk array is valid only for the duration of
423-
/// the call.
407+
/// Calls the passed in Call function for each allocation associated with the
408+
/// async task object. The function is passed the allocation pointer and an
409+
/// array of chunks. Each chunk consists of a start, length, and kind for that
410+
/// chunk of the allocated memory. Any regions of the allocation that are not
411+
/// covered by a chunk are unallocated or garbage. The chunk array is valid only
412+
/// for the duration of the call.
424413
///
425-
/// A slab may be part of a chain of slabs, so the
426-
/// function may be called more than once.
414+
/// An async task may have more than one allocation associated with it, so the
415+
/// function may be called more than once. It may also have no allocations, in
416+
/// which case the function is not called.
427417
///
428418
/// Returns NULL on success. On error, returns a pointer to a C string
429419
/// describing the error. This pointer remains valid until the next
430420
/// swift_reflection call on the given context.
431421
SWIFT_REMOTE_MIRROR_LINKAGE
432-
swift_async_task_slab_allocations_return_t
433-
swift_reflection_asyncTaskSlabAllocations(SwiftReflectionContextRef ContextRef,
434-
swift_reflection_ptr_t SlabPtr);
422+
const char *swift_reflection_iterateAsyncTaskAllocations(
423+
SwiftReflectionContextRef ContextRef, swift_reflection_ptr_t AsyncTaskPtr,
424+
swift_asyncTaskAllocationIterator Call, void *ContextPtr);
435425

436426
#ifdef __cplusplus
437427
} // extern "C"

include/swift/SwiftRemoteMirror/SwiftRemoteMirrorTypes.h

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -189,42 +189,12 @@ typedef struct swift_metadata_cache_node {
189189
swift_reflection_ptr_t Right;
190190
} swift_metadata_cache_node_t;
191191

192-
/// The return value when getting an async task's slab pointer.
193-
typedef struct swift_async_task_slab_return {
194-
/// On failure, a pointer to a string describing the error. On success, NULL.
195-
/// This pointer remains valid until the next
196-
/// swift_reflection call on the given context.
197-
const char *Error;
198-
199-
/// The task's slab pointer, if no error occurred.
200-
swift_reflection_ptr_t SlabPtr;
201-
} swift_async_task_slab_return_t;
202-
203192
typedef struct swift_async_task_allocation_chunk {
204193
swift_reflection_ptr_t Start;
205194
unsigned Length;
206195
swift_layout_kind_t Kind;
207196
} swift_async_task_allocation_chunk_t;
208197

209-
typedef struct swift_async_task_slab_allocations_return {
210-
/// On failure, a pointer to a string describing the error. On success, NULL.
211-
/// This pointer remains valid until the next
212-
/// swift_reflection call on the given context.
213-
const char *Error;
214-
215-
/// The remote pointer to the next slab, or NULL/0 if none.
216-
swift_reflection_ptr_t NextSlab;
217-
218-
/// The size of the entire slab, in bytes.
219-
unsigned SlabSize;
220-
221-
/// The number of chunks pointed to by Chunks.
222-
unsigned ChunkCount;
223-
224-
/// A pointer to the chunks, if no error occurred.
225-
swift_async_task_allocation_chunk_t *Chunks;
226-
} swift_async_task_slab_allocations_return_t;
227-
228198
/// An opaque pointer to a context which maintains state and
229199
/// caching of reflection structure for heap instances.
230200
typedef struct SwiftReflectionContext *SwiftReflectionContextRef;

stdlib/public/Concurrency/Debug.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ const void *const _swift_concurrency_debug_jobMetadata;
3232
SWIFT_EXPORT_FROM(swift_Concurrency)
3333
const void *const _swift_concurrency_debug_asyncTaskMetadata;
3434

35-
/// A fake metadata pointer placed at the start of async task slab allocations.
36-
SWIFT_EXPORT_FROM(swift_Concurrency)
37-
const void *const _swift_concurrency_debug_asyncTaskSlabMetadata;
38-
3935
} // namespace swift
4036

4137
#endif

stdlib/public/Concurrency/Task.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,6 @@ using namespace swift;
6868
using FutureFragment = AsyncTask::FutureFragment;
6969
using TaskGroup = swift::TaskGroup;
7070

71-
Metadata swift::TaskAllocatorSlabMetadata;
72-
const void *const swift::_swift_concurrency_debug_asyncTaskSlabMetadata =
73-
&TaskAllocatorSlabMetadata;
74-
7571
void FutureFragment::destroy() {
7672
auto queueHead = waitQueue.load(std::memory_order_acquire);
7773
switch (queueHead.getStatus()) {

stdlib/public/Concurrency/TaskPrivate.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,8 @@ class alignas(sizeof(void*) * 2) ActiveTaskStatus {
270270

271271
/// The size of an allocator slab.
272272
static constexpr size_t SlabCapacity = 1000;
273-
extern Metadata TaskAllocatorSlabMetadata;
274273

275-
using TaskAllocator = StackAllocator<SlabCapacity, &TaskAllocatorSlabMetadata>;
274+
using TaskAllocator = StackAllocator<SlabCapacity>;
276275

277276
/// Private storage in an AsyncTask object.
278277
struct AsyncTask::PrivateStorage {

stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ extern "C" {
1818
SWIFT_REMOTE_MIRROR_LINKAGE
1919
unsigned long long swift_reflection_classIsSwiftMask = 2;
2020

21-
SWIFT_REMOTE_MIRROR_LINKAGE uint32_t swift_reflection_libraryVersion = 2;
21+
SWIFT_REMOTE_MIRROR_LINKAGE uint32_t swift_reflection_libraryVersion = 1;
2222
}
2323

2424
#include "swift/Demangling/Demangler.h"
@@ -43,7 +43,6 @@ struct SwiftReflectionContext {
4343
std::vector<std::function<void()>> freeFuncs;
4444
std::vector<std::tuple<swift_addr_t, swift_addr_t>> dataSegments;
4545
std::string lastString;
46-
std::vector<swift_async_task_allocation_chunk_t> lastChunks;
4746

4847
SwiftReflectionContext(MemoryReaderImpl impl) {
4948
auto Reader = std::make_shared<CMemoryReader>(impl);
@@ -775,46 +774,22 @@ const char *swift_reflection_iterateMetadataAllocationBacktraces(
775774
return returnableCString(ContextRef, Error);
776775
}
777776

778-
swift_async_task_slab_return_t
779-
swift_reflection_asyncTaskSlabPointer(SwiftReflectionContextRef ContextRef,
780-
swift_reflection_ptr_t AsyncTaskPtr) {
781-
auto Context = ContextRef->nativeContext;
782-
llvm::Optional<std::string> Error;
783-
NativeReflectionContext::StoredPointer SlabPtr;
784-
std::tie(Error, SlabPtr) = Context->asyncTaskSlabPtr(AsyncTaskPtr);
785-
786-
swift_async_task_slab_return_t Result = {};
787-
Result.Error = returnableCString(ContextRef, Error);
788-
Result.SlabPtr = SlabPtr;
789-
return Result;
790-
}
791-
792-
swift_async_task_slab_allocations_return_t
793-
swift_reflection_asyncTaskSlabAllocations(SwiftReflectionContextRef ContextRef,
794-
swift_reflection_ptr_t SlabPtr) {
795-
auto Context = ContextRef->nativeContext;
796-
llvm::Optional<std::string> Error;
797-
NativeReflectionContext::AsyncTaskSlabInfo Info;
798-
std::tie(Error, Info) = Context->asyncTaskSlabAllocations(SlabPtr);
799-
800-
swift_async_task_slab_allocations_return_t Result = {};
801-
Result.Error = returnableCString(ContextRef, Error);
802-
803-
Result.NextSlab = Info.NextSlab;
804-
Result.SlabSize = Info.SlabSize;
805-
806-
ContextRef->lastChunks.clear();
807-
ContextRef->lastChunks.reserve(Info.Chunks.size());
808-
for (auto &Chunk : Info.Chunks) {
809-
swift_async_task_allocation_chunk_t ConvertedChunk;
810-
ConvertedChunk.Start = Chunk.Start;
811-
ConvertedChunk.Length = Chunk.Length;
812-
ConvertedChunk.Kind = convertAllocationChunkKind(Chunk.Kind);
813-
ContextRef->lastChunks.push_back(ConvertedChunk);
814-
}
815-
816-
Result.ChunkCount = ContextRef->lastChunks.size();
817-
Result.Chunks = ContextRef->lastChunks.data();
818-
819-
return Result;
777+
const char *swift_reflection_iterateAsyncTaskAllocations(
778+
SwiftReflectionContextRef ContextRef, swift_reflection_ptr_t AsyncTaskPtr,
779+
swift_asyncTaskAllocationIterator Call, void *ContextPtr) {
780+
auto Context = ContextRef->nativeContext;
781+
auto Error = Context->iterateAsyncTaskAllocations(
782+
AsyncTaskPtr, [&](auto AllocationPtr, auto Count, auto Chunks) {
783+
std::vector<swift_async_task_allocation_chunk_t> ConvertedChunks;
784+
ConvertedChunks.reserve(Count);
785+
for (unsigned i = 0; i < Count; i++) {
786+
swift_async_task_allocation_chunk_t Chunk;
787+
Chunk.Start = Chunks[i].Start;
788+
Chunk.Length = Chunks[i].Length;
789+
Chunk.Kind = convertAllocationChunkKind(Chunks[i].Kind);
790+
ConvertedChunks.push_back(Chunk);
791+
}
792+
Call(AllocationPtr, Count, ConvertedChunks.data(), ContextPtr);
793+
});
794+
return returnableCString(ContextRef, Error);
820795
}

stdlib/public/runtime/StackAllocator.h

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace swift {
3030
///
3131
/// StackAllocator performs fast allocation and deallocation of memory by
3232
/// implementing a bump-pointer allocation strategy.
33-
///
33+
///
3434
/// This isn't strictly a bump-pointer allocator as it uses backing slabs of
3535
/// memory rather than relying on a boundless contiguous heap. However, it has
3636
/// bump-pointer semantics in that it is a monotonically growing pool of memory
@@ -45,10 +45,7 @@ namespace swift {
4545
/// It's possible to place the first slab into pre-allocated memory.
4646
///
4747
/// The SlabCapacity specifies the capacity for newly allocated slabs.
48-
///
49-
/// SlabMetadataPtr specifies a fake metadata pointer to place at the beginning
50-
/// of slab allocations, so analysis tools can identify them.
51-
template <size_t SlabCapacity, Metadata *SlabMetadataPtr>
48+
template <size_t SlabCapacity>
5249
class StackAllocator {
5350
private:
5451

@@ -89,10 +86,6 @@ class StackAllocator {
8986
/// This struct is actually just the slab header. The slab buffer is tail
9087
/// allocated after Slab.
9188
struct Slab {
92-
/// A fake metadata pointer that analysis tools can use to identify slab
93-
/// allocations.
94-
const void *metadata;
95-
9689
/// A single linked list of all allocated slabs.
9790
Slab *next = nullptr;
9891

@@ -102,8 +95,7 @@ class StackAllocator {
10295

10396
// Here starts the tail allocated memory buffer of the slab.
10497

105-
Slab(size_t newCapacity)
106-
: metadata(SlabMetadataPtr), capacity(newCapacity) {
98+
Slab(size_t newCapacity) : capacity(newCapacity) {
10799
assert((size_t)capacity == newCapacity && "capacity overflow");
108100
}
109101

0 commit comments

Comments
 (0)