| 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 |