Skip to content

Commit b73b325

Browse files
mikeashairspeedswift
authored andcommitted
[Runtime] Only enable metadata allocation tracking when requested with an environment variable.
Expose _swift_debug variables for Remote Mirror to use for tracking metadata allocation, and adopt them in Remote Mirror. rdar://problem/55481578
1 parent d9805ca commit b73b325

File tree

3 files changed

+62
-17
lines changed

3 files changed

+62
-17
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -867,10 +867,30 @@ class ReflectionContext
867867

868868
llvm::Optional<std::string>
869869
iterateMetadataAllocations(std::function<void (MetadataAllocation)> Call) {
870-
std::string AllocationPoolName = "__ZL14AllocationPool";
871-
auto AllocationPoolAddr = getReader().getSymbolAddress(AllocationPoolName);
870+
std::string IterationEnabledName =
871+
"__swift_debug_metadataAllocationIterationEnabled";
872+
std::string AllocationPoolPointerName =
873+
"__swift_debug_allocationPoolPointer";
874+
875+
auto IterationEnabledAddr =
876+
getReader().getSymbolAddress(IterationEnabledName);
877+
if (!IterationEnabledAddr)
878+
return "unable to look up debug variable " + IterationEnabledName;
879+
char IterationEnabled;
880+
if (!getReader().readInteger(IterationEnabledAddr, &IterationEnabled))
881+
return "failed to read value of " + IterationEnabledName;
882+
if (!IterationEnabled)
883+
return std::string("remote process does not have metadata allocation "
884+
"iteration enabled");
885+
886+
auto AllocationPoolAddrAddr =
887+
getReader().getSymbolAddress(AllocationPoolPointerName);
888+
if (!AllocationPoolAddrAddr)
889+
return "unable to look up debug variable " + AllocationPoolPointerName;
890+
auto AllocationPoolAddr =
891+
getReader().readPointer(AllocationPoolAddrAddr, sizeof(StoredPointer));
872892
if (!AllocationPoolAddr)
873-
return "unable to look up allocation pool symbol " + AllocationPoolName;
893+
return "failed to read value of " + AllocationPoolPointerName;
874894

875895
struct PoolRange {
876896
StoredPointer Begin;
@@ -886,7 +906,7 @@ class ReflectionContext
886906
};
887907

888908
auto PoolBytes = getReader()
889-
.readBytes(RemoteAddress(AllocationPoolAddr), sizeof(PoolRange));
909+
.readBytes(AllocationPoolAddr->getResolvedAddress(), sizeof(PoolRange));
890910
auto Pool = reinterpret_cast<const PoolRange *>(PoolBytes.get());
891911
if (!Pool)
892912
return std::string("failure reading allocation pool contents");

include/swift/Runtime/Debug.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ bool _swift_reportFatalErrorsToDebugger;
231231
SWIFT_RUNTIME_STDLIB_SPI
232232
bool _swift_shouldReportFatalErrorsToDebugger();
233233

234+
SWIFT_RUNTIME_STDLIB_SPI
235+
bool _swift_debug_metadataAllocationIterationEnabled;
236+
237+
SWIFT_RUNTIME_STDLIB_SPI
238+
const void * const _swift_debug_allocationPoolPointer;
234239

235240
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
236241
inline static int swift_asprintf(char **strp, const char *fmt, ...) {

stdlib/public/runtime/Metadata.cpp

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5494,18 +5494,31 @@ static std::atomic<PoolRange>
54945494
AllocationPool{PoolRange{InitialAllocationPool.Pool,
54955495
sizeof(InitialAllocationPool.Pool)}};
54965496

5497+
bool swift::_swift_debug_metadataAllocationIterationEnabled = false;
5498+
const void * const swift::_swift_debug_allocationPoolPointer = &AllocationPool;
5499+
54975500
void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
5498-
if (Tag == 0) abort();
5501+
assert(Tag != 0);
54995502
assert(alignment <= alignof(void*));
55005503
assert(size % alignof(void*) == 0);
55015504

5505+
static OnceToken_t getenvToken;
5506+
SWIFT_ONCE_F(getenvToken, [](void *) {
5507+
const char *value =
5508+
getenv("SWIFT_DEBUG_ENABLE_METADATA_ALLOCATION_ITERATION");
5509+
if (value && (value[0] == '1' || value[0] == 'y' || value[0] == 'Y'))
5510+
_swift_debug_metadataAllocationIterationEnabled = true;
5511+
}, nullptr);
5512+
55025513
// If the size is larger than the maximum, just use malloc.
55035514
if (size > PoolRange::MaxPoolAllocationSize)
55045515
return malloc(size);
55055516

55065517
// Allocate out of the pool.
5518+
auto sizeWithHeader = size;
5519+
if (SWIFT_UNLIKELY(_swift_debug_metadataAllocationIterationEnabled))
5520+
sizeWithHeader += sizeof(AllocationHeader);
55075521
PoolRange curState = AllocationPool.load(std::memory_order_relaxed);
5508-
auto sizeWithHeader = size + sizeof(AllocationHeader);
55095522
while (true) {
55105523
char *allocation;
55115524
PoolRange newState;
@@ -5518,18 +5531,21 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
55185531
newState = PoolRange{curState.Begin + sizeWithHeader,
55195532
curState.Remaining - sizeWithHeader};
55205533
} else {
5521-
auto poolSize = PoolRange::PageSize - sizeof(PoolTrailer);
5534+
auto poolSize = PoolRange::PageSize;
5535+
if (SWIFT_UNLIKELY(_swift_debug_metadataAllocationIterationEnabled))
5536+
poolSize -= sizeof(PoolTrailer);
55225537
allocatedNewPage = true;
55235538
allocation = new char[PoolRange::PageSize];
55245539

5525-
char *prevTrailer = curState.Begin + curState.Remaining;
5526-
PoolTrailer *newTrailer = (PoolTrailer *)(allocation + poolSize);
5527-
newTrailer->PrevTrailer = prevTrailer;
5528-
newTrailer->PoolSize = poolSize;
5529-
5540+
if (SWIFT_UNLIKELY(_swift_debug_metadataAllocationIterationEnabled)) {
5541+
PoolTrailer *newTrailer = (PoolTrailer *)(allocation + poolSize);
5542+
char *prevTrailer = curState.Begin + curState.Remaining;
5543+
newTrailer->PrevTrailer = prevTrailer;
5544+
newTrailer->PoolSize = poolSize;
5545+
}
55305546
newState = PoolRange{allocation + sizeWithHeader,
55315547
poolSize - sizeWithHeader};
5532-
__asan_poison_memory_region(allocation, PoolRange::PageSize);
5548+
__asan_poison_memory_region(allocation, newState.Remaining);
55335549
}
55345550

55355551
// Swap in the new state.
@@ -5541,11 +5557,15 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
55415557
__msan_allocated_memory(allocation, sizeWithHeader);
55425558
__asan_unpoison_memory_region(allocation, sizeWithHeader);
55435559

5544-
AllocationHeader *header = (AllocationHeader *)allocation;
5545-
header->Size = size;
5546-
header->Tag = Tag;
5560+
if (SWIFT_UNLIKELY(_swift_debug_metadataAllocationIterationEnabled)) {
5561+
AllocationHeader *header = (AllocationHeader *)allocation;
5562+
header->Size = size;
5563+
header->Tag = Tag;
55475564

5548-
return allocation + sizeof(AllocationHeader);
5565+
return allocation + sizeof(AllocationHeader);
5566+
} else {
5567+
return allocation;
5568+
}
55495569
}
55505570

55515571
// If it failed, go back to a neutral state and try again.

0 commit comments

Comments
 (0)