]>
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 "GCSegmentedArray.h"
34 GCSegmentedArray
<T
>::GCSegmentedArray()
36 , m_numberOfSegments(0)
38 m_segments
.push(GCArraySegment
<T
>::create());
43 GCSegmentedArray
<T
>::~GCSegmentedArray()
45 ASSERT(m_numberOfSegments
== 1);
46 ASSERT(m_segments
.size() == 1);
47 GCArraySegment
<T
>::destroy(m_segments
.removeHead());
49 ASSERT(!m_numberOfSegments
);
50 ASSERT(!m_segments
.size());
54 void GCSegmentedArray
<T
>::clear()
56 if (!m_segments
.head())
58 GCArraySegment
<T
>* next
;
59 for (GCArraySegment
<T
>* current
= m_segments
.head(); current
->next(); current
= next
) {
60 next
= current
->next();
61 m_segments
.remove(current
);
62 GCArraySegment
<T
>::destroy(current
);
65 m_numberOfSegments
= 1;
67 m_segments
.head()->m_top
= 0;
72 void GCSegmentedArray
<T
>::expand()
74 ASSERT(m_segments
.head()->m_top
== s_segmentCapacity
);
76 GCArraySegment
<T
>* nextSegment
= GCArraySegment
<T
>::create();
80 nextSegment
->m_top
= 0;
83 m_segments
.push(nextSegment
);
84 setTopForEmptySegment();
89 bool GCSegmentedArray
<T
>::refill()
94 GCArraySegment
<T
>::destroy(m_segments
.removeHead());
95 ASSERT(m_numberOfSegments
> 1);
97 setTopForFullSegment();
102 template <typename T
>
103 void GCSegmentedArray
<T
>::fillVector(Vector
<T
>& vector
)
105 ASSERT(vector
.size() == size());
107 GCArraySegment
<T
>* currentSegment
= m_segments
.head();
112 for (unsigned i
= 0; i
< m_top
; ++i
) {
113 ASSERT(currentSegment
->data()[i
]);
114 vector
[count
++] = currentSegment
->data()[i
];
117 currentSegment
= currentSegment
->next();
118 while (currentSegment
) {
119 for (unsigned i
= 0; i
< s_segmentCapacity
; ++i
) {
120 ASSERT(currentSegment
->data()[i
]);
121 vector
[count
++] = currentSegment
->data()[i
];
123 currentSegment
= currentSegment
->next();
127 template <typename T
>
128 inline GCArraySegment
<T
>* GCArraySegment
<T
>::create()
130 return new (NotNull
, fastMalloc(blockSize
)) GCArraySegment
<T
>();
133 template <typename T
>
134 inline void GCArraySegment
<T
>::destroy(GCArraySegment
* segment
)
136 segment
->~GCArraySegment();
140 template <typename T
>
141 inline size_t GCSegmentedArray
<T
>::postIncTop()
143 size_t result
= m_top
++;
144 ASSERT(result
== m_segments
.head()->m_top
++);
148 template <typename T
>
149 inline size_t GCSegmentedArray
<T
>::preDecTop()
151 size_t result
= --m_top
;
152 ASSERT(result
== --m_segments
.head()->m_top
);
156 template <typename T
>
157 inline void GCSegmentedArray
<T
>::setTopForFullSegment()
159 ASSERT(m_segments
.head()->m_top
== s_segmentCapacity
);
160 m_top
= s_segmentCapacity
;
163 template <typename T
>
164 inline void GCSegmentedArray
<T
>::setTopForEmptySegment()
166 ASSERT(!m_segments
.head()->m_top
);
170 template <typename T
>
171 inline size_t GCSegmentedArray
<T
>::top()
173 ASSERT(m_top
== m_segments
.head()->m_top
);
177 template <typename T
>
179 inline void GCSegmentedArray
<T
>::validatePrevious() { }
181 inline void GCSegmentedArray
<T
>::validatePrevious()
184 for (GCArraySegment
<T
>* current
= m_segments
.head(); current
; current
= current
->next())
186 ASSERT(m_segments
.size() == m_numberOfSegments
);
190 template <typename T
>
191 inline void GCSegmentedArray
<T
>::append(T value
)
193 if (m_top
== s_segmentCapacity
)
195 m_segments
.head()->data()[postIncTop()] = value
;
198 template <typename T
>
199 inline bool GCSegmentedArray
<T
>::canRemoveLast()
204 template <typename T
>
205 inline const T GCSegmentedArray
<T
>::removeLast()
207 return m_segments
.head()->data()[preDecTop()];
210 template <typename T
>
211 inline bool GCSegmentedArray
<T
>::isEmpty()
215 if (m_segments
.head()->next()) {
216 ASSERT(m_segments
.head()->next()->m_top
== s_segmentCapacity
);
222 template <typename T
>
223 inline size_t GCSegmentedArray
<T
>::size()
225 return m_top
+ s_segmentCapacity
* (m_numberOfSegments
- 1);
230 #endif // GCSegmentedArrayInlines_h