Title: [142652] trunk/Source/WebCore
Revision
142652
Author
[email protected]
Date
2013-02-12 12:14:06 -0800 (Tue, 12 Feb 2013)

Log Message

Cache timer heap pointer to timers
https://bugs.webkit.org/show_bug.cgi?id=109597

Reviewed by Andreas Kling.

Accessing timer heap through thread global storage is slow (~0.1% in PLT3). We can cache the heap pointer to
each TimerBase. There are not huge numbers of timers around so memory is not an issue and many timers are heavily reused.

* platform/Timer.cpp:
(WebCore::threadGlobalTimerHeap):
(WebCore::TimerHeapReference::operator=):
(WebCore::TimerHeapIterator::checkConsistency):
(WebCore::TimerBase::TimerBase):
(WebCore::TimerBase::checkHeapIndex):
(WebCore::TimerBase::setNextFireTime):
* platform/Timer.h:
(WebCore::TimerBase::timerHeap):
(TimerBase):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (142651 => 142652)


--- trunk/Source/WebCore/ChangeLog	2013-02-12 20:12:53 UTC (rev 142651)
+++ trunk/Source/WebCore/ChangeLog	2013-02-12 20:14:06 UTC (rev 142652)
@@ -1,3 +1,24 @@
+2013-02-12  Antti Koivisto  <[email protected]>
+
+        Cache timer heap pointer to timers
+        https://bugs.webkit.org/show_bug.cgi?id=109597
+
+        Reviewed by Andreas Kling.
+
+        Accessing timer heap through thread global storage is slow (~0.1% in PLT3). We can cache the heap pointer to
+        each TimerBase. There are not huge numbers of timers around so memory is not an issue and many timers are heavily reused.
+
+        * platform/Timer.cpp:
+        (WebCore::threadGlobalTimerHeap):
+        (WebCore::TimerHeapReference::operator=):
+        (WebCore::TimerHeapIterator::checkConsistency):
+        (WebCore::TimerBase::TimerBase):
+        (WebCore::TimerBase::checkHeapIndex):
+        (WebCore::TimerBase::setNextFireTime):
+        * platform/Timer.h:
+        (WebCore::TimerBase::timerHeap):
+        (TimerBase):
+
 2013-02-12  Adam Barth  <[email protected]>
 
         BackgroundHTMLParser::resumeFrom should take a struct

Modified: trunk/Source/WebCore/platform/Timer.cpp (142651 => 142652)


--- trunk/Source/WebCore/platform/Timer.cpp	2013-02-12 20:12:53 UTC (rev 142651)
+++ trunk/Source/WebCore/platform/Timer.cpp	2013-02-12 20:14:06 UTC (rev 142652)
@@ -48,13 +48,10 @@
 // Then we set a single shared system timer to fire at that time.
 //
 // When a timer's "next fire time" changes, we need to move it around in the priority queue.
-
-// Simple accessors to thread-specific data.
-static Vector<TimerBase*>& timerHeap()
+static Vector<TimerBase*>& threadGlobalTimerHeap()
 {
     return threadGlobalData().threadTimers().timerHeap();
 }
-
 // ----------------
 
 class TimerHeapPointer {
@@ -85,7 +82,7 @@
 inline TimerHeapReference& TimerHeapReference::operator=(TimerBase* timer)
 {
     m_reference = timer;
-    Vector<TimerBase*>& heap = timerHeap();
+    Vector<TimerBase*>& heap = timer->timerHeap();
     if (&m_reference >= heap.data() && &m_reference < heap.data() + heap.size())
         timer->m_heapIndex = &m_reference - heap.data();
     return *this;
@@ -131,10 +128,10 @@
 private:
     void checkConsistency(ptrdiff_t offset = 0) const
     {
-        ASSERT(m_pointer >= timerHeap().data());
-        ASSERT(m_pointer <= timerHeap().data() + timerHeap().size());
-        ASSERT_UNUSED(offset, m_pointer + offset >= timerHeap().data());
-        ASSERT_UNUSED(offset, m_pointer + offset <= timerHeap().data() + timerHeap().size());
+        ASSERT(m_pointer >= threadGlobalTimerHeap().data());
+        ASSERT(m_pointer <= threadGlobalTimerHeap().data() + threadGlobalTimerHeap().size());
+        ASSERT_UNUSED(offset, m_pointer + offset >= threadGlobalTimerHeap().data());
+        ASSERT_UNUSED(offset, m_pointer + offset <= threadGlobalTimerHeap().data() + threadGlobalTimerHeap().size());
     }
 
     friend bool operator==(TimerHeapIterator, TimerHeapIterator);
@@ -195,6 +192,7 @@
     , m_unalignedNextFireTime(0)
     , m_repeatInterval(0)
     , m_heapIndex(-1)
+    , m_cachedThreadGlobalTimerHeap(0)
 #ifndef NDEBUG
     , m_thread(currentThread())
 #endif
@@ -238,6 +236,7 @@
 
 inline void TimerBase::checkHeapIndex() const
 {
+    ASSERT(timerHeap() == threadGlobalTimerHeap());
     ASSERT(!timerHeap().isEmpty());
     ASSERT(m_heapIndex >= 0);
     ASSERT(m_heapIndex < static_cast<int>(timerHeap().size()));
@@ -320,6 +319,10 @@
     if (m_unalignedNextFireTime != newUnalignedTime)
         m_unalignedNextFireTime = newUnalignedTime;
 
+    // Accessing thread global data is slow. Cache the heap pointer.
+    if (!m_cachedThreadGlobalTimerHeap)
+        m_cachedThreadGlobalTimerHeap = &threadGlobalTimerHeap();
+
     // Keep heap valid while changing the next-fire time.
     double oldTime = m_nextFireTime;
     double newTime = alignedFireTime(newUnalignedTime);

Modified: trunk/Source/WebCore/platform/Timer.h (142651 => 142652)


--- trunk/Source/WebCore/platform/Timer.h	2013-02-12 20:12:53 UTC (rev 142651)
+++ trunk/Source/WebCore/platform/Timer.h	2013-02-12 20:14:06 UTC (rev 142652)
@@ -28,6 +28,7 @@
 
 #include <wtf/Noncopyable.h>
 #include <wtf/Threading.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
@@ -80,11 +81,15 @@
     void heapPop();
     void heapPopMin();
 
+    const Vector<TimerBase*>& timerHeap() const { ASSERT(m_cachedThreadGlobalTimerHeap); return *m_cachedThreadGlobalTimerHeap; }
+    Vector<TimerBase*>& timerHeap() { ASSERT(m_cachedThreadGlobalTimerHeap); return *m_cachedThreadGlobalTimerHeap; }
+
     double m_nextFireTime; // 0 if inactive
     double m_unalignedNextFireTime; // m_nextFireTime not considering alignment interval
     double m_repeatInterval; // 0 if not repeating
     int m_heapIndex; // -1 if not in heap
     unsigned m_heapInsertionOrder; // Used to keep order among equal-fire-time timers
+    Vector<TimerBase*>* m_cachedThreadGlobalTimerHeap;
 
 #ifndef NDEBUG
     ThreadIdentifier m_thread;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to