Title: [246974] releases/WebKitGTK/webkit-2.24/Source/bmalloc
Revision
246974
Author
[email protected]
Date
2019-07-01 01:53:28 -0700 (Mon, 01 Jul 2019)

Log Message

Merge r244244 - [bmalloc][Linux] Add support for memory status calculation
https://bugs.webkit.org/show_bug.cgi?id=195938

Reviewed by Carlos Garcia Campos.

Memory status and under-memory-pressure capabilities in bmalloc can be
implemented on Linux by reading and parsing the statm file under the
proc filesystem.

We retrieve the resident set size from the statm file and multiply it
with the page size. This gives an upper-bound estimate of the memory
that's being consumed by the process.

The statm-based estimate seems preferable to other alternatives. One
such alternative would be reading and parsing more-detailed smaps file,
also exposed under the proc filesystem. This is at the moment being done
in WTF's MemoryFootprint implementation for Linux systems, but on Linux
ports this operation is being throttled to only execute once per second
because of the big computing expense required to read and parse out the
data. A future MemoryFootprint implementation could simply retrieve the
memory footprint value from bmalloc.

Another alternative is the Linux taskstats interface. This one would
require utilizing a netlink socket to retrieve the necessary statistics,
but it requires the process to have elevated privileges, which is a
blocker.

* bmalloc/AvailableMemory.cpp:
(bmalloc::LinuxMemory::singleton):
(bmalloc::LinuxMemory::footprint const):
(bmalloc::computeAvailableMemory):
(bmalloc::memoryStatus):
* bmalloc/AvailableMemory.h:
(bmalloc::isUnderMemoryPressure):
* bmalloc/bmalloc.h:

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.24/Source/bmalloc/ChangeLog (246973 => 246974)


--- releases/WebKitGTK/webkit-2.24/Source/bmalloc/ChangeLog	2019-07-01 08:53:25 UTC (rev 246973)
+++ releases/WebKitGTK/webkit-2.24/Source/bmalloc/ChangeLog	2019-07-01 08:53:28 UTC (rev 246974)
@@ -1,3 +1,41 @@
+2019-04-13  Zan Dobersek  <[email protected]>
+
+        [bmalloc][Linux] Add support for memory status calculation
+        https://bugs.webkit.org/show_bug.cgi?id=195938
+
+        Reviewed by Carlos Garcia Campos.
+
+        Memory status and under-memory-pressure capabilities in bmalloc can be
+        implemented on Linux by reading and parsing the statm file under the
+        proc filesystem.
+
+        We retrieve the resident set size from the statm file and multiply it
+        with the page size. This gives an upper-bound estimate of the memory
+        that's being consumed by the process.
+
+        The statm-based estimate seems preferable to other alternatives. One
+        such alternative would be reading and parsing more-detailed smaps file,
+        also exposed under the proc filesystem. This is at the moment being done
+        in WTF's MemoryFootprint implementation for Linux systems, but on Linux
+        ports this operation is being throttled to only execute once per second
+        because of the big computing expense required to read and parse out the
+        data. A future MemoryFootprint implementation could simply retrieve the
+        memory footprint value from bmalloc.
+
+        Another alternative is the Linux taskstats interface. This one would
+        require utilizing a netlink socket to retrieve the necessary statistics,
+        but it requires the process to have elevated privileges, which is a
+        blocker.
+
+        * bmalloc/AvailableMemory.cpp:
+        (bmalloc::LinuxMemory::singleton):
+        (bmalloc::LinuxMemory::footprint const):
+        (bmalloc::computeAvailableMemory):
+        (bmalloc::memoryStatus):
+        * bmalloc/AvailableMemory.h:
+        (bmalloc::isUnderMemoryPressure):
+        * bmalloc/bmalloc.h:
+
 2019-02-19  Yusuke Suzuki  <[email protected]>
 
         [bmalloc] bmalloc::Heap is allocated even though we use system malloc mode

Modified: releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/AvailableMemory.cpp (246973 => 246974)


--- releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/AvailableMemory.cpp	2019-07-01 08:53:25 UTC (rev 246973)
+++ releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/AvailableMemory.cpp	2019-07-01 08:53:28 UTC (rev 246974)
@@ -43,6 +43,10 @@
 #import <mach/mach_error.h>
 #import <math.h>
 #elif BOS(UNIX)
+#if BOS(LINUX)
+#include <algorithm>
+#include <fcntl.h>
+#endif
 #include <unistd.h>
 #endif
 
@@ -88,6 +92,62 @@
 }
 #endif
 
+#if BOS(UNIX)
+struct LinuxMemory {
+    static const LinuxMemory& singleton()
+    {
+        static LinuxMemory s_singleton;
+        static std::once_flag s_onceFlag;
+        std::call_once(s_onceFlag,
+            [] {
+                long numPages = sysconf(_SC_PHYS_PAGES);
+                s_singleton.pageSize = sysconf(_SC_PAGE_SIZE);
+                if (numPages == -1 || s_singleton.pageSize == -1)
+                    s_singleton.availableMemory = availableMemoryGuess;
+                else
+                    s_singleton.availableMemory = numPages * s_singleton.pageSize;
+
+                s_singleton.statmFd = open("/proc/self/statm", O_RDONLY | O_CLOEXEC);
+            });
+        return s_singleton;
+    }
+
+    size_t footprint() const
+    {
+        if (statmFd == -1)
+            return 0;
+
+        std::array<char, 256> statmBuffer;
+        ssize_t numBytes = pread(statmFd, statmBuffer.data(), statmBuffer.size(), 0);
+        if (numBytes <= 0)
+            return 0;
+
+        std::array<char, 32> rssBuffer;
+        {
+            auto begin = std::find(statmBuffer.begin(), statmBuffer.end(), ' ');
+            if (begin == statmBuffer.end())
+                return 0;
+
+            std::advance(begin, 1);
+            auto end = std::find(begin, statmBuffer.end(), ' ');
+            if (end == statmBuffer.end())
+                return 0;
+
+            auto last = std::copy_n(begin, std::min<size_t>(31, std::distance(begin, end)), rssBuffer.begin());
+            *last = '\0';
+        }
+
+        unsigned long dirtyPages = strtoul(rssBuffer.data(), nullptr, 10);
+        return dirtyPages * pageSize;
+    }
+
+    long pageSize { 0 };
+    size_t availableMemory { 0 };
+
+    int statmFd { -1 };
+};
+#endif
+
 static size_t computeAvailableMemory()
 {
 #if BOS(DARWIN)
@@ -100,6 +160,8 @@
     // Round up the memory size to a multiple of 128MB because max_mem may not be exactly 512MB
     // (for example) and we have code that depends on those boundaries.
     return ((sizeAccordingToKernel + multiple - 1) / multiple) * multiple;
+#elif BOS(LINUX)
+    return LinuxMemory::singleton().availableMemory;
 #elif BOS(UNIX)
     long pages = sysconf(_SC_PHYS_PAGES);
     long pageSize = sysconf(_SC_PAGE_SIZE);
@@ -121,9 +183,10 @@
     return availableMemory;
 }
 
-#if BPLATFORM(IOS_FAMILY)
+#if BPLATFORM(IOS_FAMILY) || BOS(LINUX)
 MemoryStatus memoryStatus()
 {
+#if BPLATFORM(IOS_FAMILY)
     task_vm_info_data_t vmInfo;
     mach_msg_type_number_t vmSize = TASK_VM_INFO_COUNT;
     
@@ -132,8 +195,13 @@
         memoryFootprint = static_cast<size_t>(vmInfo.phys_footprint);
 
     double percentInUse = static_cast<double>(memoryFootprint) / static_cast<double>(availableMemory());
+#elif BOS(LINUX)
+    auto& memory = LinuxMemory::singleton();
+    size_t memoryFootprint = memory.footprint();
+    double percentInUse = static_cast<double>(memoryFootprint) / static_cast<double>(memory.availableMemory);
+#endif
+
     double percentAvailableMemoryInUse = std::min(percentInUse, 1.0);
-    
     return MemoryStatus(memoryFootprint, percentAvailableMemoryInUse);
 }
 #endif

Modified: releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/AvailableMemory.h (246973 => 246974)


--- releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/AvailableMemory.h	2019-07-01 08:53:25 UTC (rev 246973)
+++ releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/AvailableMemory.h	2019-07-01 08:53:28 UTC (rev 246974)
@@ -32,7 +32,7 @@
 
 size_t availableMemory();
 
-#if BPLATFORM(IOS_FAMILY)
+#if BPLATFORM(IOS_FAMILY) || BOS(LINUX)
 struct MemoryStatus {
     MemoryStatus(size_t memoryFootprint, double percentAvailableMemoryInUse)
         : memoryFootprint(memoryFootprint)
@@ -61,7 +61,7 @@
 
 inline bool isUnderMemoryPressure()
 {
-#if BPLATFORM(IOS_FAMILY)
+#if BPLATFORM(IOS_FAMILY) || BOS(LINUX)
     return percentAvailableMemoryInUse() > memoryPressureThreshold;
 #else
     return false;

Modified: releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/bmalloc.h (246973 => 246974)


--- releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/bmalloc.h	2019-07-01 08:53:25 UTC (rev 246973)
+++ releases/WebKitGTK/webkit-2.24/Source/bmalloc/bmalloc/bmalloc.h	2019-07-01 08:53:28 UTC (rev 246974)
@@ -111,7 +111,7 @@
     return bmalloc::availableMemory();
 }
     
-#if BPLATFORM(IOS_FAMILY)
+#if BPLATFORM(IOS_FAMILY) || BOS(LINUX)
 inline size_t memoryFootprint()
 {
     return bmalloc::memoryFootprint();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to