Changeset 139218 in webkit


Ignore:
Timestamp:
Jan 9, 2013 12:08:32 PM (11 years ago)
Author:
Antti Koivisto
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):

Location:
trunk/Source
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def

    r138636 r139218  
    209209    ?fastMallocSize@WTF@@YAIPBX@Z
    210210    ?fastMallocStatistics@WTF@@YA?AUFastMallocStatistics@1@XZ
     211    ?releaseFastMallocFreeMemory@WTF@@YAXXZ
    211212    ?fastRealloc@WTF@@YAPAXPAXI@Z
    212213    ?fastStrDup@WTF@@YAPADPBD@Z
  • trunk/Source/WTF/ChangeLog

    r139184 r139218  
     12013-01-09  Antti Koivisto  <antti@apple.com>
     2
     3        Release FastMalloc thread caches on memory warning
     4        https://bugs.webkit.org/show_bug.cgi?id=106471
     5       
     6        Reviewed by Geoff Garen.
     7
     8        Use TCMalloc_ThreadCache::Cleanup() instead of calling Scavenge() twice. This releases all the memory
     9        and looks nicer too.
     10
     11        * wtf/FastMalloc.cpp:
     12        (WTF::releaseFastMallocFreeMemory):
     13
    1142013-01-09  Carlos Garcia Campos  <cgarcia@igalia.com>
    215
  • trunk/Source/WTF/wtf/FastMalloc.cpp

    r139004 r139218  
    43834383{
    43844384    // Flush free pages in the current thread cache back to the page heap.
    4385     // Low watermark mechanism in Scavenge() prevents full return on the first pass.
    4386     // The second pass flushes everything.
    4387     if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent()) {
    4388         threadCache->Scavenge();
    4389         threadCache->Scavenge();
    4390     }
     4385    if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent())
     4386        threadCache->Cleanup();
    43914387
    43924388    SpinLockHolder h(&pageheap_lock);
    43934389    pageheap->ReleaseFreePages();
    43944390}
    4395    
     4391
    43964392FastMallocStatistics fastMallocStatistics()
    43974393{
  • trunk/Source/WebCore/ChangeLog

    r139217 r139218  
     12013-01-09  Antti Koivisto  <antti@apple.com>
     2
     3        Release FastMalloc thread caches on memory warning
     4        https://bugs.webkit.org/show_bug.cgi?id=106471
     5
     6        Reviewed by Geoff Garen.
     7       
     8        FastMalloc keeps some memory in per-thread caches (currently 2MB each). We currently flush these caches on memory warning
     9        for the main thread only. We should do it for other WebKit threads that use FastMalloc too.
     10
     11        Call WTF::releaseFastMallocFreeMemory in a bunch of WebCore support threads on memory warning. Unfortunately we don't have
     12        an uniform way of doing threads so this requires bunch of thread type specific code.
     13       
     14        Looks to be ~1% progression in membuster3 final and maximum numbers.
     15
     16        * platform/mac/MemoryPressureHandlerMac.mm:
     17        (WebCore::MemoryPressureHandler::releaseMemory):
     18        * storage/StorageTask.cpp:
     19        (WebCore::StorageTask::performTask):
     20        * storage/StorageTask.h:
     21        (WebCore::StorageTask::createReleaseFastMallocFreeMemory):
     22        * storage/StorageThread.cpp:
     23        (WebCore::storageThreads):
     24        (WebCore):
     25        (WebCore::StorageThread::StorageThread):
     26        (WebCore::StorageThread::~StorageThread):
     27        (WebCore::StorageThread::releaseFastMallocFreeMemoryInAllThread):
     28        * storage/StorageThread.h:
     29        (StorageThread):
     30        * workers/WorkerThread.cpp:
     31        (WebCore::threadSetMutex):
     32        (WebCore::workerThreads):
     33        (WebCore::WorkerThread::workerThreadCount):
     34        (WebCore::WorkerThread::WorkerThread):
     35        (WebCore::WorkerThread::~WorkerThread):
     36        (WebCore::WorkerThread::releaseFastMallocFreeMemoryInAllThread):
     37        (WebCore):
     38        * workers/WorkerThread.h:
     39        (WorkerThread):
     40
    1412013-01-09  Tony Gentilcore  <tonyg@chromium.org>
    242
  • trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm

    r138482 r139218  
    3333#import <WebCore/PageCache.h>
    3434#import <WebCore/LayerPool.h>
     35#import <WebCore/ScrollingThread.h>
     36#import <WebCore/StorageThread.h>
     37#import <WebCore/WorkerThread.h>
    3538#import <wtf/CurrentTime.h>
    3639#import <wtf/FastMalloc.h>
     40#import <wtf/Functional.h>
    3741
    3842#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
     
    161165    gcController().discardAllCompiledCode();
    162166
     167    // FastMalloc has lock-free thread specific caches that can only be cleared from the thread itself.
     168    StorageThread::releaseFastMallocFreeMemoryInAllThreads();
     169#if ENABLE(WORKERS)
     170    WorkerThread::releaseFastMallocFreeMemoryInAllThreads();
     171#endif
     172#if ENABLE(THREADED_SCROLLING)
     173    ScrollingThread::dispatch(bind(WTF::releaseFastMallocFreeMemory));
     174#endif
    163175    WTF::releaseFastMallocFreeMemory();
    164176}
  • trunk/Source/WebCore/storage/StorageTask.cpp

    r112343 r139218  
    106106            m_area->deleteEmptyDatabase();
    107107            break;
     108        case ReleaseFastMallocFreeMemory:
     109            WTF::releaseFastMallocFreeMemory();
     110            break;
    108111        case TerminateThread:
    109112            m_thread->performTerminate();
  • trunk/Source/WebCore/storage/StorageTask.h

    r127757 r139218  
    3939        WTF_MAKE_NONCOPYABLE(StorageTask); WTF_MAKE_FAST_ALLOCATED;
    4040    public:
    41         enum Type { AreaImport, AreaSync, DeleteEmptyDatabase, SetOriginDetails, ImportOrigins, DeleteAllOrigins, DeleteOrigin, TerminateThread };
     41        enum Type { AreaImport, AreaSync, DeleteEmptyDatabase, SetOriginDetails, ImportOrigins, DeleteAllOrigins, DeleteOrigin, ReleaseFastMallocFreeMemory, TerminateThread };
    4242
    4343        ~StorageTask();
     
    5050        static PassOwnPtr<StorageTask> createDeleteOrigin(const String& originIdentifier) { return adoptPtr(new StorageTask(DeleteOrigin, originIdentifier)); }
    5151        static PassOwnPtr<StorageTask> createDeleteAllOrigins() { return adoptPtr(new StorageTask(DeleteAllOrigins)); }
     52        static PassOwnPtr<StorageTask> createReleaseFastMallocFreeMemory() { return adoptPtr(new StorageTask(ReleaseFastMallocFreeMemory)); }
    5253        static PassOwnPtr<StorageTask> createTerminate(StorageThread* thread) { return adoptPtr(new StorageTask(TerminateThread, thread)); }
    5354
  • trunk/Source/WebCore/storage/StorageThread.cpp

    r114656 r139218  
    3030#include "StorageTask.h"
    3131#include "StorageAreaSync.h"
     32#include <wtf/HashSet.h>
    3233#include <wtf/MainThread.h>
    3334
    3435namespace WebCore {
     36
     37static HashSet<StorageThread*>& storageThreads()
     38{
     39    ASSERT(isMainThread());
     40    DEFINE_STATIC_LOCAL(HashSet<StorageThread*>, threads, ());
     41    return threads;
     42}
    3543
    3644PassOwnPtr<StorageThread> StorageThread::create()
     
    4250    : m_threadID(0)
    4351{
     52    ASSERT(isMainThread());
     53    storageThreads().add(this);
    4454}
    4555
     
    4858    ASSERT(isMainThread());
    4959    ASSERT(!m_threadID);
     60    storageThreads().remove(this);
    5061}
    5162
     
    101112}
    102113
     114void StorageThread::releaseFastMallocFreeMemoryInAllThreads()
     115{
     116    HashSet<StorageThread*>& threads = storageThreads();
     117    HashSet<StorageThread*>::iterator end = threads.end();
     118    for (HashSet<StorageThread*>::iterator it = threads.begin(); it != end; ++it)
     119        (*it)->scheduleTask(StorageTask::createReleaseFastMallocFreeMemory());
    103120}
     121
     122}
  • trunk/Source/WebCore/storage/StorageThread.h

    r108746 r139218  
    5151        void performTerminate();
    5252
     53        static void releaseFastMallocFreeMemoryInAllThreads();
     54
    5355    private:
    5456        StorageThread();
  • trunk/Source/WebCore/workers/WorkerThread.cpp

    r137520 r139218  
    5454namespace WebCore {
    5555
    56 static Mutex& threadCountMutex()
     56static Mutex& threadSetMutex()
    5757{
    5858    AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
     
    6060}
    6161
    62 unsigned WorkerThread::m_threadCount = 0;
     62static HashSet<WorkerThread*>& workerThreads()
     63{
     64    DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ());
     65    return threads;
     66}
    6367
    6468unsigned WorkerThread::workerThreadCount()
    6569{
    66     MutexLocker lock(threadCountMutex());
    67     return m_threadCount;
     70    MutexLocker lock(threadSetMutex());
     71    return workerThreads().size();
    6872}
    6973
     
    115119#endif
    116120{
    117     MutexLocker lock(threadCountMutex());
    118     m_threadCount++;
     121    MutexLocker lock(threadSetMutex());
     122    workerThreads().add(this);
    119123}
    120124
    121125WorkerThread::~WorkerThread()
    122126{
    123     MutexLocker lock(threadCountMutex());
    124     ASSERT(m_threadCount > 0);
    125     m_threadCount--;
     127    MutexLocker lock(threadSetMutex());
     128    ASSERT(workerThreads().contains(this));
     129    workerThreads().remove(this);
    126130}
    127131
     
    273277}
    274278
     279class ReleaseFastMallocFreeMemoryTask : public ScriptExecutionContext::Task {
     280    virtual void performTask(ScriptExecutionContext*) OVERRIDE { WTF::releaseFastMallocFreeMemory(); }
     281};
     282
     283void WorkerThread::releaseFastMallocFreeMemoryInAllThreads()
     284{
     285    MutexLocker lock(threadSetMutex());
     286    HashSet<WorkerThread*>& threads = workerThreads();
     287    HashSet<WorkerThread*>::iterator end = threads.end();
     288    for (HashSet<WorkerThread*>::iterator it = threads.begin(); it != end; ++it)
     289        (*it)->runLoop().postTask(adoptPtr(new ReleaseFastMallocFreeMemoryTask));
     290}
     291
    275292} // namespace WebCore
    276293
  • trunk/Source/WebCore/workers/WorkerThread.h

    r126365 r139218  
    6464        // Number of active worker threads.
    6565        static unsigned workerThreadCount();
     66        static void releaseFastMallocFreeMemoryInAllThreads();
    6667
    6768#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
     
    99100        NotificationClient* m_notificationClient;
    100101#endif
    101 
    102         // Track the number of WorkerThread instances for use in layout tests.
    103         static unsigned m_threadCount;
    104102    };
    105103
Note: See TracChangeset for help on using the changeset viewer.