Log number of bytes reclaimed at each step of memory pressure relief.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Apr 2014 19:19:58 +0000 (19:19 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Apr 2014 19:19:58 +0000 (19:19 +0000)
<https://webkit.org/b/131751>

Reviewed by Antti Koivisto.

* platform/MemoryPressureHandler.h:
* platform/MemoryPressureHandler.cpp:
(WebCore::MemoryPressureHandler::ReliefLogger::platformLog):
(WebCore::MemoryPressureHandler::ReliefLogger::platformMemoryUsage):
(WebCore::MemoryPressureHandler::ReliefLogger::ReliefLogger):
(WebCore::MemoryPressureHandler::ReliefLogger::~ReliefLogger):
* platform/cocoa/MemoryPressureHandlerCocoa.mm:
(WebCore::MemoryPressureHandlerCocoa::ReliefLogger::platformMemoryUsage):
(WebCore::MemoryPressureHandlerCocoa::ReliefLogger::platformLog):

    Add a simple RAII helper to check memory usage before and after
    a block of code, and then dump the delta to system log.

(WebCore::MemoryPressureHandler::releaseMemory):
* platform/cocoa/MemoryPressureHandlerCocoa.mm:
(WebCore::MemoryPressureHandler::platformReleaseMemory):

    Use ReliefLogger to annotate the various attempts to reduce
    our memory footprint. This will help us understand the efficiency
    of our current strategy.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@167445 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/MemoryPressureHandler.cpp
Source/WebCore/platform/MemoryPressureHandler.h
Source/WebCore/platform/cocoa/MemoryPressureHandlerCocoa.mm

index 6961dce..5076b93 100644 (file)
@@ -1,3 +1,31 @@
+2014-04-17  Andreas Kling  <akling@apple.com>
+
+        Log number of bytes reclaimed at each step of memory pressure relief.
+        <https://webkit.org/b/131751>
+
+        Reviewed by Antti Koivisto.
+
+        * platform/MemoryPressureHandler.h:
+        * platform/MemoryPressureHandler.cpp:
+        (WebCore::MemoryPressureHandler::ReliefLogger::platformLog):
+        (WebCore::MemoryPressureHandler::ReliefLogger::platformMemoryUsage):
+        (WebCore::MemoryPressureHandler::ReliefLogger::ReliefLogger):
+        (WebCore::MemoryPressureHandler::ReliefLogger::~ReliefLogger):
+        * platform/cocoa/MemoryPressureHandlerCocoa.mm:
+        (WebCore::MemoryPressureHandlerCocoa::ReliefLogger::platformMemoryUsage):
+        (WebCore::MemoryPressureHandlerCocoa::ReliefLogger::platformLog):
+
+            Add a simple RAII helper to check memory usage before and after
+            a block of code, and then dump the delta to system log.
+
+        (WebCore::MemoryPressureHandler::releaseMemory):
+        * platform/cocoa/MemoryPressureHandlerCocoa.mm:
+        (WebCore::MemoryPressureHandler::platformReleaseMemory):
+
+            Use ReliefLogger to annotate the various attempts to reduce
+            our memory footprint. This will help us understand the efficiency
+            of our current strategy.
+
 2014-04-17  David Hyatt  <hyatt@apple.com>
 
         [New Multicolumn] columnNumberForOffset is not patched for new multicolumn code yet.
index 6439614..a3749d8 100644 (file)
@@ -67,32 +67,56 @@ MemoryPressureHandler::MemoryPressureHandler()
 
 void MemoryPressureHandler::releaseMemory(bool critical)
 {
-    int savedPageCacheCapacity = pageCache()->capacity();
-    pageCache()->setCapacity(0);
-    pageCache()->setCapacity(savedPageCacheCapacity);
-
-    fontCache()->purgeInactiveFontData();
-
-    memoryCache()->pruneToPercentage(0);
-
-    cssValuePool().drain();
-
-    clearWidthCaches();
-
-    for (auto* document : Document::allDocuments())
-        document->clearStyleResolver();
-
-    gcController().discardAllCompiledCode();
+    {
+        ReliefLogger log("Empty the PageCache");
+        int savedPageCacheCapacity = pageCache()->capacity();
+        pageCache()->setCapacity(0);
+        pageCache()->setCapacity(savedPageCacheCapacity);
+    }
+
+    {
+        ReliefLogger log("Purge inactive FontData");
+        fontCache()->purgeInactiveFontData();
+    }
+
+    {
+        ReliefLogger log("Prune MemoryCache");
+        memoryCache()->pruneToPercentage(0);
+    }
+
+    {
+        ReliefLogger log("Drain CSSValuePool");
+        cssValuePool().drain();
+    }
+
+    {
+        ReliefLogger log("Clear WidthCaches");
+        clearWidthCaches();
+    }
+
+    {
+        ReliefLogger log("Discard StyleResolvers");
+        for (auto* document : Document::allDocuments())
+            document->clearStyleResolver();
+    }
+
+    {
+        ReliefLogger log("Discard all JIT-compiled code");
+        gcController().discardAllCompiledCode();
+    }
 
     platformReleaseMemory(critical);
 
-    // FastMalloc has lock-free thread specific caches that can only be cleared from the thread itself.
-    StorageThread::releaseFastMallocFreeMemoryInAllThreads();
-    WorkerThread::releaseFastMallocFreeMemoryInAllThreads();
+    {
+        ReliefLogger log("Release free FastMalloc memory");
+        // FastMalloc has lock-free thread specific caches that can only be cleared from the thread itself.
+        StorageThread::releaseFastMallocFreeMemoryInAllThreads();
+        WorkerThread::releaseFastMallocFreeMemoryInAllThreads();
 #if ENABLE(ASYNC_SCROLLING)
-    ScrollingThread::dispatch(bind(WTF::releaseFastMallocFreeMemory));
+        ScrollingThread::dispatch(bind(WTF::releaseFastMallocFreeMemory));
 #endif
-    WTF::releaseFastMallocFreeMemory();
+        WTF::releaseFastMallocFreeMemory();
+    }
 }
 
 #if !PLATFORM(COCOA)
@@ -101,6 +125,8 @@ void MemoryPressureHandler::uninstall() { }
 void MemoryPressureHandler::holdOff(unsigned) { }
 void MemoryPressureHandler::respondToMemoryPressure() { }
 void MemoryPressureHandler::platformReleaseMemory(bool) { }
+void MemoryPressureHandler::ReliefLogger::platformLog() { }
+size_t MemoryPressureHandler::ReliefLogger::platformMemoryUsage() { return 0; }
 #endif
 
 } // namespace WebCore
index 17b83a9..5803531 100644 (file)
@@ -70,6 +70,27 @@ public:
     void respondToMemoryPressureIfNeeded();
 #endif
 
+    class ReliefLogger {
+    public:
+        explicit ReliefLogger(const char *log)
+            : m_logString(log)
+            , m_initialMemory(platformMemoryUsage())
+        {
+        }
+
+        ~ReliefLogger()
+        {
+            platformLog();
+        }
+
+    private:
+        size_t platformMemoryUsage();
+        void platformLog();
+
+        const char* m_logString;
+        size_t m_initialMemory;
+};
+
 private:
     void uninstall();
 
index 659291e..167a496 100644 (file)
@@ -31,6 +31,8 @@
 #import "LayerPool.h"
 #import "Logging.h"
 #import "WebCoreSystemInterface.h"
+#import <mach/mach.h>
+#import <mach/task_info.h>
 #import <malloc/malloc.h>
 #import <notify.h>
 #import <wtf/CurrentTime.h>
@@ -46,10 +48,16 @@ namespace WebCore {
 void MemoryPressureHandler::platformReleaseMemory(bool)
 {
 #if PLATFORM(MAC)
-    LayerPool::sharedPool()->drain();
+    {
+        ReliefLogger log("Drain LayerPool");
+        LayerPool::sharedPool()->drain();
+    }
 #endif
 #if USE(IOSURFACE)
-    IOSurfacePool::sharedPool().discardAllSurfaces();
+    {
+        ReliefLogger log("Drain IOSurfacePool");
+        IOSurfacePool::sharedPool().discardAllSurfaces();
+    }
 #endif
 }
 
@@ -159,6 +167,34 @@ void MemoryPressureHandler::respondToMemoryPressure()
     holdOff(std::max(holdOffTime, s_minimumHoldOffTime));
 }
 
+size_t MemoryPressureHandler::ReliefLogger::platformMemoryUsage()
+{
+    task_vm_info_data_t vmInfo;
+    mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
+    kern_return_t err = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count);
+    if (err != KERN_SUCCESS)
+        return static_cast<size_t>(-1);
+
+    return vmInfo.internal;
+}
+
+void MemoryPressureHandler::ReliefLogger::platformLog()
+{
+    size_t currentMemory = platformMemoryUsage();
+    if (currentMemory == static_cast<size_t>(-1) || m_initialMemory == static_cast<size_t>(-1)) {
+        NSLog(@"%s (Unable to get dirty memory information for process)\n", m_logString);
+        return;
+    }
+
+    ssize_t memoryDiff = currentMemory - m_initialMemory;
+    if (memoryDiff < 0)
+        NSLog(@"Pressure relief: %s: -dirty %ld bytes (from %ld to %ld)\n", m_logString, (memoryDiff * -1), m_initialMemory, currentMemory);
+    else if (memoryDiff > 0)
+        NSLog(@"Pressure relief: %s: +dirty %ld bytes (from %ld to %ld)\n", m_logString, memoryDiff, m_initialMemory, currentMemory);
+    else
+        NSLog(@"Pressure relief: %s: =dirty (at %ld bytes)\n", m_logString, currentMemory);
+}
+
 #if PLATFORM(IOS)
 static void respondToMemoryPressureCallback(CFRunLoopObserverRef observer, CFRunLoopActivity /*activity*/, void* /*info*/)
 {