summaryrefslogtreecommitdiff
path: root/debian/patches/pkgsrc/patch-src_3rdparty_webkit_Source_WebCore_platform_Timer.cpp
blob: dd9da09ee941730f9dcb8776f74f41f5a9d6c6ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
$NetBSD: patch-src_3rdparty_webkit_Source_WebCore_platform_Timer.cpp,v 1.1 2013/05/09 14:07:08 joerg Exp $

Upstream changeset 92556

--- a/src/3rdparty/webkit/Source/WebCore/platform/Timer.cpp.orig	2012-11-23 10:09:58.000000000 +0000
+++ b/src/3rdparty/webkit/Source/WebCore/platform/Timer.cpp
@@ -41,6 +41,8 @@ using namespace std;
 
 namespace WebCore {
 
+class TimerHeapReference;
+
 // Timers are stored in a heap data structure, used to implement a priority queue.
 // This allows us to efficiently determine which timer needs to fire the soonest.
 // Then we set a single shared system timer to fire at that time.
@@ -53,110 +55,138 @@ static Vector<TimerBase*>& timerHeap()
     return threadGlobalData().threadTimers().timerHeap();
 }
 
-// Class to represent elements in the heap when calling the standard library heap algorithms.
-// Maintains the m_heapIndex value in the timers themselves, which allows us to do efficient
-// modification of the heap.
-class TimerHeapElement {
-public:
-    explicit TimerHeapElement(int i)
-        : m_index(i)
-        , m_timer(timerHeap()[m_index])
-    { 
-        checkConsistency(); 
-    }
-
-    TimerHeapElement(const TimerHeapElement&);
-    TimerHeapElement& operator=(const TimerHeapElement&);
-
-    TimerBase* timer() const { return m_timer; }
-
-    void checkConsistency() const
-    {
-        ASSERT(m_index >= 0);
-        ASSERT(m_index < static_cast<int>(timerHeap().size()));
-    }
+// ----------------
 
+class TimerHeapPointer {
+public:
+    TimerHeapPointer(TimerBase** pointer) : m_pointer(pointer) { }
+    TimerHeapReference operator*() const;
+    TimerBase* operator->() const { return *m_pointer; }
 private:
-    TimerHeapElement();
+    TimerBase** m_pointer;
+};
 
-    int m_index;
-    TimerBase* m_timer;
+class TimerHeapReference {
+public:
+    TimerHeapReference(TimerBase*& reference) : m_reference(reference) { }
+    operator TimerBase*() const { return m_reference; }
+    TimerHeapPointer operator&() const { return &m_reference; }
+    TimerHeapReference& operator=(TimerBase*);
+    TimerHeapReference& operator=(TimerHeapReference);
+private:
+    TimerBase*& m_reference;
 };
 
-inline TimerHeapElement::TimerHeapElement(const TimerHeapElement& o)
-    : m_index(-1), m_timer(o.timer())
+inline TimerHeapReference TimerHeapPointer::operator*() const
 {
+    return *m_pointer;
 }
 
-inline TimerHeapElement& TimerHeapElement::operator=(const TimerHeapElement& o)
+inline TimerHeapReference& TimerHeapReference::operator=(TimerBase* timer)
 {
-    TimerBase* t = o.timer();
-    m_timer = t;
-    if (m_index != -1) {
-        checkConsistency();
-        timerHeap()[m_index] = t;
-        t->m_heapIndex = m_index;
-    }
+    m_reference = timer;
+    Vector<TimerBase*>& heap = timerHeap();
+    if (&m_reference >= heap.data() && &m_reference < heap.data() + heap.size())
+        timer->m_heapIndex = &m_reference - heap.data();
     return *this;
 }
 
-inline bool operator<(const TimerHeapElement& a, const TimerHeapElement& b)
+inline TimerHeapReference& TimerHeapReference::operator=(TimerHeapReference b)
 {
-    // The comparisons below are "backwards" because the heap puts the largest 
-    // element first and we want the lowest time to be the first one in the heap.
-    double aFireTime = a.timer()->m_nextFireTime;
-    double bFireTime = b.timer()->m_nextFireTime;
-    if (bFireTime != aFireTime)
-        return bFireTime < aFireTime;
-    
-    // We need to look at the difference of the insertion orders instead of comparing the two 
-    // outright in case of overflow. 
-    unsigned difference = a.timer()->m_heapInsertionOrder - b.timer()->m_heapInsertionOrder;
-    return difference < UINT_MAX / 2;
+    TimerBase* timer = b;
+    return *this = timer;
+}
+
+inline void swap(TimerHeapReference a, TimerHeapReference b)
+{
+    TimerBase* timerA = a;
+    TimerBase* timerB = b;
+
+    // Invoke the assignment operator, since that takes care of updating m_heapIndex.
+    a = timerB;
+    b = timerA;
 }
 
 // ----------------
 
 // Class to represent iterators in the heap when calling the standard library heap algorithms.
-// Returns TimerHeapElement for elements in the heap rather than the TimerBase pointers themselves.
-class TimerHeapIterator : public iterator<random_access_iterator_tag, TimerHeapElement, int> {
+// Uses a custom pointer and reference type that update indices for pointers in the heap.
+class TimerHeapIterator : public iterator<random_access_iterator_tag, TimerBase*, ptrdiff_t, TimerHeapPointer, TimerHeapReference> {
 public:
-    TimerHeapIterator() : m_index(-1) { }
-    TimerHeapIterator(int i) : m_index(i) { checkConsistency(); }
-
-    TimerHeapIterator& operator++() { checkConsistency(); ++m_index; checkConsistency(); return *this; }
-    TimerHeapIterator operator++(int) { checkConsistency(); checkConsistency(1); return m_index++; }
+    explicit TimerHeapIterator(TimerBase** pointer) : m_pointer(pointer) { checkConsistency(); }
 
-    TimerHeapIterator& operator--() { checkConsistency(); --m_index; checkConsistency(); return *this; }
-    TimerHeapIterator operator--(int) { checkConsistency(); checkConsistency(-1); return m_index--; }
+    TimerHeapIterator& operator++() { checkConsistency(); ++m_pointer; checkConsistency(); return *this; }
+    TimerHeapIterator operator++(int) { checkConsistency(1); return TimerHeapIterator(m_pointer++); }
 
-    TimerHeapIterator& operator+=(int i) { checkConsistency(); m_index += i; checkConsistency(); return *this; }
-    TimerHeapIterator& operator-=(int i) { checkConsistency(); m_index -= i; checkConsistency(); return *this; }
+    TimerHeapIterator& operator--() { checkConsistency(); --m_pointer; checkConsistency(); return *this; }
+    TimerHeapIterator operator--(int) { checkConsistency(-1); return TimerHeapIterator(m_pointer--); }
 
-    TimerHeapElement operator*() const { return TimerHeapElement(m_index); }
-    TimerHeapElement operator[](int i) const { return TimerHeapElement(m_index + i); }
+    TimerHeapIterator& operator+=(ptrdiff_t i) { checkConsistency(); m_pointer += i; checkConsistency(); return *this; }
+    TimerHeapIterator& operator-=(ptrdiff_t i) { checkConsistency(); m_pointer -= i; checkConsistency(); return *this; }
 
-    int index() const { return m_index; }
+    TimerHeapReference operator*() const { return TimerHeapReference(*m_pointer); }
+    TimerHeapReference operator[](ptrdiff_t i) const { return TimerHeapReference(m_pointer[i]); }
+    TimerBase* operator->() const { return *m_pointer; }
 
-    void checkConsistency(int offset = 0) const
+private:
+    void checkConsistency(ptrdiff_t offset = 0) const
     {
-        ASSERT_UNUSED(offset, m_index + offset >= 0);
-        ASSERT_UNUSED(offset, m_index + offset <= static_cast<int>(timerHeap().size()));
+        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());
     }
 
-private:
-    int m_index;
+    friend bool operator==(TimerHeapIterator, TimerHeapIterator);
+    friend bool operator!=(TimerHeapIterator, TimerHeapIterator);
+    friend bool operator<(TimerHeapIterator, TimerHeapIterator);
+    friend bool operator>(TimerHeapIterator, TimerHeapIterator);
+    friend bool operator<=(TimerHeapIterator, TimerHeapIterator);
+    friend bool operator>=(TimerHeapIterator, TimerHeapIterator);
+    
+    friend TimerHeapIterator operator+(TimerHeapIterator, size_t);
+    friend TimerHeapIterator operator+(size_t, TimerHeapIterator);
+    
+    friend TimerHeapIterator operator-(TimerHeapIterator, size_t);
+    friend ptrdiff_t operator-(TimerHeapIterator, TimerHeapIterator);
+
+    TimerBase** m_pointer;
 };
 
-inline bool operator==(TimerHeapIterator a, TimerHeapIterator b) { return a.index() == b.index(); }
-inline bool operator!=(TimerHeapIterator a, TimerHeapIterator b) { return a.index() != b.index(); }
-inline bool operator<(TimerHeapIterator a, TimerHeapIterator b) { return a.index() < b.index(); }
+inline bool operator==(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer == b.m_pointer; }
+inline bool operator!=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer != b.m_pointer; }
+inline bool operator<(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer < b.m_pointer; }
+inline bool operator>(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer > b.m_pointer; }
+inline bool operator<=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer <= b.m_pointer; }
+inline bool operator>=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer >= b.m_pointer; }
+
+inline TimerHeapIterator operator+(TimerHeapIterator a, size_t b) { return TimerHeapIterator(a.m_pointer + b); }
+inline TimerHeapIterator operator+(size_t a, TimerHeapIterator b) { return TimerHeapIterator(a + b.m_pointer); }
 
-inline TimerHeapIterator operator+(TimerHeapIterator a, int b) { return a.index() + b; }
-inline TimerHeapIterator operator+(int a, TimerHeapIterator b) { return a + b.index(); }
+inline TimerHeapIterator operator-(TimerHeapIterator a, size_t b) { return TimerHeapIterator(a.m_pointer - b); }
+inline ptrdiff_t operator-(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer - b.m_pointer; }
 
-inline TimerHeapIterator operator-(TimerHeapIterator a, int b) { return a.index() - b; }
-inline int operator-(TimerHeapIterator a, TimerHeapIterator b) { return a.index() - b.index(); }
+// ----------------
+
+class TimerHeapLessThanFunction {
+public:
+    bool operator()(TimerBase*, TimerBase*) const;
+};
+
+inline bool TimerHeapLessThanFunction::operator()(TimerBase* a, TimerBase* b) const
+{
+    // The comparisons below are "backwards" because the heap puts the largest 
+    // element first and we want the lowest time to be the first one in the heap.
+    double aFireTime = a->m_nextFireTime;
+    double bFireTime = b->m_nextFireTime;
+    if (bFireTime != aFireTime)
+        return bFireTime < aFireTime;
+    
+    // We need to look at the difference of the insertion orders instead of comparing the two 
+    // outright in case of overflow. 
+    unsigned difference = a->m_heapInsertionOrder - b->m_heapInsertionOrder;
+    return difference < numeric_limits<unsigned>::max() / 2;
+}
 
 // ----------------
 
@@ -225,7 +255,8 @@ void TimerBase::heapDecreaseKey()
 {
     ASSERT(m_nextFireTime != 0);
     checkHeapIndex();
-    push_heap(TimerHeapIterator(0), TimerHeapIterator(m_heapIndex + 1));
+    TimerBase** heapData = timerHeap().data();
+    push_heap(TimerHeapIterator(heapData), TimerHeapIterator(heapData + m_heapIndex + 1), TimerHeapLessThanFunction());
     checkHeapIndex();
 }
 
@@ -274,7 +305,9 @@ void TimerBase::heapPopMin()
 {
     ASSERT(this == timerHeap().first());
     checkHeapIndex();
-    pop_heap(TimerHeapIterator(0), TimerHeapIterator(timerHeap().size()));
+    Vector<TimerBase*>& heap = timerHeap();
+    TimerBase** heapData = heap.data();
+    pop_heap(TimerHeapIterator(heapData), TimerHeapIterator(heapData + heap.size()), TimerHeapLessThanFunction());
     checkHeapIndex();
     ASSERT(this == timerHeap().last());
 }