]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/GCSegmentedArrayInlines.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / heap / GCSegmentedArrayInlines.h
CommitLineData
81345200
A
1/*
2 * Copyright (C) 2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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.
24 */
25
26#ifndef GCSegmentedArrayInlines_h
27#define GCSegmentedArrayInlines_h
28
81345200
A
29#include "GCSegmentedArray.h"
30
31namespace JSC {
32
33template <typename T>
ed1e77d3
A
34GCSegmentedArray<T>::GCSegmentedArray()
35 : m_top(0)
81345200
A
36 , m_numberOfSegments(0)
37{
ed1e77d3 38 m_segments.push(GCArraySegment<T>::create());
81345200
A
39 m_numberOfSegments++;
40}
41
42template <typename T>
43GCSegmentedArray<T>::~GCSegmentedArray()
44{
45 ASSERT(m_numberOfSegments == 1);
46 ASSERT(m_segments.size() == 1);
ed1e77d3 47 GCArraySegment<T>::destroy(m_segments.removeHead());
81345200
A
48 m_numberOfSegments--;
49 ASSERT(!m_numberOfSegments);
50 ASSERT(!m_segments.size());
51}
52
53template <typename T>
54void GCSegmentedArray<T>::clear()
55{
56 if (!m_segments.head())
57 return;
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);
ed1e77d3 62 GCArraySegment<T>::destroy(current);
81345200
A
63 }
64 m_top = 0;
65 m_numberOfSegments = 1;
66#if !ASSERT_DISABLED
67 m_segments.head()->m_top = 0;
68#endif
69}
70
71template <typename T>
72void GCSegmentedArray<T>::expand()
73{
74 ASSERT(m_segments.head()->m_top == s_segmentCapacity);
75
ed1e77d3 76 GCArraySegment<T>* nextSegment = GCArraySegment<T>::create();
81345200
A
77 m_numberOfSegments++;
78
79#if !ASSERT_DISABLED
80 nextSegment->m_top = 0;
81#endif
82
83 m_segments.push(nextSegment);
84 setTopForEmptySegment();
85 validatePrevious();
86}
87
88template <typename T>
89bool GCSegmentedArray<T>::refill()
90{
91 validatePrevious();
92 if (top())
93 return true;
ed1e77d3 94 GCArraySegment<T>::destroy(m_segments.removeHead());
81345200
A
95 ASSERT(m_numberOfSegments > 1);
96 m_numberOfSegments--;
97 setTopForFullSegment();
98 validatePrevious();
99 return true;
100}
101
102template <typename T>
103void GCSegmentedArray<T>::fillVector(Vector<T>& vector)
104{
105 ASSERT(vector.size() == size());
106
107 GCArraySegment<T>* currentSegment = m_segments.head();
108 if (!currentSegment)
109 return;
110
111 unsigned count = 0;
112 for (unsigned i = 0; i < m_top; ++i) {
113 ASSERT(currentSegment->data()[i]);
114 vector[count++] = currentSegment->data()[i];
115 }
116
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];
122 }
123 currentSegment = currentSegment->next();
124 }
125}
126
127template <typename T>
ed1e77d3 128inline GCArraySegment<T>* GCArraySegment<T>::create()
81345200 129{
ed1e77d3
A
130 return new (NotNull, fastMalloc(blockSize)) GCArraySegment<T>();
131}
132
133template <typename T>
134inline void GCArraySegment<T>::destroy(GCArraySegment* segment)
135{
136 segment->~GCArraySegment();
137 fastFree(segment);
81345200
A
138}
139
140template <typename T>
141inline size_t GCSegmentedArray<T>::postIncTop()
142{
143 size_t result = m_top++;
144 ASSERT(result == m_segments.head()->m_top++);
145 return result;
146}
147
148template <typename T>
149inline size_t GCSegmentedArray<T>::preDecTop()
150{
151 size_t result = --m_top;
152 ASSERT(result == --m_segments.head()->m_top);
153 return result;
154}
155
156template <typename T>
157inline void GCSegmentedArray<T>::setTopForFullSegment()
158{
159 ASSERT(m_segments.head()->m_top == s_segmentCapacity);
160 m_top = s_segmentCapacity;
161}
162
163template <typename T>
164inline void GCSegmentedArray<T>::setTopForEmptySegment()
165{
166 ASSERT(!m_segments.head()->m_top);
167 m_top = 0;
168}
169
170template <typename T>
171inline size_t GCSegmentedArray<T>::top()
172{
173 ASSERT(m_top == m_segments.head()->m_top);
174 return m_top;
175}
176
177template <typename T>
178#if ASSERT_DISABLED
179inline void GCSegmentedArray<T>::validatePrevious() { }
180#else
181inline void GCSegmentedArray<T>::validatePrevious()
182{
183 unsigned count = 0;
184 for (GCArraySegment<T>* current = m_segments.head(); current; current = current->next())
185 count++;
186 ASSERT(m_segments.size() == m_numberOfSegments);
187}
188#endif
189
190template <typename T>
191inline void GCSegmentedArray<T>::append(T value)
192{
193 if (m_top == s_segmentCapacity)
194 expand();
195 m_segments.head()->data()[postIncTop()] = value;
196}
197
198template <typename T>
199inline bool GCSegmentedArray<T>::canRemoveLast()
200{
201 return !!m_top;
202}
203
204template <typename T>
205inline const T GCSegmentedArray<T>::removeLast()
206{
207 return m_segments.head()->data()[preDecTop()];
208}
209
210template <typename T>
211inline bool GCSegmentedArray<T>::isEmpty()
212{
213 if (m_top)
214 return false;
215 if (m_segments.head()->next()) {
216 ASSERT(m_segments.head()->next()->m_top == s_segmentCapacity);
217 return false;
218 }
219 return true;
220}
221
222template <typename T>
223inline size_t GCSegmentedArray<T>::size()
224{
225 return m_top + s_segmentCapacity * (m_numberOfSegments - 1);
226}
227
228} // namespace JSC
229
230#endif // GCSegmentedArrayInlines_h