Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(917)

Side by Side Diff: src/hydrogen.h

Issue 23609020: First implementation of HUnique<T> and HUniqueSet<T>, which is supposed to replace UniqueValueId. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/cctest/cctest.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2283 matching lines...) Expand 10 before | Expand all | Expand 10 after
2294 } 2294 }
2295 ~NoObservableSideEffectsScope() { 2295 ~NoObservableSideEffectsScope() {
2296 builder_->graph()->DecrementInNoSideEffectsScope(); 2296 builder_->graph()->DecrementInNoSideEffectsScope();
2297 } 2297 }
2298 2298
2299 private: 2299 private:
2300 HGraphBuilder* builder_; 2300 HGraphBuilder* builder_;
2301 }; 2301 };
2302 2302
2303 2303
2304 template <typename T>
2305 class HUniqueSet;
2306
2307
2308 template <typename T>
2309 class HUnique V8_FINAL {
rossberg 2013/09/11 10:34:07 I think this should live somewhere else (e.g. hand
Toon Verwaest 2013/09/11 11:17:57 A separate file would be nice.
2310 public:
2311 // TODO(titzer): this should be private.
2312 explicit HUnique(Handle<T> handle) {
2313 if (handle.is_null()) {
2314 raw_address_ = NULL;
2315 } else {
2316 raw_address_ = reinterpret_cast<Address>(*handle);
Toon Verwaest 2013/09/11 11:17:57 Can we ensure that this is only called in a Disall
2317 ASSERT_NE(raw_address_, NULL);
2318 }
2319 handle_ = handle;
2320 }
2321
2322 // Constructor for handling automatic up casting.
2323 // Ex. HUnique<JSFunction> can be passed when HUnique<Object> is expected.
2324 template <class S> HUnique(HUnique<S> uniq) {
2325 #ifdef DEBUG
2326 T* a = NULL;
2327 S* b = NULL;
2328 a = b; // Fake assignment to enforce type checks.
2329 USE(a);
2330 #endif
2331 raw_address_ = uniq.raw_address_;
2332 handle_ = uniq.handle_; // Creates a new handle sharing the same location.
2333 }
2334
2335 template <typename U>
2336 bool operator==(const HUnique<U>& other) const {
2337 return raw_address_ == other.raw_address_;
2338 }
2339
2340 template <typename U>
2341 bool operator!=(const HUnique<U>& other) const {
2342 return raw_address_ != other.raw_address_;
2343 }
2344
2345 intptr_t Hashcode() const {
2346 return reinterpret_cast<intptr_t>(raw_address_);
2347 }
2348
2349 bool IsNull() {
2350 return raw_address_ == NULL;
2351 }
2352
2353 // Don't do this unless you have access to the heap!
2354 // No, seriously! You can compare and hash and set-ify uniques that were
2355 // all created at the same time; please don't dereference.
2356 Handle<T> handle() {
2357 return handle_;
2358 }
2359
2360 friend class HUniqueSet<T>; // Uses internal implementation details for speed
2361 template <class U>
2362 friend class HUnique; // For comparing raw_address values
2363
2364 private:
2365 Address raw_address_;
2366 Handle<T> handle_;
2367 };
2368
2369
2370 template <typename T>
2371 class HUniqueSet V8_FINAL : public ZoneObject {
2372 public:
2373 // Constructor; a new set will be empty.
2374 HUniqueSet() : size_(0), capacity_(0), array_(NULL) { }
2375
2376 // Add a new element to this unique set; mutates this set.
2377 void Add(HUnique<T> uniq, Zone* zone) {
2378 // Keep the set sorted by the {raw_address} of the unique elements.
2379 for (int i = 0; i < size_; i++) {
2380 if (array_[i] == uniq) return;
2381 if (array_[i].raw_address_ > uniq.raw_address_) {
2382 // Insert in the middle.
2383 Grow(size_ + 1, zone);
Toon Verwaest 2013/09/11 11:17:57 You can merge this code with the code after the fo
2384 for (int j = size_ - 1; j >= i; j--) {
rossberg 2013/09/11 10:34:07 Could it be worth using memmove here?
2385 array_[j + 1] = array_[j];
2386 }
2387 array_[i] = uniq;
2388 size_++;
2389 return;
2390 }
2391 }
2392 // Append the element to the the end.
2393 Grow(size_ + 1, zone);
2394 array_[size_++] = uniq;
2395 }
2396
2397 // Compare this set against another set.
2398 bool Equals(HUniqueSet<T>* that) {
2399 if (that->size_ != this->size_) return false;
2400 for (int i = 0; i < this->size_; i++) {
2401 if (this->array_[i] != that->array_[i]) return false;
2402 }
2403 return true;
2404 }
2405
2406 // Check if this set is a subset of the given set.
2407 bool IsSubset(HUniqueSet<T>* that) {
2408 if (that->size_ < this->size_) return false;
2409 int j = 0;
2410 for (int i = 0; i < this->size_; i++) {
2411 HUnique<T> sought = this->array_[i];
2412 bool found = false;
rossberg 2013/09/11 10:34:07 The rest of this for-loop could be simplified to:
Toon Verwaest 2013/09/11 14:24:11 This version double-checks every entry though; sin
rossberg 2013/09/11 15:01:49 Good catch. Tweaking that is left as an exercise.
Toon Verwaest 2013/09/11 15:27:53 Hence the version I attached in my previous commen
rossberg 2013/09/12 09:34:45 That's still one for the kitty. :)
2413 while (j < that->size_) {
2414 if (sought == that->array_[j++]) {
2415 found = true;
2416 break;
2417 }
2418 }
2419 if (!found) return false;
Toon Verwaest 2013/09/11 11:17:57 For minimal checking if (that->size_ < this->size
2420 }
2421 return true;
2422 }
2423
2424 // Returns a new set representing the intersection of this set and the other.
2425 HUniqueSet<T>* Intersect(HUniqueSet<T>* that, Zone* zone) {
2426 if (that->size_ == 0 || this->size_ == 0) return new(zone) HUniqueSet<T>();
2427
2428 HUniqueSet<T>* out = new(zone) HUniqueSet<T>();
2429 out->Grow(this->size_ > that->size_ ? this->size_ : that->size_, zone);
rossberg 2013/09/11 10:34:07 Nit: Min(...)
Toon Verwaest 2013/09/11 11:17:57 I guess you meant to flip the sizes? What about ju
2430
2431 int i = 0, j = 0, k = 0;
2432 for (;;) {
2433 if (i >= this->size_) break; // Left has been exhausted.
2434 if (j >= that->size_) break; // Right has been exhausted.
rossberg 2013/09/11 10:34:07 Why not simply while (i < this->size && j < that-
2435
2436 HUnique<T> a = this->array_[i];
2437 HUnique<T> b = that->array_[j];
2438 if (a == b) {
2439 out->array_[k++] = a;
2440 i++;
2441 j++;
2442 } else if (a.raw_address_ < b.raw_address_) {
2443 i++;
2444 } else {
2445 j++;
2446 }
2447 }
2448
2449 out->size_ = k;
2450 return out;
2451 }
2452
2453 // Returns a new set representing the union of this set and the other.
2454 HUniqueSet<T>* Union(HUniqueSet<T>* that, Zone* zone) {
2455 if (that->size_ == 0) return this->Copy(zone);
2456 if (this->size_ == 0) return that->Copy(zone);
2457
2458 HUniqueSet<T>* out = new(zone) HUniqueSet<T>();
2459 out->Grow(this->size_ + that->size_, zone);
2460
2461 int i = 0, j = 0, k = 0;
2462 for (;;) {
rossberg 2013/09/11 10:34:07 Same here: while (i < this->size && j < that->siz
2463 if (i >= this->size_) { // Left has been exhausted.
2464 while (j < that->size_) out->array_[k++] = that->array_[j++];
2465 break;
2466 }
2467 if (j >= that->size_) { // Right has been exhausted.
2468 while (i < this->size_) out->array_[k++] = this->array_[i++];
2469 break;
2470 }
2471
2472 HUnique<T> a = this->array_[i];
2473 HUnique<T> b = that->array_[j];
2474 if (a == b) {
2475 out->array_[k++] = a;
2476 i++;
2477 j++;
2478 } else if (a.raw_address_ < b.raw_address_) {
2479 out->array_[k++] = a;
2480 i++;
2481 } else {
2482 out->array_[k++] = b;
2483 j++;
2484 }
2485 }
2486
2487 out->size_ = k;
2488 return out;
2489 }
2490
2491 // Makes an exact copy of this set.
2492 HUniqueSet<T>* Copy(Zone* zone) {
2493 HUniqueSet<T>* copy = new(zone) HUniqueSet<T>();
2494 copy->size_ = this->size_;
2495 copy->capacity_ = this->size_;
2496 copy->array_ = zone->NewArray<HUnique<T> >(this->size_);
2497 memcpy(copy->array_, this->array_, this->size_ * sizeof(HUnique<T>));
2498 return copy;
2499 }
2500
2501 inline int size() {
2502 return size_;
2503 }
2504
2505 private:
2506 // These sets should be small, since operations are implemented with simple
2507 // linear algorithms. Enforce a maximum size.
2508 static const int kMaxCapacity = 65535;
2509
2510 uint16_t size_;
2511 uint16_t capacity_;
2512 HUnique<T>* array_;
2513
2514 // Grow the size of internal storage to be at least {size} elements.
2515 void Grow(int size, Zone* zone) {
2516 CHECK(size < kMaxCapacity); // Enforce maximum size.
2517 if (capacity_ < size) {
2518 int new_capacity = capacity_ + capacity_ + size; // 2*current + needed
rossberg 2013/09/11 10:34:07 That seems like a lot, and can cause up to a 200%
Toon Verwaest 2013/09/11 11:17:57 I guess this is 0, 1 or 4? Otherwise it seems like
2519 if (new_capacity > kMaxCapacity) new_capacity = kMaxCapacity;
2520 HUnique<T>* new_array = zone->NewArray<HUnique<T> >(new_capacity);
2521 memcpy(new_array, array_, size_ * sizeof(HUnique<T>));
2522 capacity_ = new_capacity;
2523 array_ = new_array;
2524 }
2525 }
2526 };
2527
2528
2304 } } // namespace v8::internal 2529 } } // namespace v8::internal
2305 2530
2306 #endif // V8_HYDROGEN_H_ 2531 #endif // V8_HYDROGEN_H_
OLDNEW
« no previous file with comments | « no previous file | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698