From: Kostya Kortchinsky Date: Thu, 30 Jan 2020 19:06:49 +0000 (-0800) Subject: [scudo][standalone] Release secondary memory on purge X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=654f5d684561d784fa8927d3de31b7dab3f28087;p=platform%2Fupstream%2Fllvm.git [scudo][standalone] Release secondary memory on purge Summary: The Secondary's cache needs to be released when the Combined's `releaseToOS` function is called (via `M_PURGE`) for example, which this CL adds. Additionally, if doing a forced release, we'll release the transfer batch class as well since now we can do that. There is a couple of other house keeping changes as well: - read the page size only once in the Secondary Cache `store` - remove the interval check for `CanRelease`: we are going to make that configurable via `mallopt` so this needs not be set in stone there. Reviewers: cferris, hctim, pcc, eugenis Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D73730 --- diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index 6e3bd09..4ae398a 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -567,6 +567,7 @@ public: void releaseToOS() { initThreadMaybe(); Primary.releaseToOS(); + Secondary.releaseToOS(); } // Iterate over all chunks and call a callback for all busy chunks located diff --git a/compiler-rt/lib/scudo/standalone/primary32.h b/compiler-rt/lib/scudo/standalone/primary32.h index 62d7981..ab7a1f3 100644 --- a/compiler-rt/lib/scudo/standalone/primary32.h +++ b/compiler-rt/lib/scudo/standalone/primary32.h @@ -73,8 +73,7 @@ public: SizeClassInfo *Sci = getSizeClassInfo(I); Sci->RandState = getRandomU32(&Seed); // See comment in the 64-bit primary about releasing smaller size classes. - Sci->CanRelease = (ReleaseToOsInterval >= 0) && - (I != SizeClassMap::BatchClassId) && + Sci->CanRelease = (I != SizeClassMap::BatchClassId) && (getSizeByClassId(I) >= (PageSize / 32)); } ReleaseToOsIntervalMs = ReleaseToOsInterval; @@ -178,8 +177,6 @@ public: uptr releaseToOS() { uptr TotalReleasedBytes = 0; for (uptr I = 0; I < NumClasses; I++) { - if (I == SizeClassMap::BatchClassId) - continue; SizeClassInfo *Sci = getSizeClassInfo(I); ScopedLock L(Sci->Mutex); TotalReleasedBytes += releaseToOSMaybe(Sci, I, /*Force=*/true); diff --git a/compiler-rt/lib/scudo/standalone/primary64.h b/compiler-rt/lib/scudo/standalone/primary64.h index 5b83f0c..02e8051 100644 --- a/compiler-rt/lib/scudo/standalone/primary64.h +++ b/compiler-rt/lib/scudo/standalone/primary64.h @@ -86,8 +86,7 @@ public: // memory accesses which ends up being fairly costly. The current lower // limit is mostly arbitrary and based on empirical observations. // TODO(kostyak): make the lower limit a runtime option - Region->CanRelease = (ReleaseToOsInterval >= 0) && - (I != SizeClassMap::BatchClassId) && + Region->CanRelease = (I != SizeClassMap::BatchClassId) && (getSizeByClassId(I) >= (PageSize / 32)); Region->RandState = getRandomU32(&Seed); } @@ -190,8 +189,6 @@ public: uptr releaseToOS() { uptr TotalReleasedBytes = 0; for (uptr I = 0; I < NumClasses; I++) { - if (I == SizeClassMap::BatchClassId) - continue; RegionInfo *Region = getRegionInfo(I); ScopedLock L(Region->Mutex); TotalReleasedBytes += releaseToOSMaybe(Region, I, /*Force=*/true); diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h index 0e6ce4c..feb43e7 100644 --- a/compiler-rt/lib/scudo/standalone/secondary.h +++ b/compiler-rt/lib/scudo/standalone/secondary.h @@ -59,6 +59,7 @@ public: static bool canCache(UNUSED uptr Size) { return false; } void disable() {} void enable() {} + void releaseToOS() {} }; template @@ -112,6 +113,7 @@ public: } bool retrieve(uptr Size, LargeBlock::Header **H) { + const uptr PageSize = getPageSizeCached(); ScopedLock L(Mutex); if (EntriesCount == 0) return false; @@ -121,7 +123,7 @@ public: const uptr BlockSize = Entries[I].BlockEnd - Entries[I].Block; if (Size > BlockSize) continue; - if (Size < BlockSize - getPageSizeCached() * 4U) + if (Size < BlockSize - PageSize * 4U) continue; *H = reinterpret_cast(Entries[I].Block); Entries[I].Block = 0; @@ -138,6 +140,8 @@ public: return MaxEntriesCount != 0U && Size <= MaxEntrySize; } + void releaseToOS() { releaseOlderThan(UINT64_MAX); } + void disable() { Mutex.lock(); } void enable() { Mutex.unlock(); } @@ -259,6 +263,8 @@ public: static uptr canCache(uptr Size) { return CacheT::canCache(Size); } + void releaseToOS() { Cache.releaseToOS(); } + private: CacheT Cache;