| Index: base/allocator/partition_allocator/page_allocator.cc
|
| diff --git a/base/allocator/partition_allocator/page_allocator.cc b/base/allocator/partition_allocator/page_allocator.cc
|
| index bb737b3341986d73739a2f5bed84d0c33052b1ce..1dba6d319f4a543c42f7ff02108e3cf01ec17009 100644
|
| --- a/base/allocator/partition_allocator/page_allocator.cc
|
| +++ b/base/allocator/partition_allocator/page_allocator.cc
|
| @@ -213,8 +213,9 @@ bool SetSystemPagesAccessible(void* address, size_t length) {
|
| #endif
|
| }
|
|
|
| -void DecommitSystemPages(void* address, size_t length) {
|
| +void DecommitSystemPages(void* address, size_t length, bool purge_hint) {
|
| DCHECK(!(length & kSystemPageOffsetMask));
|
| + ALLOW_UNUSED_LOCAL(purge_hint);
|
| #if defined(OS_POSIX)
|
| #if defined(OS_MACOSX)
|
| // On macOS, MADV_FREE_REUSABLE has comparable behavior to MADV_FREE, but also
|
| @@ -222,7 +223,21 @@ void DecommitSystemPages(void* address, size_t length) {
|
| // and memory-infra to correctly track the pages.
|
| int ret = madvise(address, length, MADV_FREE_REUSABLE);
|
| #else
|
| - int ret = madvise(address, length, MADV_FREE);
|
| + int advice = MADV_FREE;
|
| +// For platforms known to support MADV_REMOVE, use it to promptly
|
| +// let go of the pages. |purge_hint| is otherwise disregarded, leaving
|
| +// it to the OS' policy for recycling MADV_FREE'd pages.
|
| +#if defined(OS_LINUX) || defined(OS_ANDROID)
|
| + if (purge_hint)
|
| + advice = MADV_REMOVE;
|
| +#endif
|
| + int ret = madvise(address, length, advice);
|
| +#if defined(OS_LINUX) || defined(OS_ANDROID)
|
| + // If MADV_REMOVE's zero'ing fails due to not being writable,
|
| + // fall back to freeing.
|
| + if (ret != 0 && purge_hint)
|
| + ret = madvise(address, length, MADV_FREE);
|
| +#endif
|
| #endif
|
| if (ret != 0 && errno == EINVAL) {
|
| // MADV_FREE only works on Linux 4.5+ . If request failed,
|
|
|