2011-01-14 Patrick Gansterer <paroga@webkit.org>
authorparoga@webkit.org <paroga@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Jan 2011 22:21:58 +0000 (22:21 +0000)
committerparoga@webkit.org <paroga@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Jan 2011 22:21:58 +0000 (22:21 +0000)
        Reviewed by Adam Roben.

        Use the Windows thread pool instead of an extra thread for FastMalloc scavenging
        https://bugs.webkit.org/show_bug.cgi?id=45186

        Use CreateTimerQueueTimer() to start periodicScavenge() and stop it with DeleteTimerQueueTimer().

        * wtf/FastMalloc.cpp:
        (WTF::TCMalloc_PageHeap::initializeScavenger):
        (WTF::TCMalloc_PageHeap::isScavengerSuspended):
        (WTF::TCMalloc_PageHeap::scheduleScavenger):
        (WTF::TCMalloc_PageHeap::rescheduleScavenger):
        (WTF::TCMalloc_PageHeap::suspendScavenger):
        (WTF::scavengerTimerFired):
        (WTF::TCMalloc_PageHeap::periodicScavenge):
        (WTF::TCMalloc_PageHeap::signalScavenger):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/wtf/FastMalloc.cpp

index 539ae8f..8737c3d 100644 (file)
@@ -1,3 +1,22 @@
+2011-01-14  Patrick Gansterer  <paroga@webkit.org>
+
+        Reviewed by Adam Roben.
+
+        Use the Windows thread pool instead of an extra thread for FastMalloc scavenging
+        https://bugs.webkit.org/show_bug.cgi?id=45186
+
+        Use CreateTimerQueueTimer() to start periodicScavenge() and stop it with DeleteTimerQueueTimer().
+
+        * wtf/FastMalloc.cpp:
+        (WTF::TCMalloc_PageHeap::initializeScavenger):
+        (WTF::TCMalloc_PageHeap::isScavengerSuspended):
+        (WTF::TCMalloc_PageHeap::scheduleScavenger):
+        (WTF::TCMalloc_PageHeap::rescheduleScavenger):
+        (WTF::TCMalloc_PageHeap::suspendScavenger):
+        (WTF::scavengerTimerFired):
+        (WTF::TCMalloc_PageHeap::periodicScavenge):
+        (WTF::TCMalloc_PageHeap::signalScavenger):
+
 2011-01-14  Laszlo Gombos  <laszlo.1.gombos@nokia.com>
 
         Reviewed by Kenneth Rohde Christiansen.
index 42b2812..fdee480 100644 (file)
@@ -1446,7 +1446,21 @@ class TCMalloc_PageHeap {
   void scavenge();
   ALWAYS_INLINE bool shouldScavenge() const;
 
-#if !HAVE(DISPATCH_H)
+#if HAVE(DISPATCH_H) || OS(WINDOWS)
+  void periodicScavenge();
+  ALWAYS_INLINE bool isScavengerSuspended();
+  ALWAYS_INLINE void scheduleScavenger();
+  ALWAYS_INLINE void rescheduleScavenger();
+  ALWAYS_INLINE void suspendScavenger();
+#endif
+
+#if HAVE(DISPATCH_H)
+  dispatch_queue_t m_scavengeQueue;
+  dispatch_source_t m_scavengeTimer;
+  bool m_scavengingSuspended;
+#elif OS(WINDOWS)
+  HANDLE m_scavengeQueueTimer;
+#else 
   static NO_RETURN_WITH_VALUE void* runScavengerThread(void*);
   NO_RETURN void scavengerThread();
 
@@ -1456,12 +1470,6 @@ class TCMalloc_PageHeap {
 
   pthread_mutex_t m_scavengeMutex;
   pthread_cond_t m_scavengeCondition;
-#else // !HAVE(DISPATCH_H)
-  void periodicScavenge();
-
-  dispatch_queue_t m_scavengeQueue;
-  dispatch_source_t m_scavengeTimer;
-  bool m_scavengingScheduled;
 #endif
 
 #endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
@@ -1497,7 +1505,85 @@ void TCMalloc_PageHeap::init()
 
 #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
 
-#if !HAVE(DISPATCH_H)
+#if HAVE(DISPATCH_H)
+
+void TCMalloc_PageHeap::initializeScavenger()
+{
+    m_scavengeQueue = dispatch_queue_create("com.apple.JavaScriptCore.FastMallocSavenger", NULL);
+    m_scavengeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_scavengeQueue);
+    dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, kScavengeDelayInSeconds * NSEC_PER_SEC);
+    dispatch_source_set_timer(m_scavengeTimer, startTime, kScavengeDelayInSeconds * NSEC_PER_SEC, 1000 * NSEC_PER_USEC);
+    dispatch_source_set_event_handler(m_scavengeTimer, ^{ periodicScavenge(); });
+    m_scavengingSuspended = false;
+}
+
+ALWAYS_INLINE bool TCMalloc_PageHeap::isScavengerSuspended()
+{
+    ASSERT(IsHeld(pageheap_lock));
+    return m_scavengingSuspended;
+}
+
+ALWAYS_INLINE void TCMalloc_PageHeap::scheduleScavenger()
+{
+    ASSERT(IsHeld(pageheap_lock));
+    m_scavengingSuspended = false;
+    dispatch_resume(m_scavengeTimer);
+}
+
+ALWAYS_INLINE void TCMalloc_PageHeap::rescheduleScavenger()
+{
+    // Nothing to do here for libdispatch.
+}
+
+ALWAYS_INLINE void TCMalloc_PageHeap::suspendScavenger()
+{
+    ASSERT(IsHeld(pageheap_lock));
+    m_scavengingSuspended = true;
+    dispatch_suspend(m_scavengeTimer);
+}
+
+#elif OS(WINDOWS)
+
+static void CALLBACK scavengerTimerFired(void* context, BOOLEAN)
+{
+    static_cast<TCMalloc_PageHeap*>(context)->periodicScavenge();
+}
+
+void TCMalloc_PageHeap::initializeScavenger()
+{
+    m_scavengeQueueTimer = 0;
+}
+
+ALWAYS_INLINE bool TCMalloc_PageHeap::isScavengerSuspended()
+{
+    ASSERT(IsHeld(pageheap_lock));
+    return !m_scavengeQueueTimer;
+}
+
+ALWAYS_INLINE void TCMalloc_PageHeap::scheduleScavenger()
+{
+    // We need to use WT_EXECUTEONLYONCE here and reschedule the timer, because
+    // Windows will fire the timer event even when the function is already running.
+    ASSERT(IsHeld(pageheap_lock));
+    CreateTimerQueueTimer(&m_scavengeQueueTimer, 0, scavengerTimerFired, 0, kScavengeDelayInSeconds * 1000, 0, WT_EXECUTEONLYONCE);
+}
+
+ALWAYS_INLINE void TCMalloc_PageHeap::rescheduleScavenger()
+{
+    // We must delete the timer and create it again, because it is not possible to retrigger a timer on Windows.
+    suspendScavenger();
+    scheduleScavenger();
+}
+
+ALWAYS_INLINE void TCMalloc_PageHeap::suspendScavenger()
+{
+    ASSERT(IsHeld(pageheap_lock));
+    HANDLE scavengeQueueTimer = m_scavengeQueueTimer;
+    m_scavengeQueueTimer = 0;
+    DeleteTimerQueueTimer(0, scavengeQueueTimer, 0);
+}
+
+#else
 
 void TCMalloc_PageHeap::initializeScavenger()
 {
@@ -1537,27 +1623,6 @@ ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
         pthread_cond_signal(&m_scavengeCondition);
 }
 
-#else // !HAVE(DISPATCH_H)
-
-void TCMalloc_PageHeap::initializeScavenger()
-{
-  m_scavengeQueue = dispatch_queue_create("com.apple.JavaScriptCore.FastMallocSavenger", NULL);
-  m_scavengeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_scavengeQueue);
-  dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, kScavengeDelayInSeconds * NSEC_PER_SEC);
-  dispatch_source_set_timer(m_scavengeTimer, startTime, kScavengeDelayInSeconds * NSEC_PER_SEC, 1000 * NSEC_PER_USEC);
-  dispatch_source_set_event_handler(m_scavengeTimer, ^{ periodicScavenge(); });
-  m_scavengingScheduled = false;
-}
-
-ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
-{
-    ASSERT(IsHeld(pageheap_lock));
-    if (!m_scavengingScheduled && shouldScavenge()) {
-        m_scavengingScheduled = true;
-        dispatch_resume(m_scavengeTimer);
-    }
-}
-
 #endif
 
 void TCMalloc_PageHeap::scavenge()
@@ -2386,13 +2451,29 @@ static inline TCMalloc_PageHeap* getPageHeap()
 
 #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
 
-#if !HAVE(DISPATCH_H)
-#if OS(WINDOWS)
-static void sleep(unsigned seconds)
+#if HAVE(DISPATCH_H) || OS(WINDOWS)
+
+void TCMalloc_PageHeap::periodicScavenge()
 {
-    ::Sleep(seconds * 1000);
+    SpinLockHolder h(&pageheap_lock);
+    pageheap->scavenge();
+
+    if (shouldScavenge()) {
+        rescheduleScavenger();
+        return;
+    }
+
+    suspendScavenger();
 }
-#endif
+
+ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
+{
+    ASSERT(IsHeld(pageheap_lock));
+    if (isScavengerSuspended() && shouldScavenge())
+        scheduleScavenger();
+}
+
+#else
 
 void TCMalloc_PageHeap::scavengerThread()
 {
@@ -2417,19 +2498,7 @@ void TCMalloc_PageHeap::scavengerThread()
   }
 }
 
-#else
-
-void TCMalloc_PageHeap::periodicScavenge()
-{
-    SpinLockHolder h(&pageheap_lock);
-    pageheap->scavenge();
-
-    if (!shouldScavenge()) {
-        m_scavengingScheduled = false;
-        dispatch_suspend(m_scavengeTimer);
-    }
-}
-#endif // HAVE(DISPATCH_H)
+#endif
 
 #endif