diff options
Diffstat (limited to 'standalone/secondary.h')
-rw-r--r-- | standalone/secondary.h | 75 |
1 files changed, 29 insertions, 46 deletions
diff --git a/standalone/secondary.h b/standalone/secondary.h index 2d177576258..ea5d6808aec 100644 --- a/standalone/secondary.h +++ b/standalone/secondary.h @@ -28,10 +28,7 @@ namespace scudo { namespace LargeBlock { -struct alignas(Max<uptr>(archSupportsMemoryTagging() - ? archMemoryTagGranuleSize() - : 1, - 1U << SCUDO_MIN_ALIGNMENT_LOG)) Header { +struct Header { LargeBlock::Header *Prev; LargeBlock::Header *Next; uptr CommitBase; @@ -41,12 +38,9 @@ struct alignas(Max<uptr>(archSupportsMemoryTagging() [[no_unique_address]] MapPlatformData Data; }; -static_assert(sizeof(Header) % (1U << SCUDO_MIN_ALIGNMENT_LOG) == 0, ""); -static_assert(!archSupportsMemoryTagging() || - sizeof(Header) % archMemoryTagGranuleSize() == 0, - ""); - -constexpr uptr getHeaderSize() { return sizeof(Header); } +constexpr uptr getHeaderSize() { + return roundUpTo(sizeof(Header), 1U << SCUDO_MIN_ALIGNMENT_LOG); +} template <typename Config> static uptr addHeaderTag(uptr Ptr) { if (allocatorSupportsMemoryTagging<Config>()) @@ -55,7 +49,8 @@ template <typename Config> static uptr addHeaderTag(uptr Ptr) { } template <typename Config> static Header *getHeader(uptr Ptr) { - return reinterpret_cast<Header *>(addHeaderTag<Config>(Ptr)) - 1; + return reinterpret_cast<Header *>(addHeaderTag<Config>(Ptr) - + getHeaderSize()); } template <typename Config> static Header *getHeader(const void *Ptr) { @@ -71,6 +66,7 @@ static void unmap(LargeBlock::Header *H) { class MapAllocatorNoCache { public: + void initLinkerInitialized(UNUSED s32 ReleaseToOsInterval) {} void init(UNUSED s32 ReleaseToOsInterval) {} bool retrieve(UNUSED Options Options, UNUSED uptr Size, UNUSED uptr Alignment, UNUSED LargeBlock::Header **H, UNUSED bool *Zeroed) { @@ -82,7 +78,6 @@ public: void enable() {} void releaseToOS() {} void disableMemoryTagging() {} - void unmapTestOnly() {} bool setOption(Option O, UNUSED sptr Value) { if (O == Option::ReleaseInterval || O == Option::MaxCacheEntriesCount || O == Option::MaxCacheEntrySize) @@ -113,19 +108,6 @@ void mapSecondary(Options Options, uptr CommitBase, uptr CommitSize, } } -// Template specialization to avoid producing zero-length array -template <typename T, size_t Size> class NonZeroLengthArray { -public: - T &operator[](uptr Idx) { return values[Idx]; } - -private: - T values[Size]; -}; -template <typename T> class NonZeroLengthArray<T, 0> { -public: - T &operator[](uptr UNUSED Idx) { UNREACHABLE("Unsupported!"); } -}; - template <typename Config> class MapAllocatorCache { public: // Ensure the default maximum specified fits the array. @@ -133,14 +115,17 @@ public: Config::SecondaryCacheEntriesArraySize, ""); - void init(s32 ReleaseToOsInterval) { - DCHECK_EQ(EntriesCount, 0U); + void initLinkerInitialized(s32 ReleaseToOsInterval) { setOption(Option::MaxCacheEntriesCount, static_cast<sptr>(Config::SecondaryCacheDefaultMaxEntriesCount)); setOption(Option::MaxCacheEntrySize, static_cast<sptr>(Config::SecondaryCacheDefaultMaxEntrySize)); setOption(Option::ReleaseInterval, static_cast<sptr>(ReleaseToOsInterval)); } + void init(s32 ReleaseToOsInterval) { + memset(this, 0, sizeof(*this)); + initLinkerInitialized(ReleaseToOsInterval); + } void store(Options Options, LargeBlock::Header *H) { if (!canCache(H->CommitSize)) @@ -232,7 +217,7 @@ public: const u32 MaxCount = atomic_load_relaxed(&MaxEntriesCount); bool Found = false; CachedBlock Entry; - uptr HeaderPos = 0; + uptr HeaderPos; { ScopedLock L(Mutex); if (EntriesCount == 0) @@ -336,8 +321,6 @@ public: void enable() { Mutex.unlock(); } - void unmapTestOnly() { empty(); } - private: void empty() { struct { @@ -408,20 +391,21 @@ private: atomic_s32 ReleaseToOsIntervalMs = {}; CachedBlock Entries[Config::SecondaryCacheEntriesArraySize] = {}; - NonZeroLengthArray<CachedBlock, Config::SecondaryCacheQuarantineSize> - Quarantine = {}; + CachedBlock Quarantine[Config::SecondaryCacheQuarantineSize] = {}; }; template <typename Config> class MapAllocator { public: - void init(GlobalStats *S, s32 ReleaseToOsInterval = -1) { - DCHECK_EQ(AllocatedBytes, 0U); - DCHECK_EQ(FreedBytes, 0U); - Cache.init(ReleaseToOsInterval); - Stats.init(); + void initLinkerInitialized(GlobalStats *S, s32 ReleaseToOsInterval = -1) { + Cache.initLinkerInitialized(ReleaseToOsInterval); + Stats.initLinkerInitialized(); if (LIKELY(S)) S->link(&Stats); } + void init(GlobalStats *S, s32 ReleaseToOsInterval = -1) { + memset(this, 0, sizeof(*this)); + initLinkerInitialized(S, ReleaseToOsInterval); + } void *allocate(Options Options, uptr Size, uptr AlignmentHint = 0, uptr *BlockEnd = nullptr, @@ -459,7 +443,7 @@ public: } } - bool canCache(uptr Size) { return Cache.canCache(Size); } + uptr canCache(uptr Size) { return Cache.canCache(Size); } bool setOption(Option O, sptr Value) { return Cache.setOption(O, Value); } @@ -467,8 +451,6 @@ public: void disableMemoryTagging() { Cache.disableMemoryTagging(); } - void unmapTestOnly() { Cache.unmapTestOnly(); } - private: typename Config::SecondaryCache Cache; @@ -499,7 +481,7 @@ void *MapAllocator<Config>::allocate(Options Options, uptr Size, uptr Alignment, FillContentsMode FillContents) { if (Options.get(OptionBit::AddLargeAllocationSlack)) Size += 1UL << SCUDO_MIN_ALIGNMENT_LOG; - Alignment = Max(Alignment, uptr(1U) << SCUDO_MIN_ALIGNMENT_LOG); + Alignment = Max(Alignment, 1UL << SCUDO_MIN_ALIGNMENT_LOG); const uptr PageSize = getPageSizeCached(); uptr RoundedSize = roundUpTo(roundUpTo(Size, Alignment) + LargeBlock::getHeaderSize() + @@ -616,11 +598,12 @@ void MapAllocator<Config>::deallocate(Options Options, void *Ptr) { template <typename Config> void MapAllocator<Config>::getStats(ScopedString *Str) const { - Str->append("Stats: MapAllocator: allocated %u times (%zuK), freed %u times " - "(%zuK), remains %u (%zuK) max %zuM\n", - NumberOfAllocs, AllocatedBytes >> 10, NumberOfFrees, - FreedBytes >> 10, NumberOfAllocs - NumberOfFrees, - (AllocatedBytes - FreedBytes) >> 10, LargestSize >> 20); + Str->append( + "Stats: MapAllocator: allocated %zu times (%zuK), freed %zu times " + "(%zuK), remains %zu (%zuK) max %zuM\n", + NumberOfAllocs, AllocatedBytes >> 10, NumberOfFrees, FreedBytes >> 10, + NumberOfAllocs - NumberOfFrees, (AllocatedBytes - FreedBytes) >> 10, + LargestSize >> 20); } } // namespace scudo |