@@ -5471,13 +5471,17 @@ namespace {
5471
5471
size_t Remaining;
5472
5472
};
5473
5473
5474
+ // / The trailer placed at the end of each pool allocation, used when
5475
+ // / SWIFT_DEBUG_ENABLE_METADATA_ALLOCATION_ITERATION is on.
5474
5476
struct PoolTrailer {
5475
5477
void *PrevTrailer;
5476
5478
size_t PoolSize;
5477
5479
};
5478
5480
5479
- static constexpr size_t InitialPoolSize = 64 * 1024 - sizeof (PoolTrailer) ;
5481
+ static constexpr size_t InitialPoolSize = 64 * 1024 ;
5480
5482
5483
+ // / The header placed before each allocation, used when
5484
+ // / SWIFT_DEBUG_ENABLE_METADATA_ALLOCATION_ITERATION is on.
5481
5485
struct alignas (void *) AllocationHeader {
5482
5486
uint16_t Size;
5483
5487
uint16_t Tag;
@@ -5488,7 +5492,6 @@ namespace {
5488
5492
// doesn't cost us anything in binary size.
5489
5493
alignas (void *) static struct {
5490
5494
char Pool[InitialPoolSize];
5491
- PoolTrailer Trailer{ nullptr , InitialPoolSize };
5492
5495
} InitialAllocationPool;
5493
5496
static std::atomic<PoolRange>
5494
5497
AllocationPool{PoolRange{InitialAllocationPool.Pool ,
@@ -5497,18 +5500,31 @@ AllocationPool{PoolRange{InitialAllocationPool.Pool,
5497
5500
bool swift::_swift_debug_metadataAllocationIterationEnabled = false ;
5498
5501
const void * const swift::_swift_debug_allocationPoolPointer = &AllocationPool;
5499
5502
5503
+ static void checkAllocatorDebugEnvironmentVariable (void *context) {
5504
+ const char *value =
5505
+ getenv (" SWIFT_DEBUG_ENABLE_METADATA_ALLOCATION_ITERATION" );
5506
+ if (value && (value[0 ] == ' 1' || value[0 ] == ' y' || value[0 ] == ' Y' )) {
5507
+ _swift_debug_metadataAllocationIterationEnabled = true ;
5508
+ // Write a PoolTrailer to the end of InitialAllocationPool and shrink
5509
+ // the pool accordingly.
5510
+ auto poolCopy = AllocationPool.load (std::memory_order_relaxed);
5511
+ assert (poolCopy.Begin == InitialAllocationPool.Pool );
5512
+ size_t newPoolSize = InitialPoolSize - sizeof (PoolTrailer);
5513
+ PoolTrailer trailer = { nullptr , newPoolSize };
5514
+ memcpy (InitialAllocationPool.Pool + newPoolSize, &trailer,
5515
+ sizeof (trailer));
5516
+ poolCopy.Remaining = newPoolSize;
5517
+ AllocationPool.store (poolCopy, std::memory_order_relaxed);
5518
+ }
5519
+ }
5520
+
5500
5521
void *MetadataAllocator::Allocate (size_t size, size_t alignment) {
5501
5522
assert (Tag != 0 );
5502
5523
assert (alignment <= alignof (void *));
5503
5524
assert (size % alignof (void *) == 0 );
5504
5525
5505
5526
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 );
5527
+ SWIFT_ONCE_F (getenvToken, checkAllocatorDebugEnvironmentVariable, nullptr );
5512
5528
5513
5529
// If the size is larger than the maximum, just use malloc.
5514
5530
if (size > PoolRange::MaxPoolAllocationSize)
0 commit comments