| OLD | NEW |
| 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 13 matching lines...) Expand all Loading... |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_UTILS_H_ | 28 #ifndef V8_UTILS_H_ |
| 29 #define V8_UTILS_H_ | 29 #define V8_UTILS_H_ |
| 30 | 30 |
| 31 #include <limits.h> | 31 #include <limits.h> |
| 32 #include <stdlib.h> | 32 #include <stdlib.h> |
| 33 #include <string.h> | 33 #include <string.h> |
| 34 #include <algorithm> | |
| 35 | 34 |
| 36 #include "allocation.h" | 35 #include "allocation.h" |
| 37 #include "checks.h" | 36 #include "checks.h" |
| 38 #include "globals.h" | 37 #include "globals.h" |
| 38 #include "platform.h" |
| 39 #include "vector.h" |
| 39 | 40 |
| 40 namespace v8 { | 41 namespace v8 { |
| 41 namespace internal { | 42 namespace internal { |
| 42 | 43 |
| 43 // ---------------------------------------------------------------------------- | 44 // ---------------------------------------------------------------------------- |
| 44 // General helper functions | 45 // General helper functions |
| 45 | 46 |
| 46 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) | 47 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) |
| 47 | 48 |
| 48 // Returns true iff x is a power of 2. Cannot be used with the maximally | 49 // Returns true iff x is a power of 2. Cannot be used with the maximally |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 } | 243 } |
| 243 | 244 |
| 244 | 245 |
| 245 // Returns the negative absolute value of its argument. | 246 // Returns the negative absolute value of its argument. |
| 246 template <typename T> | 247 template <typename T> |
| 247 T NegAbs(T a) { | 248 T NegAbs(T a) { |
| 248 return a < 0 ? a : -a; | 249 return a < 0 ? a : -a; |
| 249 } | 250 } |
| 250 | 251 |
| 251 | 252 |
| 252 inline int StrLength(const char* string) { | |
| 253 size_t length = strlen(string); | |
| 254 ASSERT(length == static_cast<size_t>(static_cast<int>(length))); | |
| 255 return static_cast<int>(length); | |
| 256 } | |
| 257 | |
| 258 | |
| 259 // TODO(svenpanne) Clean up the whole power-of-2 mess. | 253 // TODO(svenpanne) Clean up the whole power-of-2 mess. |
| 260 inline int32_t WhichPowerOf2Abs(int32_t x) { | 254 inline int32_t WhichPowerOf2Abs(int32_t x) { |
| 261 return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x)); | 255 return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x)); |
| 262 } | 256 } |
| 263 | 257 |
| 264 | 258 |
| 265 // ---------------------------------------------------------------------------- | 259 // ---------------------------------------------------------------------------- |
| 266 // BitField is a help template for encoding and decode bitfield with | 260 // BitField is a help template for encoding and decode bitfield with |
| 267 // unsigned content. | 261 // unsigned content. |
| 268 | 262 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 | 381 |
| 388 T* value() { return instance_; } | 382 T* value() { return instance_; } |
| 389 T* operator -> () { return instance_; } | 383 T* operator -> () { return instance_; } |
| 390 | 384 |
| 391 private: | 385 private: |
| 392 StaticResource<T>* resource_; | 386 StaticResource<T>* resource_; |
| 393 T* instance_; | 387 T* instance_; |
| 394 }; | 388 }; |
| 395 | 389 |
| 396 | 390 |
| 397 template <typename T> | |
| 398 class Vector { | |
| 399 public: | |
| 400 Vector() : start_(NULL), length_(0) {} | |
| 401 Vector(T* data, int length) : start_(data), length_(length) { | |
| 402 ASSERT(length == 0 || (length > 0 && data != NULL)); | |
| 403 } | |
| 404 | |
| 405 static Vector<T> New(int length) { | |
| 406 return Vector<T>(NewArray<T>(length), length); | |
| 407 } | |
| 408 | |
| 409 // Returns a vector using the same backing storage as this one, | |
| 410 // spanning from and including 'from', to but not including 'to'. | |
| 411 Vector<T> SubVector(int from, int to) { | |
| 412 SLOW_ASSERT(to <= length_); | |
| 413 SLOW_ASSERT(from < to); | |
| 414 ASSERT(0 <= from); | |
| 415 return Vector<T>(start() + from, to - from); | |
| 416 } | |
| 417 | |
| 418 // Returns the length of the vector. | |
| 419 int length() const { return length_; } | |
| 420 | |
| 421 // Returns whether or not the vector is empty. | |
| 422 bool is_empty() const { return length_ == 0; } | |
| 423 | |
| 424 // Returns the pointer to the start of the data in the vector. | |
| 425 T* start() const { return start_; } | |
| 426 | |
| 427 // Access individual vector elements - checks bounds in debug mode. | |
| 428 T& operator[](int index) const { | |
| 429 ASSERT(0 <= index && index < length_); | |
| 430 return start_[index]; | |
| 431 } | |
| 432 | |
| 433 const T& at(int index) const { return operator[](index); } | |
| 434 | |
| 435 T& first() { return start_[0]; } | |
| 436 | |
| 437 T& last() { return start_[length_ - 1]; } | |
| 438 | |
| 439 // Returns a clone of this vector with a new backing store. | |
| 440 Vector<T> Clone() const { | |
| 441 T* result = NewArray<T>(length_); | |
| 442 for (int i = 0; i < length_; i++) result[i] = start_[i]; | |
| 443 return Vector<T>(result, length_); | |
| 444 } | |
| 445 | |
| 446 void Sort(int (*cmp)(const T*, const T*)) { | |
| 447 std::sort(start(), start() + length(), RawComparer(cmp)); | |
| 448 } | |
| 449 | |
| 450 void Sort() { | |
| 451 std::sort(start(), start() + length()); | |
| 452 } | |
| 453 | |
| 454 void Truncate(int length) { | |
| 455 ASSERT(length <= length_); | |
| 456 length_ = length; | |
| 457 } | |
| 458 | |
| 459 // Releases the array underlying this vector. Once disposed the | |
| 460 // vector is empty. | |
| 461 void Dispose() { | |
| 462 DeleteArray(start_); | |
| 463 start_ = NULL; | |
| 464 length_ = 0; | |
| 465 } | |
| 466 | |
| 467 inline Vector<T> operator+(int offset) { | |
| 468 ASSERT(offset < length_); | |
| 469 return Vector<T>(start_ + offset, length_ - offset); | |
| 470 } | |
| 471 | |
| 472 // Factory method for creating empty vectors. | |
| 473 static Vector<T> empty() { return Vector<T>(NULL, 0); } | |
| 474 | |
| 475 template<typename S> | |
| 476 static Vector<T> cast(Vector<S> input) { | |
| 477 return Vector<T>(reinterpret_cast<T*>(input.start()), | |
| 478 input.length() * sizeof(S) / sizeof(T)); | |
| 479 } | |
| 480 | |
| 481 protected: | |
| 482 void set_start(T* start) { start_ = start; } | |
| 483 | |
| 484 private: | |
| 485 T* start_; | |
| 486 int length_; | |
| 487 | |
| 488 class RawComparer { | |
| 489 public: | |
| 490 explicit RawComparer(int (*cmp)(const T*, const T*)) : cmp_(cmp) {} | |
| 491 bool operator()(const T& a, const T& b) { | |
| 492 return cmp_(&a, &b) < 0; | |
| 493 } | |
| 494 | |
| 495 private: | |
| 496 int (*cmp_)(const T*, const T*); | |
| 497 }; | |
| 498 }; | |
| 499 | |
| 500 | |
| 501 // A pointer that can only be set once and doesn't allow NULL values. | 391 // A pointer that can only be set once and doesn't allow NULL values. |
| 502 template<typename T> | 392 template<typename T> |
| 503 class SetOncePointer { | 393 class SetOncePointer { |
| 504 public: | 394 public: |
| 505 SetOncePointer() : pointer_(NULL) { } | 395 SetOncePointer() : pointer_(NULL) { } |
| 506 | 396 |
| 507 bool is_set() const { return pointer_ != NULL; } | 397 bool is_set() const { return pointer_ != NULL; } |
| 508 | 398 |
| 509 T* get() const { | 399 T* get() const { |
| 510 ASSERT(pointer_ != NULL); | 400 ASSERT(pointer_ != NULL); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 528 | 418 |
| 529 explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) { | 419 explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) { |
| 530 for (int i = 0; i < kSize; ++i) { | 420 for (int i = 0; i < kSize; ++i) { |
| 531 buffer_[i] = initial_value; | 421 buffer_[i] = initial_value; |
| 532 } | 422 } |
| 533 } | 423 } |
| 534 | 424 |
| 535 // When copying, make underlying Vector to reference our buffer. | 425 // When copying, make underlying Vector to reference our buffer. |
| 536 EmbeddedVector(const EmbeddedVector& rhs) | 426 EmbeddedVector(const EmbeddedVector& rhs) |
| 537 : Vector<T>(rhs) { | 427 : Vector<T>(rhs) { |
| 538 // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead. | 428 OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); |
| 539 memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize); | |
| 540 set_start(buffer_); | 429 set_start(buffer_); |
| 541 } | 430 } |
| 542 | 431 |
| 543 EmbeddedVector& operator=(const EmbeddedVector& rhs) { | 432 EmbeddedVector& operator=(const EmbeddedVector& rhs) { |
| 544 if (this == &rhs) return *this; | 433 if (this == &rhs) return *this; |
| 545 Vector<T>::operator=(rhs); | 434 Vector<T>::operator=(rhs); |
| 546 // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead. | 435 OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); |
| 547 memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize); | |
| 548 this->set_start(buffer_); | 436 this->set_start(buffer_); |
| 549 return *this; | 437 return *this; |
| 550 } | 438 } |
| 551 | 439 |
| 552 private: | 440 private: |
| 553 T buffer_[kSize]; | 441 T buffer_[kSize]; |
| 554 }; | 442 }; |
| 555 | 443 |
| 556 | 444 |
| 557 template <typename T> | |
| 558 class ScopedVector : public Vector<T> { | |
| 559 public: | |
| 560 explicit ScopedVector(int length) : Vector<T>(NewArray<T>(length), length) { } | |
| 561 ~ScopedVector() { | |
| 562 DeleteArray(this->start()); | |
| 563 } | |
| 564 | |
| 565 private: | |
| 566 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedVector); | |
| 567 }; | |
| 568 | |
| 569 #define STATIC_ASCII_VECTOR(x) \ | |
| 570 v8::internal::Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(x), \ | |
| 571 ARRAY_SIZE(x)-1) | |
| 572 | |
| 573 inline Vector<const char> CStrVector(const char* data) { | |
| 574 return Vector<const char>(data, StrLength(data)); | |
| 575 } | |
| 576 | |
| 577 inline Vector<const uint8_t> OneByteVector(const char* data, int length) { | |
| 578 return Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), length); | |
| 579 } | |
| 580 | |
| 581 inline Vector<const uint8_t> OneByteVector(const char* data) { | |
| 582 return OneByteVector(data, StrLength(data)); | |
| 583 } | |
| 584 | |
| 585 inline Vector<char> MutableCStrVector(char* data) { | |
| 586 return Vector<char>(data, StrLength(data)); | |
| 587 } | |
| 588 | |
| 589 inline Vector<char> MutableCStrVector(char* data, int max) { | |
| 590 int length = StrLength(data); | |
| 591 return Vector<char>(data, (length < max) ? length : max); | |
| 592 } | |
| 593 | |
| 594 | |
| 595 /* | 445 /* |
| 596 * A class that collects values into a backing store. | 446 * A class that collects values into a backing store. |
| 597 * Specialized versions of the class can allow access to the backing store | 447 * Specialized versions of the class can allow access to the backing store |
| 598 * in different ways. | 448 * in different ways. |
| 599 * There is no guarantee that the backing store is contiguous (and, as a | 449 * There is no guarantee that the backing store is contiguous (and, as a |
| 600 * consequence, no guarantees that consecutively added elements are adjacent | 450 * consequence, no guarantees that consecutively added elements are adjacent |
| 601 * in memory). The collector may move elements unless it has guaranteed not | 451 * in memory). The collector may move elements unless it has guaranteed not |
| 602 * to. | 452 * to. |
| 603 */ | 453 */ |
| 604 template <typename T, int growth_factor = 2, int max_growth = 1 * MB> | 454 template <typename T, int growth_factor = 2, int max_growth = 1 * MB> |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 | 762 |
| 913 // We need different implementations of BitCast for pointer and non-pointer | 763 // We need different implementations of BitCast for pointer and non-pointer |
| 914 // values. We use partial specialization of auxiliary struct to work around | 764 // values. We use partial specialization of auxiliary struct to work around |
| 915 // issues with template functions overloading. | 765 // issues with template functions overloading. |
| 916 template <class Dest, class Source> | 766 template <class Dest, class Source> |
| 917 struct BitCastHelper { | 767 struct BitCastHelper { |
| 918 STATIC_ASSERT(sizeof(Dest) == sizeof(Source)); | 768 STATIC_ASSERT(sizeof(Dest) == sizeof(Source)); |
| 919 | 769 |
| 920 INLINE(static Dest cast(const Source& source)) { | 770 INLINE(static Dest cast(const Source& source)) { |
| 921 Dest dest; | 771 Dest dest; |
| 922 // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead. | 772 OS::MemCopy(&dest, &source, sizeof(dest)); |
| 923 memcpy(&dest, &source, sizeof(dest)); | |
| 924 return dest; | 773 return dest; |
| 925 } | 774 } |
| 926 }; | 775 }; |
| 927 | 776 |
| 928 template <class Dest, class Source> | 777 template <class Dest, class Source> |
| 929 struct BitCastHelper<Dest, Source*> { | 778 struct BitCastHelper<Dest, Source*> { |
| 930 INLINE(static Dest cast(Source* source)) { | 779 INLINE(static Dest cast(Source* source)) { |
| 931 return BitCastHelper<Dest, uintptr_t>:: | 780 return BitCastHelper<Dest, uintptr_t>:: |
| 932 cast(reinterpret_cast<uintptr_t>(source)); | 781 cast(reinterpret_cast<uintptr_t>(source)); |
| 933 } | 782 } |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1201 iterator end() { return container_->end(); } | 1050 iterator end() { return container_->end(); } |
| 1202 reverse_iterator rbegin() { return container_->rbegin(); } | 1051 reverse_iterator rbegin() { return container_->rbegin(); } |
| 1203 reverse_iterator rend() { return container_->rend(); } | 1052 reverse_iterator rend() { return container_->rend(); } |
| 1204 private: | 1053 private: |
| 1205 C* container_; | 1054 C* container_; |
| 1206 }; | 1055 }; |
| 1207 | 1056 |
| 1208 } } // namespace v8::internal | 1057 } } // namespace v8::internal |
| 1209 | 1058 |
| 1210 #endif // V8_UTILS_H_ | 1059 #endif // V8_UTILS_H_ |
| OLD | NEW |