Title: [139218] trunk/Source
Revision
139218
Author
[email protected]
Date
2013-01-09 12:08:32 -0800 (Wed, 09 Jan 2013)

Log Message

Source/WebCore: Release FastMalloc thread caches on memory warning
https://bugs.webkit.org/show_bug.cgi?id=106471

Reviewed by Geoff Garen.
        
FastMalloc keeps some memory in per-thread caches (currently 2MB each). We currently flush these caches on memory warning 
for the main thread only. We should do it for other WebKit threads that use FastMalloc too.

Call WTF::releaseFastMallocFreeMemory in a bunch of WebCore support threads on memory warning. Unfortunately we don't have 
an uniform way of doing threads so this requires bunch of thread type specific code.
        
Looks to be ~1% progression in membuster3 final and maximum numbers.

* platform/mac/MemoryPressureHandlerMac.mm:
(WebCore::MemoryPressureHandler::releaseMemory):
* storage/StorageTask.cpp:
(WebCore::StorageTask::performTask):
* storage/StorageTask.h:
(WebCore::StorageTask::createReleaseFastMallocFreeMemory):
* storage/StorageThread.cpp:
(WebCore::storageThreads):
(WebCore):
(WebCore::StorageThread::StorageThread):
(WebCore::StorageThread::~StorageThread):
(WebCore::StorageThread::releaseFastMallocFreeMemoryInAllThread):
* storage/StorageThread.h:
(StorageThread):
* workers/WorkerThread.cpp:
(WebCore::threadSetMutex):
(WebCore::workerThreads):
(WebCore::WorkerThread::workerThreadCount):
(WebCore::WorkerThread::WorkerThread):
(WebCore::WorkerThread::~WorkerThread):
(WebCore::WorkerThread::releaseFastMallocFreeMemoryInAllThread):
(WebCore):
* workers/WorkerThread.h:
(WorkerThread):

Source/WTF: Release FastMalloc thread caches on memory warning
https://bugs.webkit.org/show_bug.cgi?id=106471
        
Reviewed by Geoff Garen.

Use TCMalloc_ThreadCache::Cleanup() instead of calling Scavenge() twice. This releases all the memory
and looks nicer too.

* wtf/FastMalloc.cpp:
(WTF::releaseFastMallocFreeMemory):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (139217 => 139218)


--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def	2013-01-09 20:08:32 UTC (rev 139218)
@@ -208,6 +208,7 @@
     ?fastMallocMatchFailed@Internal@WTF@@YAXPAX@Z
     ?fastMallocSize@WTF@@YAIPBX@Z
     ?fastMallocStatistics@WTF@@YA?AUFastMallocStatistics@1@XZ
+    ?releaseFastMallocFreeMemory@WTF@@YAXXZ
     ?fastRealloc@WTF@@YAPAXPAXI@Z
     ?fastStrDup@WTF@@YAPADPBD@Z
     ?fastZeroedMalloc@WTF@@YAPAXI@Z

Modified: trunk/Source/WTF/ChangeLog (139217 => 139218)


--- trunk/Source/WTF/ChangeLog	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WTF/ChangeLog	2013-01-09 20:08:32 UTC (rev 139218)
@@ -1,3 +1,16 @@
+2013-01-09  Antti Koivisto  <[email protected]>
+
+        Release FastMalloc thread caches on memory warning
+        https://bugs.webkit.org/show_bug.cgi?id=106471
+        
+        Reviewed by Geoff Garen.
+
+        Use TCMalloc_ThreadCache::Cleanup() instead of calling Scavenge() twice. This releases all the memory
+        and looks nicer too.
+
+        * wtf/FastMalloc.cpp:
+        (WTF::releaseFastMallocFreeMemory):
+
 2013-01-09  Carlos Garcia Campos  <[email protected]>
 
         Unreviewed. Fix make distcheck.

Modified: trunk/Source/WTF/wtf/FastMalloc.cpp (139217 => 139218)


--- trunk/Source/WTF/wtf/FastMalloc.cpp	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WTF/wtf/FastMalloc.cpp	2013-01-09 20:08:32 UTC (rev 139218)
@@ -4382,17 +4382,13 @@
 void releaseFastMallocFreeMemory()
 {
     // Flush free pages in the current thread cache back to the page heap.
-    // Low watermark mechanism in Scavenge() prevents full return on the first pass.
-    // The second pass flushes everything.
-    if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent()) {
-        threadCache->Scavenge();
-        threadCache->Scavenge();
-    }
+    if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent())
+        threadCache->Cleanup();
 
     SpinLockHolder h(&pageheap_lock);
     pageheap->ReleaseFreePages();
 }
-    
+
 FastMallocStatistics fastMallocStatistics()
 {
     FastMallocStatistics statistics;

Modified: trunk/Source/WebCore/ChangeLog (139217 => 139218)


--- trunk/Source/WebCore/ChangeLog	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WebCore/ChangeLog	2013-01-09 20:08:32 UTC (rev 139218)
@@ -1,3 +1,43 @@
+2013-01-09  Antti Koivisto  <[email protected]>
+
+        Release FastMalloc thread caches on memory warning
+        https://bugs.webkit.org/show_bug.cgi?id=106471
+
+        Reviewed by Geoff Garen.
+        
+        FastMalloc keeps some memory in per-thread caches (currently 2MB each). We currently flush these caches on memory warning 
+        for the main thread only. We should do it for other WebKit threads that use FastMalloc too.
+
+        Call WTF::releaseFastMallocFreeMemory in a bunch of WebCore support threads on memory warning. Unfortunately we don't have 
+        an uniform way of doing threads so this requires bunch of thread type specific code.
+        
+        Looks to be ~1% progression in membuster3 final and maximum numbers.
+
+        * platform/mac/MemoryPressureHandlerMac.mm:
+        (WebCore::MemoryPressureHandler::releaseMemory):
+        * storage/StorageTask.cpp:
+        (WebCore::StorageTask::performTask):
+        * storage/StorageTask.h:
+        (WebCore::StorageTask::createReleaseFastMallocFreeMemory):
+        * storage/StorageThread.cpp:
+        (WebCore::storageThreads):
+        (WebCore):
+        (WebCore::StorageThread::StorageThread):
+        (WebCore::StorageThread::~StorageThread):
+        (WebCore::StorageThread::releaseFastMallocFreeMemoryInAllThread):
+        * storage/StorageThread.h:
+        (StorageThread):
+        * workers/WorkerThread.cpp:
+        (WebCore::threadSetMutex):
+        (WebCore::workerThreads):
+        (WebCore::WorkerThread::workerThreadCount):
+        (WebCore::WorkerThread::WorkerThread):
+        (WebCore::WorkerThread::~WorkerThread):
+        (WebCore::WorkerThread::releaseFastMallocFreeMemoryInAllThread):
+        (WebCore):
+        * workers/WorkerThread.h:
+        (WorkerThread):
+
 2013-01-09  Tony Gentilcore  <[email protected]>
 
         REGRESSION(r139141): Assertion failure in WebCore::HTMLConstructionSite::HTMLConstructionSite

Modified: trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm (139217 => 139218)


--- trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm	2013-01-09 20:08:32 UTC (rev 139218)
@@ -32,8 +32,12 @@
 #import <WebCore/MemoryCache.h>
 #import <WebCore/PageCache.h>
 #import <WebCore/LayerPool.h>
+#import <WebCore/ScrollingThread.h>
+#import <WebCore/StorageThread.h>
+#import <WebCore/WorkerThread.h>
 #import <wtf/CurrentTime.h>
 #import <wtf/FastMalloc.h>
+#import <wtf/Functional.h>
 
 #if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
 #import "WebCoreSystemInterface.h"
@@ -160,6 +164,14 @@
 
     gcController().discardAllCompiledCode();
 
+    // FastMalloc has lock-free thread specific caches that can only be cleared from the thread itself.
+    StorageThread::releaseFastMallocFreeMemoryInAllThreads();
+#if ENABLE(WORKERS)
+    WorkerThread::releaseFastMallocFreeMemoryInAllThreads();
+#endif
+#if ENABLE(THREADED_SCROLLING)
+    ScrollingThread::dispatch(bind(WTF::releaseFastMallocFreeMemory));
+#endif
     WTF::releaseFastMallocFreeMemory();
 }
 #endif

Modified: trunk/Source/WebCore/storage/StorageTask.cpp (139217 => 139218)


--- trunk/Source/WebCore/storage/StorageTask.cpp	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WebCore/storage/StorageTask.cpp	2013-01-09 20:08:32 UTC (rev 139218)
@@ -105,6 +105,9 @@
         case DeleteEmptyDatabase:
             m_area->deleteEmptyDatabase();
             break;
+        case ReleaseFastMallocFreeMemory:
+            WTF::releaseFastMallocFreeMemory();
+            break;
         case TerminateThread:
             m_thread->performTerminate();
             break;

Modified: trunk/Source/WebCore/storage/StorageTask.h (139217 => 139218)


--- trunk/Source/WebCore/storage/StorageTask.h	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WebCore/storage/StorageTask.h	2013-01-09 20:08:32 UTC (rev 139218)
@@ -38,7 +38,7 @@
     class StorageTask {
         WTF_MAKE_NONCOPYABLE(StorageTask); WTF_MAKE_FAST_ALLOCATED;
     public:
-        enum Type { AreaImport, AreaSync, DeleteEmptyDatabase, SetOriginDetails, ImportOrigins, DeleteAllOrigins, DeleteOrigin, TerminateThread };
+        enum Type { AreaImport, AreaSync, DeleteEmptyDatabase, SetOriginDetails, ImportOrigins, DeleteAllOrigins, DeleteOrigin, ReleaseFastMallocFreeMemory, TerminateThread };
 
         ~StorageTask();
 
@@ -49,6 +49,7 @@
         static PassOwnPtr<StorageTask> createSetOriginDetails(const String& originIdentifier, const String& databaseFilename) { return adoptPtr(new StorageTask(SetOriginDetails, originIdentifier, databaseFilename)); }
         static PassOwnPtr<StorageTask> createDeleteOrigin(const String& originIdentifier) { return adoptPtr(new StorageTask(DeleteOrigin, originIdentifier)); }
         static PassOwnPtr<StorageTask> createDeleteAllOrigins() { return adoptPtr(new StorageTask(DeleteAllOrigins)); }
+        static PassOwnPtr<StorageTask> createReleaseFastMallocFreeMemory() { return adoptPtr(new StorageTask(ReleaseFastMallocFreeMemory)); }
         static PassOwnPtr<StorageTask> createTerminate(StorageThread* thread) { return adoptPtr(new StorageTask(TerminateThread, thread)); }
 
         void performTask();

Modified: trunk/Source/WebCore/storage/StorageThread.cpp (139217 => 139218)


--- trunk/Source/WebCore/storage/StorageThread.cpp	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WebCore/storage/StorageThread.cpp	2013-01-09 20:08:32 UTC (rev 139218)
@@ -29,10 +29,18 @@
 #include "AutodrainedPool.h"
 #include "StorageTask.h"
 #include "StorageAreaSync.h"
+#include <wtf/HashSet.h>
 #include <wtf/MainThread.h>
 
 namespace WebCore {
 
+static HashSet<StorageThread*>& storageThreads()
+{
+    ASSERT(isMainThread());
+    DEFINE_STATIC_LOCAL(HashSet<StorageThread*>, threads, ());
+    return threads;
+}
+
 PassOwnPtr<StorageThread> StorageThread::create()
 {
     return adoptPtr(new StorageThread);
@@ -41,12 +49,15 @@
 StorageThread::StorageThread()
     : m_threadID(0)
 {
+    ASSERT(isMainThread());
+    storageThreads().add(this);
 }
 
 StorageThread::~StorageThread()
 {
     ASSERT(isMainThread());
     ASSERT(!m_threadID);
+    storageThreads().remove(this);
 }
 
 bool StorageThread::start()
@@ -100,4 +111,12 @@
     m_queue.kill();
 }
 
+void StorageThread::releaseFastMallocFreeMemoryInAllThreads()
+{
+    HashSet<StorageThread*>& threads = storageThreads();
+    HashSet<StorageThread*>::iterator end = threads.end();
+    for (HashSet<StorageThread*>::iterator it = threads.begin(); it != end; ++it)
+        (*it)->scheduleTask(StorageTask::createReleaseFastMallocFreeMemory());
 }
+
+}

Modified: trunk/Source/WebCore/storage/StorageThread.h (139217 => 139218)


--- trunk/Source/WebCore/storage/StorageThread.h	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WebCore/storage/StorageThread.h	2013-01-09 20:08:32 UTC (rev 139218)
@@ -50,6 +50,8 @@
         // Background thread part of the terminate procedure.
         void performTerminate();
 
+        static void releaseFastMallocFreeMemoryInAllThreads();
+
     private:
         StorageThread();
 

Modified: trunk/Source/WebCore/workers/WorkerThread.cpp (139217 => 139218)


--- trunk/Source/WebCore/workers/WorkerThread.cpp	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WebCore/workers/WorkerThread.cpp	2013-01-09 20:08:32 UTC (rev 139218)
@@ -53,18 +53,22 @@
 
 namespace WebCore {
 
-static Mutex& threadCountMutex()
+static Mutex& threadSetMutex()
 {
     AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
     return mutex;
 }
 
-unsigned WorkerThread::m_threadCount = 0;
+static HashSet<WorkerThread*>& workerThreads()
+{
+    DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ());
+    return threads;
+}
 
 unsigned WorkerThread::workerThreadCount()
 {
-    MutexLocker lock(threadCountMutex());
-    return m_threadCount;
+    MutexLocker lock(threadSetMutex());
+    return workerThreads().size();
 }
 
 struct WorkerThreadStartupData {
@@ -114,15 +118,15 @@
     , m_notificationClient(0)
 #endif
 {
-    MutexLocker lock(threadCountMutex());
-    m_threadCount++;
+    MutexLocker lock(threadSetMutex());
+    workerThreads().add(this);
 }
 
 WorkerThread::~WorkerThread()
 {
-    MutexLocker lock(threadCountMutex());
-    ASSERT(m_threadCount > 0);
-    m_threadCount--;
+    MutexLocker lock(threadSetMutex());
+    ASSERT(workerThreads().contains(this));
+    workerThreads().remove(this);
 }
 
 bool WorkerThread::start()
@@ -272,6 +276,19 @@
     m_runLoop.terminate();
 }
 
+class ReleaseFastMallocFreeMemoryTask : public ScriptExecutionContext::Task {
+    virtual void performTask(ScriptExecutionContext*) OVERRIDE { WTF::releaseFastMallocFreeMemory(); }
+};
+
+void WorkerThread::releaseFastMallocFreeMemoryInAllThreads()
+{
+    MutexLocker lock(threadSetMutex());
+    HashSet<WorkerThread*>& threads = workerThreads();
+    HashSet<WorkerThread*>::iterator end = threads.end();
+    for (HashSet<WorkerThread*>::iterator it = threads.begin(); it != end; ++it)
+        (*it)->runLoop().postTask(adoptPtr(new ReleaseFastMallocFreeMemoryTask));
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WORKERS)

Modified: trunk/Source/WebCore/workers/WorkerThread.h (139217 => 139218)


--- trunk/Source/WebCore/workers/WorkerThread.h	2013-01-09 20:01:46 UTC (rev 139217)
+++ trunk/Source/WebCore/workers/WorkerThread.h	2013-01-09 20:08:32 UTC (rev 139218)
@@ -63,6 +63,7 @@
 
         // Number of active worker threads.
         static unsigned workerThreadCount();
+        static void releaseFastMallocFreeMemoryInAllThreads();
 
 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
         NotificationClient* getNotificationClient() { return m_notificationClient; }
@@ -98,9 +99,6 @@
 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
         NotificationClient* m_notificationClient;
 #endif
-
-        // Track the number of WorkerThread instances for use in layout tests.
-        static unsigned m_threadCount;
     };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to