Ticket #40852: patch-src_3rdparty_webkit_Source_WebCore_platform_Timer.cpp.diff

File patch-src_3rdparty_webkit_Source_WebCore_platform_Timer.cpp.diff, 11.1 KB (added by BSeppke (Benjamin Seppke), 8 years ago)

WebKit and Mac OS X 10.9 patch

  • src/3rdparty/webkit/Source/WebCore/platform/Timer.cpp

    old new  
    4141
    4242namespace WebCore {
    4343
     44class TimerHeapReference;
     45
    4446// Timers are stored in a heap data structure, used to implement a priority queue.
    4547// This allows us to efficiently determine which timer needs to fire the soonest.
    4648// Then we set a single shared system timer to fire at that time.
     
    5355    return threadGlobalData().threadTimers().timerHeap();
    5456}
    5557
    56 // Class to represent elements in the heap when calling the standard library heap algorithms.
    57 // Maintains the m_heapIndex value in the timers themselves, which allows us to do efficient
    58 // modification of the heap.
    59 class TimerHeapElement {
    60 public:
    61     explicit TimerHeapElement(int i)
    62         : m_index(i)
    63         , m_timer(timerHeap()[m_index])
    64     {
    65         checkConsistency();
    66     }
    67 
    68     TimerHeapElement(const TimerHeapElement&);
    69     TimerHeapElement& operator=(const TimerHeapElement&);
    70 
    71     TimerBase* timer() const { return m_timer; }
    72 
    73     void checkConsistency() const
    74     {
    75         ASSERT(m_index >= 0);
    76         ASSERT(m_index < static_cast<int>(timerHeap().size()));
    77     }
     58// ----------------
    7859
     60class TimerHeapPointer {
     61public:
     62    TimerHeapPointer(TimerBase** pointer) : m_pointer(pointer) { }
     63    TimerHeapReference operator*() const;
     64    TimerBase* operator->() const { return *m_pointer; }
    7965private:
    80     TimerHeapElement();
     66    TimerBase** m_pointer;
     67};
    8168
    82     int m_index;
    83     TimerBase* m_timer;
     69class TimerHeapReference {
     70public:
     71    TimerHeapReference(TimerBase*& reference) : m_reference(reference) { }
     72    operator TimerBase*() const { return m_reference; }
     73    TimerHeapPointer operator&() const { return &m_reference; }
     74    TimerHeapReference& operator=(TimerBase*);
     75    TimerHeapReference& operator=(TimerHeapReference);
     76private:
     77    TimerBase*& m_reference;
    8478};
    8579
    86 inline TimerHeapElement::TimerHeapElement(const TimerHeapElement& o)
    87     : m_index(-1), m_timer(o.timer())
     80inline TimerHeapReference TimerHeapPointer::operator*() const
    8881{
     82    return *m_pointer;
    8983}
    9084
    91 inline TimerHeapElement& TimerHeapElement::operator=(const TimerHeapElement& o)
     85inline TimerHeapReference& TimerHeapReference::operator=(TimerBase* timer)
    9286{
    93     TimerBase* t = o.timer();
    94     m_timer = t;
    95     if (m_index != -1) {
    96         checkConsistency();
    97         timerHeap()[m_index] = t;
    98         t->m_heapIndex = m_index;
    99     }
     87    m_reference = timer;
     88    Vector<TimerBase*>& heap = timerHeap();
     89    if (&m_reference >= heap.data() && &m_reference < heap.data() + heap.size())
     90        timer->m_heapIndex = &m_reference - heap.data();
    10091    return *this;
    10192}
    10293
    103 inline bool operator<(const TimerHeapElement& a, const TimerHeapElement& b)
     94inline TimerHeapReference& TimerHeapReference::operator=(TimerHeapReference b)
    10495{
    105     // The comparisons below are "backwards" because the heap puts the largest
    106     // element first and we want the lowest time to be the first one in the heap.
    107     double aFireTime = a.timer()->m_nextFireTime;
    108     double bFireTime = b.timer()->m_nextFireTime;
    109     if (bFireTime != aFireTime)
    110         return bFireTime < aFireTime;
     96    TimerBase* timer = b;
     97    return *this = timer;
     98}
     99
     100inline void swap(TimerHeapReference a, TimerHeapReference b)
     101{
     102    TimerBase* timerA = a;
     103    TimerBase* timerB = b;
    111104   
    112     // We need to look at the difference of the insertion orders instead of comparing the two
    113     // outright in case of overflow.
    114     unsigned difference = a.timer()->m_heapInsertionOrder - b.timer()->m_heapInsertionOrder;
    115     return difference < UINT_MAX / 2;
     105    // Invoke the assignment operator, since that takes care of updating m_heapIndex.
     106    a = timerB;
     107    b = timerA;
    116108}
    117109
    118110// ----------------
    119111
    120112// Class to represent iterators in the heap when calling the standard library heap algorithms.
    121 // Returns TimerHeapElement for elements in the heap rather than the TimerBase pointers themselves.
    122 class TimerHeapIterator : public iterator<random_access_iterator_tag, TimerHeapElement, int> {
     113// Uses a custom pointer and reference type that update indices for pointers in the heap.
     114class TimerHeapIterator : public iterator<random_access_iterator_tag, TimerBase*, ptrdiff_t, TimerHeapPointer, TimerHeapReference> {
    123115public:
    124     TimerHeapIterator() : m_index(-1) { }
    125     TimerHeapIterator(int i) : m_index(i) { checkConsistency(); }
    126 
    127     TimerHeapIterator& operator++() { checkConsistency(); ++m_index; checkConsistency(); return *this; }
    128     TimerHeapIterator operator++(int) { checkConsistency(); checkConsistency(1); return m_index++; }
    129 
    130     TimerHeapIterator& operator--() { checkConsistency(); --m_index; checkConsistency(); return *this; }
    131     TimerHeapIterator operator--(int) { checkConsistency(); checkConsistency(-1); return m_index--; }
     116    explicit TimerHeapIterator(TimerBase** pointer) : m_pointer(pointer) { checkConsistency(); }
     117   
     118    TimerHeapIterator& operator++() { checkConsistency(); ++m_pointer; checkConsistency(); return *this; }
     119    TimerHeapIterator operator++(int) { checkConsistency(1); return TimerHeapIterator(m_pointer++); }
     120   
     121    TimerHeapIterator& operator--() { checkConsistency(); --m_pointer; checkConsistency(); return *this; }
     122    TimerHeapIterator operator--(int) { checkConsistency(-1); return TimerHeapIterator(m_pointer--); }
     123   
     124    TimerHeapIterator& operator+=(ptrdiff_t i) { checkConsistency(); m_pointer += i; checkConsistency(); return *this; }
     125    TimerHeapIterator& operator-=(ptrdiff_t i) { checkConsistency(); m_pointer -= i; checkConsistency(); return *this; }
     126   
     127    TimerHeapReference operator*() const { return TimerHeapReference(*m_pointer); }
     128    TimerHeapReference operator[](ptrdiff_t i) const { return TimerHeapReference(m_pointer[i]); }
     129    TimerBase* operator->() const { return *m_pointer; }
     130   
     131private:
     132    void checkConsistency(ptrdiff_t offset = 0) const
     133    {
     134        ASSERT(m_pointer >= timerHeap().data());
     135        ASSERT(m_pointer <= timerHeap().data() + timerHeap().size());
     136        ASSERT_UNUSED(offset, m_pointer + offset >= timerHeap().data());
     137        ASSERT_UNUSED(offset, m_pointer + offset <= timerHeap().data() + timerHeap().size());
     138    }
     139   
     140    friend bool operator==(TimerHeapIterator, TimerHeapIterator);
     141    friend bool operator!=(TimerHeapIterator, TimerHeapIterator);
     142    friend bool operator<(TimerHeapIterator, TimerHeapIterator);
     143    friend bool operator>(TimerHeapIterator, TimerHeapIterator);
     144    friend bool operator<=(TimerHeapIterator, TimerHeapIterator);
     145    friend bool operator>=(TimerHeapIterator, TimerHeapIterator);
     146   
     147    friend TimerHeapIterator operator+(TimerHeapIterator, size_t);
     148    friend TimerHeapIterator operator+(size_t, TimerHeapIterator);
     149   
     150    friend TimerHeapIterator operator-(TimerHeapIterator, size_t);
     151    friend ptrdiff_t operator-(TimerHeapIterator, TimerHeapIterator);
     152   
     153    TimerBase** m_pointer;
     154};
    132155
    133     TimerHeapIterator& operator+=(int i) { checkConsistency(); m_index += i; checkConsistency(); return *this; }
    134     TimerHeapIterator& operator-=(int i) { checkConsistency(); m_index -= i; checkConsistency(); return *this; }
     156inline bool operator==(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer == b.m_pointer; }
     157inline bool operator!=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer != b.m_pointer; }
     158inline bool operator<(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer < b.m_pointer; }
     159inline bool operator>(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer > b.m_pointer; }
     160inline bool operator<=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer <= b.m_pointer; }
     161inline bool operator>=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer >= b.m_pointer; }
    135162
    136     TimerHeapElement operator*() const { return TimerHeapElement(m_index); }
    137     TimerHeapElement operator[](int i) const { return TimerHeapElement(m_index + i); }
     163inline TimerHeapIterator operator+(TimerHeapIterator a, size_t b) { return TimerHeapIterator(a.m_pointer + b); }
     164inline TimerHeapIterator operator+(size_t a, TimerHeapIterator b) { return TimerHeapIterator(a + b.m_pointer); }
    138165
    139     int index() const { return m_index; }
     166inline TimerHeapIterator operator-(TimerHeapIterator a, size_t b) { return TimerHeapIterator(a.m_pointer - b); }
     167inline ptrdiff_t operator-(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer - b.m_pointer; }
    140168
    141     void checkConsistency(int offset = 0) const
    142     {
    143         ASSERT_UNUSED(offset, m_index + offset >= 0);
    144         ASSERT_UNUSED(offset, m_index + offset <= static_cast<int>(timerHeap().size()));
    145     }
     169// ----------------
    146170
    147 private:
    148     int m_index;
     171class TimerHeapLessThanFunction {
     172public:
     173    bool operator()(TimerBase*, TimerBase*) const;
    149174};
    150175
    151 inline bool operator==(TimerHeapIterator a, TimerHeapIterator b) { return a.index() == b.index(); }
    152 inline bool operator!=(TimerHeapIterator a, TimerHeapIterator b) { return a.index() != b.index(); }
    153 inline bool operator<(TimerHeapIterator a, TimerHeapIterator b) { return a.index() < b.index(); }
    154 
    155 inline TimerHeapIterator operator+(TimerHeapIterator a, int b) { return a.index() + b; }
    156 inline TimerHeapIterator operator+(int a, TimerHeapIterator b) { return a + b.index(); }
    157 
    158 inline TimerHeapIterator operator-(TimerHeapIterator a, int b) { return a.index() - b; }
    159 inline int operator-(TimerHeapIterator a, TimerHeapIterator b) { return a.index() - b.index(); }
     176inline bool TimerHeapLessThanFunction::operator()(TimerBase* a, TimerBase* b) const
     177{
     178    // The comparisons below are "backwards" because the heap puts the largest
     179    // element first and we want the lowest time to be the first one in the heap.
     180    double aFireTime = a->m_nextFireTime;
     181    double bFireTime = b->m_nextFireTime;
     182    if (bFireTime != aFireTime)
     183        return bFireTime < aFireTime;
     184   
     185    // We need to look at the difference of the insertion orders instead of comparing the two
     186    // outright in case of overflow.
     187    unsigned difference = a->m_heapInsertionOrder - b->m_heapInsertionOrder;
     188    return difference < numeric_limits<unsigned>::max() / 2;
     189}
    160190
    161191// ----------------
    162192
    163193TimerBase::TimerBase()
    164     : m_nextFireTime(0)
    165     , m_repeatInterval(0)
    166     , m_heapIndex(-1)
     194: m_nextFireTime(0)
     195, m_repeatInterval(0)
     196, m_heapIndex(-1)
    167197#ifndef NDEBUG
    168     , m_thread(currentThread())
     198, m_thread(currentThread())
    169199#endif
    170200{
    171201}
     
    225255{
    226256    ASSERT(m_nextFireTime != 0);
    227257    checkHeapIndex();
    228     push_heap(TimerHeapIterator(0), TimerHeapIterator(m_heapIndex + 1));
     258    TimerBase** heapData = timerHeap().data();
     259    push_heap(TimerHeapIterator(heapData), TimerHeapIterator(heapData + m_heapIndex + 1), TimerHeapLessThanFunction());
    229260    checkHeapIndex();
    230261}
    231262
     
    274305{
    275306    ASSERT(this == timerHeap().first());
    276307    checkHeapIndex();
    277     pop_heap(TimerHeapIterator(0), TimerHeapIterator(timerHeap().size()));
     308    Vector<TimerBase*>& heap = timerHeap();
     309    TimerBase** heapData = heap.data();
     310    pop_heap(TimerHeapIterator(heapData), TimerHeapIterator(heapData + heap.size()), TimerHeapLessThanFunction());
    278311    checkHeapIndex();
    279312    ASSERT(this == timerHeap().last());
    280313}