summaryrefslogtreecommitdiff
path: root/standalone/secondary.h
diff options
context:
space:
mode:
Diffstat (limited to 'standalone/secondary.h')
-rw-r--r--standalone/secondary.h75
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