]>
git.saurik.com Git - apple/javascriptcore.git/blob - heap/GCSegmentedArrayInlines.h
2 * Copyright (C) 2014 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 GCSegmentedArrayInlines_h
27 #define GCSegmentedArrayInlines_h
29 #include "BlockAllocator.h"
30 #include "GCSegmentedArray.h"
35 GCSegmentedArray
<T
>::GCSegmentedArray(BlockAllocator
& blockAllocator
)
36 : m_blockAllocator(blockAllocator
)
38 , m_numberOfSegments(0)
40 m_segments
.push(GCArraySegment
<T
>::create(m_blockAllocator
.allocate
<GCArraySegment
<T
>>()));
45 GCSegmentedArray
<T
>::~GCSegmentedArray()
47 ASSERT(m_numberOfSegments
== 1);
48 ASSERT(m_segments
.size() == 1);
49 m_blockAllocator
.deallocate(GCArraySegment
<T
>::destroy(m_segments
.removeHead()));
51 ASSERT(!m_numberOfSegments
);
52 ASSERT(!m_segments
.size());
56 void GCSegmentedArray
<T
>::clear()
58 if (!m_segments
.head())
60 GCArraySegment
<T
>* next
;
61 for (GCArraySegment
<T
>* current
= m_segments
.head(); current
->next(); current
= next
) {
62 next
= current
->next();
63 m_segments
.remove(current
);
64 m_blockAllocator
.deallocate(GCArraySegment
<T
>::destroy(current
));
67 m_numberOfSegments
= 1;
69 m_segments
.head()->m_top
= 0;
74 void GCSegmentedArray
<T
>::expand()
76 ASSERT(m_segments
.head()->m_top
== s_segmentCapacity
);
78 GCArraySegment
<T
>* nextSegment
= GCArraySegment
<T
>::create(m_blockAllocator
.allocate
<GCArraySegment
<T
>>());
82 nextSegment
->m_top
= 0;
85 m_segments
.push(nextSegment
);
86 setTopForEmptySegment();
91 bool GCSegmentedArray
<T
>::refill()
96 m_blockAllocator
.deallocate(GCArraySegment
<T
>::destroy(m_segments
.removeHead()));
97 ASSERT(m_numberOfSegments
> 1);
99 setTopForFullSegment();
104 template <typename T
>
105 void GCSegmentedArray
<T
>::fillVector(Vector
<T
>& vector
)
107 ASSERT(vector
.size() == size());
109 GCArraySegment
<T
>* currentSegment
= m_segments
.head();
114 for (unsigned i
= 0; i
< m_top
; ++i
) {
115 ASSERT(currentSegment
->data()[i
]);
116 vector
[count
++] = currentSegment
->data()[i
];
119 currentSegment
= currentSegment
->next();
120 while (currentSegment
) {
121 for (unsigned i
= 0; i
< s_segmentCapacity
; ++i
) {
122 ASSERT(currentSegment
->data()[i
]);
123 vector
[count
++] = currentSegment
->data()[i
];
125 currentSegment
= currentSegment
->next();
129 template <typename T
>
130 inline GCArraySegment
<T
>* GCArraySegment
<T
>::create(DeadBlock
* block
)
132 return new (NotNull
, block
) GCArraySegment
<T
>(block
->region());
135 template <typename T
>
136 inline size_t GCSegmentedArray
<T
>::postIncTop()
138 size_t result
= m_top
++;
139 ASSERT(result
== m_segments
.head()->m_top
++);
143 template <typename T
>
144 inline size_t GCSegmentedArray
<T
>::preDecTop()
146 size_t result
= --m_top
;
147 ASSERT(result
== --m_segments
.head()->m_top
);
151 template <typename T
>
152 inline void GCSegmentedArray
<T
>::setTopForFullSegment()
154 ASSERT(m_segments
.head()->m_top
== s_segmentCapacity
);
155 m_top
= s_segmentCapacity
;
158 template <typename T
>
159 inline void GCSegmentedArray
<T
>::setTopForEmptySegment()
161 ASSERT(!m_segments
.head()->m_top
);
165 template <typename T
>
166 inline size_t GCSegmentedArray
<T
>::top()
168 ASSERT(m_top
== m_segments
.head()->m_top
);
172 template <typename T
>
174 inline void GCSegmentedArray
<T
>::validatePrevious() { }
176 inline void GCSegmentedArray
<T
>::validatePrevious()
179 for (GCArraySegment
<T
>* current
= m_segments
.head(); current
; current
= current
->next())
181 ASSERT(m_segments
.size() == m_numberOfSegments
);
185 template <typename T
>
186 inline void GCSegmentedArray
<T
>::append(T value
)
188 if (m_top
== s_segmentCapacity
)
190 m_segments
.head()->data()[postIncTop()] = value
;
193 template <typename T
>
194 inline bool GCSegmentedArray
<T
>::canRemoveLast()
199 template <typename T
>
200 inline const T GCSegmentedArray
<T
>::removeLast()
202 return m_segments
.head()->data()[preDecTop()];
205 template <typename T
>
206 inline bool GCSegmentedArray
<T
>::isEmpty()
210 if (m_segments
.head()->next()) {
211 ASSERT(m_segments
.head()->next()->m_top
== s_segmentCapacity
);
217 template <typename T
>
218 inline size_t GCSegmentedArray
<T
>::size()
220 return m_top
+ s_segmentCapacity
* (m_numberOfSegments
- 1);
225 #endif // GCSegmentedArrayInlines_h