@@ -5494,18 +5494,31 @@ static std::atomic<PoolRange>
5494
5494
AllocationPool{PoolRange{InitialAllocationPool.Pool ,
5495
5495
sizeof (InitialAllocationPool.Pool )}};
5496
5496
5497
+ bool swift::_swift_debug_metadataAllocationIterationEnabled = false ;
5498
+ const void * const swift::_swift_debug_allocationPoolPointer = &AllocationPool;
5499
+
5497
5500
void *MetadataAllocator::Allocate (size_t size, size_t alignment) {
5498
- if (Tag == 0 ) abort ( );
5501
+ assert (Tag != 0 );
5499
5502
assert (alignment <= alignof (void *));
5500
5503
assert (size % alignof (void *) == 0 );
5501
5504
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
+
5502
5513
// If the size is larger than the maximum, just use malloc.
5503
5514
if (size > PoolRange::MaxPoolAllocationSize)
5504
5515
return malloc (size);
5505
5516
5506
5517
// Allocate out of the pool.
5518
+ auto sizeWithHeader = size;
5519
+ if (SWIFT_UNLIKELY (_swift_debug_metadataAllocationIterationEnabled))
5520
+ sizeWithHeader += sizeof (AllocationHeader);
5507
5521
PoolRange curState = AllocationPool.load (std::memory_order_relaxed);
5508
- auto sizeWithHeader = size + sizeof (AllocationHeader);
5509
5522
while (true ) {
5510
5523
char *allocation;
5511
5524
PoolRange newState;
@@ -5518,18 +5531,21 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
5518
5531
newState = PoolRange{curState.Begin + sizeWithHeader,
5519
5532
curState.Remaining - sizeWithHeader};
5520
5533
} else {
5521
- auto poolSize = PoolRange::PageSize - sizeof (PoolTrailer);
5534
+ auto poolSize = PoolRange::PageSize;
5535
+ if (SWIFT_UNLIKELY (_swift_debug_metadataAllocationIterationEnabled))
5536
+ poolSize -= sizeof (PoolTrailer);
5522
5537
allocatedNewPage = true ;
5523
5538
allocation = new char [PoolRange::PageSize];
5524
5539
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
+ }
5530
5546
newState = PoolRange{allocation + sizeWithHeader,
5531
5547
poolSize - sizeWithHeader};
5532
- __asan_poison_memory_region (allocation, PoolRange::PageSize );
5548
+ __asan_poison_memory_region (allocation, newState. Remaining );
5533
5549
}
5534
5550
5535
5551
// Swap in the new state.
@@ -5541,11 +5557,15 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
5541
5557
__msan_allocated_memory (allocation, sizeWithHeader);
5542
5558
__asan_unpoison_memory_region (allocation, sizeWithHeader);
5543
5559
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;
5547
5564
5548
- return allocation + sizeof (AllocationHeader);
5565
+ return allocation + sizeof (AllocationHeader);
5566
+ } else {
5567
+ return allocation;
5568
+ }
5549
5569
}
5550
5570
5551
5571
// If it failed, go back to a neutral state and try again.
0 commit comments