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