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