OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_HYDROGEN_UNIQUE_H_ | 5 #ifndef V8_HYDROGEN_UNIQUE_H_ |
6 #define V8_HYDROGEN_UNIQUE_H_ | 6 #define V8_HYDROGEN_UNIQUE_H_ |
7 | 7 |
8 #include "handles.h" | 8 #include "handles.h" |
9 #include "objects.h" | 9 #include "objects.h" |
10 #include "utils.h" | 10 #include "utils.h" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 friend class SideEffectsTracker; | 127 friend class SideEffectsTracker; |
128 }; | 128 }; |
129 | 129 |
130 | 130 |
131 template <typename T> | 131 template <typename T> |
132 class UniqueSet V8_FINAL : public ZoneObject { | 132 class UniqueSet V8_FINAL : public ZoneObject { |
133 public: | 133 public: |
134 // Constructor. A new set will be empty. | 134 // Constructor. A new set will be empty. |
135 UniqueSet() : size_(0), capacity_(0), array_(NULL) { } | 135 UniqueSet() : size_(0), capacity_(0), array_(NULL) { } |
136 | 136 |
| 137 // Capacity constructor. A new set will be empty. |
| 138 UniqueSet(int capacity, Zone* zone) |
| 139 : size_(0), capacity_(capacity), |
| 140 array_(zone->NewArray<Unique<T> >(capacity)) { |
| 141 ASSERT(capacity <= kMaxCapacity); |
| 142 } |
| 143 |
| 144 // Singleton constructor. |
| 145 UniqueSet(Unique<T> uniq, Zone* zone) |
| 146 : size_(1), capacity_(1), array_(zone->NewArray<Unique<T> >(1)) { |
| 147 array_[0] = uniq; |
| 148 } |
| 149 |
137 // Add a new element to this unique set. Mutates this set. O(|this|). | 150 // Add a new element to this unique set. Mutates this set. O(|this|). |
138 void Add(Unique<T> uniq, Zone* zone) { | 151 void Add(Unique<T> uniq, Zone* zone) { |
139 ASSERT(uniq.IsInitialized()); | 152 ASSERT(uniq.IsInitialized()); |
140 // Keep the set sorted by the {raw_address} of the unique elements. | 153 // Keep the set sorted by the {raw_address} of the unique elements. |
141 for (int i = 0; i < size_; i++) { | 154 for (int i = 0; i < size_; i++) { |
142 if (array_[i] == uniq) return; | 155 if (array_[i] == uniq) return; |
143 if (array_[i].raw_address_ > uniq.raw_address_) { | 156 if (array_[i].raw_address_ > uniq.raw_address_) { |
144 // Insert in the middle. | 157 // Insert in the middle. |
145 Grow(size_ + 1, zone); | 158 Grow(size_ + 1, zone); |
146 for (int j = size_ - 1; j >= i; j--) array_[j + 1] = array_[j]; | 159 for (int j = size_ - 1; j >= i; j--) array_[j + 1] = array_[j]; |
(...skipping 24 matching lines...) Expand all Loading... |
171 for (int i = 0; i < this->size_; i++) { | 184 for (int i = 0; i < this->size_; i++) { |
172 if (this->array_[i] != that->array_[i]) return false; | 185 if (this->array_[i] != that->array_[i]) return false; |
173 } | 186 } |
174 return true; | 187 return true; |
175 } | 188 } |
176 | 189 |
177 // Check whether this set contains the given element. O(|this|) | 190 // Check whether this set contains the given element. O(|this|) |
178 // TODO(titzer): use binary search for large sets to make this O(log|this|) | 191 // TODO(titzer): use binary search for large sets to make this O(log|this|) |
179 template <typename U> | 192 template <typename U> |
180 bool Contains(const Unique<U> elem) const { | 193 bool Contains(const Unique<U> elem) const { |
181 for (int i = 0; i < size_; i++) { | 194 for (int i = 0; i < this->size_; ++i) { |
182 if (this->array_[i] == elem) return true; | 195 Unique<T> cand = this->array_[i]; |
| 196 if (cand.raw_address_ >= elem.raw_address_) { |
| 197 return cand.raw_address_ == elem.raw_address_; |
| 198 } |
183 } | 199 } |
184 return false; | 200 return false; |
185 } | 201 } |
186 | 202 |
187 // Check if this set is a subset of the given set. O(|this| + |that|). | 203 // Check if this set is a subset of the given set. O(|this| + |that|). |
188 bool IsSubset(const UniqueSet<T>* that) const { | 204 bool IsSubset(const UniqueSet<T>* that) const { |
189 if (that->size_ < this->size_) return false; | 205 if (that->size_ < this->size_) return false; |
190 int j = 0; | 206 int j = 0; |
191 for (int i = 0; i < this->size_; i++) { | 207 for (int i = 0; i < this->size_; i++) { |
192 Unique<T> sought = this->array_[i]; | 208 Unique<T> sought = this->array_[i]; |
193 while (true) { | 209 while (true) { |
194 if (sought == that->array_[j++]) break; | 210 if (sought == that->array_[j++]) break; |
195 // Fail whenever there are more elements in {this} than {that}. | 211 // Fail whenever there are more elements in {this} than {that}. |
196 if ((this->size_ - i) > (that->size_ - j)) return false; | 212 if ((this->size_ - i) > (that->size_ - j)) return false; |
197 } | 213 } |
198 } | 214 } |
199 return true; | 215 return true; |
200 } | 216 } |
201 | 217 |
202 // Returns a new set representing the intersection of this set and the other. | 218 // Returns a new set representing the intersection of this set and the other. |
203 // O(|this| + |that|). | 219 // O(|this| + |that|). |
204 UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) const { | 220 UniqueSet<T>* Intersect(const UniqueSet<T>* that, Zone* zone) const { |
205 if (that->size_ == 0 || this->size_ == 0) return new(zone) UniqueSet<T>(); | 221 if (that->size_ == 0 || this->size_ == 0) return new(zone) UniqueSet<T>(); |
206 | 222 |
207 UniqueSet<T>* out = new(zone) UniqueSet<T>(); | 223 UniqueSet<T>* out = new(zone) UniqueSet<T>( |
208 out->Grow(Min(this->size_, that->size_), zone); | 224 Min(this->size_, that->size_), zone); |
209 | 225 |
210 int i = 0, j = 0, k = 0; | 226 int i = 0, j = 0, k = 0; |
211 while (i < this->size_ && j < that->size_) { | 227 while (i < this->size_ && j < that->size_) { |
212 Unique<T> a = this->array_[i]; | 228 Unique<T> a = this->array_[i]; |
213 Unique<T> b = that->array_[j]; | 229 Unique<T> b = that->array_[j]; |
214 if (a == b) { | 230 if (a == b) { |
215 out->array_[k++] = a; | 231 out->array_[k++] = a; |
216 i++; | 232 i++; |
217 j++; | 233 j++; |
218 } else if (a.raw_address_ < b.raw_address_) { | 234 } else if (a.raw_address_ < b.raw_address_) { |
219 i++; | 235 i++; |
220 } else { | 236 } else { |
221 j++; | 237 j++; |
222 } | 238 } |
223 } | 239 } |
224 | 240 |
225 out->size_ = k; | 241 out->size_ = k; |
226 return out; | 242 return out; |
227 } | 243 } |
228 | 244 |
229 // Returns a new set representing the union of this set and the other. | 245 // Returns a new set representing the union of this set and the other. |
230 // O(|this| + |that|). | 246 // O(|this| + |that|). |
231 UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) const { | 247 UniqueSet<T>* Union(const UniqueSet<T>* that, Zone* zone) const { |
232 if (that->size_ == 0) return this->Copy(zone); | 248 if (that->size_ == 0) return this->Copy(zone); |
233 if (this->size_ == 0) return that->Copy(zone); | 249 if (this->size_ == 0) return that->Copy(zone); |
234 | 250 |
235 UniqueSet<T>* out = new(zone) UniqueSet<T>(); | 251 UniqueSet<T>* out = new(zone) UniqueSet<T>( |
236 out->Grow(this->size_ + that->size_, zone); | 252 this->size_ + that->size_, zone); |
237 | 253 |
238 int i = 0, j = 0, k = 0; | 254 int i = 0, j = 0, k = 0; |
239 while (i < this->size_ && j < that->size_) { | 255 while (i < this->size_ && j < that->size_) { |
240 Unique<T> a = this->array_[i]; | 256 Unique<T> a = this->array_[i]; |
241 Unique<T> b = that->array_[j]; | 257 Unique<T> b = that->array_[j]; |
242 if (a == b) { | 258 if (a == b) { |
243 out->array_[k++] = a; | 259 out->array_[k++] = a; |
244 i++; | 260 i++; |
245 j++; | 261 j++; |
246 } else if (a.raw_address_ < b.raw_address_) { | 262 } else if (a.raw_address_ < b.raw_address_) { |
247 out->array_[k++] = a; | 263 out->array_[k++] = a; |
248 i++; | 264 i++; |
249 } else { | 265 } else { |
250 out->array_[k++] = b; | 266 out->array_[k++] = b; |
251 j++; | 267 j++; |
252 } | 268 } |
253 } | 269 } |
254 | 270 |
255 while (i < this->size_) out->array_[k++] = this->array_[i++]; | 271 while (i < this->size_) out->array_[k++] = this->array_[i++]; |
256 while (j < that->size_) out->array_[k++] = that->array_[j++]; | 272 while (j < that->size_) out->array_[k++] = that->array_[j++]; |
257 | 273 |
258 out->size_ = k; | 274 out->size_ = k; |
259 return out; | 275 return out; |
260 } | 276 } |
261 | 277 |
262 // Makes an exact copy of this set. O(|this|). | 278 // Makes an exact copy of this set. O(|this|). |
263 UniqueSet<T>* Copy(Zone* zone) const { | 279 UniqueSet<T>* Copy(Zone* zone) const { |
264 UniqueSet<T>* copy = new(zone) UniqueSet<T>(); | 280 UniqueSet<T>* copy = new(zone) UniqueSet<T>(this->size_, zone); |
265 copy->size_ = this->size_; | 281 copy->size_ = this->size_; |
266 copy->capacity_ = this->size_; | |
267 copy->array_ = zone->NewArray<Unique<T> >(this->size_); | |
268 memcpy(copy->array_, this->array_, this->size_ * sizeof(Unique<T>)); | 282 memcpy(copy->array_, this->array_, this->size_ * sizeof(Unique<T>)); |
269 return copy; | 283 return copy; |
270 } | 284 } |
271 | 285 |
272 void Clear() { | 286 void Clear() { |
273 size_ = 0; | 287 size_ = 0; |
274 } | 288 } |
275 | 289 |
276 inline int size() const { | 290 inline int size() const { |
277 return size_; | 291 return size_; |
(...skipping 26 matching lines...) Expand all Loading... |
304 capacity_ = new_capacity; | 318 capacity_ = new_capacity; |
305 array_ = new_array; | 319 array_ = new_array; |
306 } | 320 } |
307 } | 321 } |
308 }; | 322 }; |
309 | 323 |
310 | 324 |
311 } } // namespace v8::internal | 325 } } // namespace v8::internal |
312 | 326 |
313 #endif // V8_HYDROGEN_UNIQUE_H_ | 327 #endif // V8_HYDROGEN_UNIQUE_H_ |
OLD | NEW |