2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef CopyWorkList_h
27 #define CopyWorkList_h
29 #include "CopyToken.h"
30 #include <wtf/DoublyLinkedList.h>
31 #include <wtf/Vector.h>
37 class CopyWorklistItem
{
44 CopyWorklistItem(JSCell
* cell
, CopyToken token
)
45 : m_value(bitwise_cast
<uintptr_t>(cell
) | static_cast<uintptr_t>(token
))
47 ASSERT(!(bitwise_cast
<uintptr_t>(cell
) & static_cast<uintptr_t>(mask
)));
48 ASSERT(static_cast<uintptr_t>(token
) <= mask
);
51 JSCell
* cell() const { return bitwise_cast
<JSCell
*>(m_value
& ~static_cast<uintptr_t>(mask
)); }
52 CopyToken
token() const { return static_cast<CopyToken
>(m_value
& mask
); }
55 static const unsigned requiredAlignment
= 8;
56 static const unsigned mask
= requiredAlignment
- 1;
61 class CopyWorkListSegment
: public DoublyLinkedListNode
<CopyWorkListSegment
> {
62 friend class WTF::DoublyLinkedListNode
<CopyWorkListSegment
>;
64 static CopyWorkListSegment
* create()
66 return new (NotNull
, fastMalloc(blockSize
)) CopyWorkListSegment();
69 static void destroy(CopyWorkListSegment
* segment
)
71 segment
->~CopyWorkListSegment();
75 size_t size() { return m_size
; }
76 bool isFull() { return reinterpret_cast<char*>(&data()[size()]) >= endOfBlock(); }
77 CopyWorklistItem
get(size_t index
) { return data()[index
]; }
79 void append(CopyWorklistItem item
)
82 data()[m_size
] = item
;
86 static const size_t blockSize
= 512;
90 : DoublyLinkedListNode
<CopyWorkListSegment
>()
95 CopyWorklistItem
* data() { return reinterpret_cast<CopyWorklistItem
*>(this + 1); }
96 char* endOfBlock() { return reinterpret_cast<char*>(this) + blockSize
; }
98 CopyWorkListSegment
* m_prev
;
99 CopyWorkListSegment
* m_next
;
103 class CopyWorkListIterator
{
104 friend class CopyWorkList
;
106 CopyWorklistItem
get() { return m_currentSegment
->get(m_currentIndex
); }
107 CopyWorklistItem
operator*() { return get(); }
108 CopyWorklistItem
operator->() { return get(); }
110 CopyWorkListIterator
& operator++()
114 if (m_currentIndex
>= m_currentSegment
->size()) {
116 m_currentSegment
= m_currentSegment
->next();
118 ASSERT(!m_currentSegment
|| m_currentSegment
->size());
124 bool operator==(const CopyWorkListIterator
& other
) const
126 return m_currentSegment
== other
.m_currentSegment
&& m_currentIndex
== other
.m_currentIndex
;
129 bool operator!=(const CopyWorkListIterator
& other
) const
131 return !(*this == other
);
134 CopyWorkListIterator()
135 : m_currentSegment(0)
141 CopyWorkListIterator(CopyWorkListSegment
* startSegment
, size_t startIndex
)
142 : m_currentSegment(startSegment
)
143 , m_currentIndex(startIndex
)
147 CopyWorkListSegment
* m_currentSegment
;
148 size_t m_currentIndex
;
152 WTF_MAKE_FAST_ALLOCATED
;
154 typedef CopyWorkListIterator iterator
;
159 void append(CopyWorklistItem
);
164 DoublyLinkedList
<CopyWorkListSegment
> m_segments
;
167 inline CopyWorkList::CopyWorkList()
171 inline CopyWorkList::~CopyWorkList()
173 while (!m_segments
.isEmpty())
174 CopyWorkListSegment::destroy(m_segments
.removeHead());
177 inline void CopyWorkList::append(CopyWorklistItem item
)
179 if (m_segments
.isEmpty() || m_segments
.tail()->isFull())
180 m_segments
.append(CopyWorkListSegment::create());
182 ASSERT(!m_segments
.tail()->isFull());
184 m_segments
.tail()->append(item
);
187 inline CopyWorkList::iterator
CopyWorkList::begin()
189 return CopyWorkListIterator(m_segments
.head(), 0);
192 inline CopyWorkList::iterator
CopyWorkList::end()
194 return CopyWorkListIterator();
199 #endif // CopyWorkList_h