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> |
34 | 35 |
35 #include "allocation.h" | 36 #include "allocation.h" |
36 #include "checks.h" | 37 #include "checks.h" |
37 #include "globals.h" | 38 #include "globals.h" |
38 #include "platform.h" | |
39 #include "vector.h" | |
40 | 39 |
41 namespace v8 { | 40 namespace v8 { |
42 namespace internal { | 41 namespace internal { |
43 | 42 |
44 // ---------------------------------------------------------------------------- | 43 // ---------------------------------------------------------------------------- |
45 // General helper functions | 44 // General helper functions |
46 | 45 |
47 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) | 46 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) |
48 | 47 |
49 // Returns true iff x is a power of 2. Cannot be used with the maximally | 48 // 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... |
243 } | 242 } |
244 | 243 |
245 | 244 |
246 // Returns the negative absolute value of its argument. | 245 // Returns the negative absolute value of its argument. |
247 template <typename T> | 246 template <typename T> |
248 T NegAbs(T a) { | 247 T NegAbs(T a) { |
249 return a < 0 ? a : -a; | 248 return a < 0 ? a : -a; |
250 } | 249 } |
251 | 250 |
252 | 251 |
| 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 |
253 // TODO(svenpanne) Clean up the whole power-of-2 mess. | 259 // TODO(svenpanne) Clean up the whole power-of-2 mess. |
254 inline int32_t WhichPowerOf2Abs(int32_t x) { | 260 inline int32_t WhichPowerOf2Abs(int32_t x) { |
255 return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x)); | 261 return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x)); |
256 } | 262 } |
257 | 263 |
258 | 264 |
259 // ---------------------------------------------------------------------------- | 265 // ---------------------------------------------------------------------------- |
260 // BitField is a help template for encoding and decode bitfield with | 266 // BitField is a help template for encoding and decode bitfield with |
261 // unsigned content. | 267 // unsigned content. |
262 | 268 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 | 387 |
382 T* value() { return instance_; } | 388 T* value() { return instance_; } |
383 T* operator -> () { return instance_; } | 389 T* operator -> () { return instance_; } |
384 | 390 |
385 private: | 391 private: |
386 StaticResource<T>* resource_; | 392 StaticResource<T>* resource_; |
387 T* instance_; | 393 T* instance_; |
388 }; | 394 }; |
389 | 395 |
390 | 396 |
| 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 |
391 // A pointer that can only be set once and doesn't allow NULL values. | 501 // A pointer that can only be set once and doesn't allow NULL values. |
392 template<typename T> | 502 template<typename T> |
393 class SetOncePointer { | 503 class SetOncePointer { |
394 public: | 504 public: |
395 SetOncePointer() : pointer_(NULL) { } | 505 SetOncePointer() : pointer_(NULL) { } |
396 | 506 |
397 bool is_set() const { return pointer_ != NULL; } | 507 bool is_set() const { return pointer_ != NULL; } |
398 | 508 |
399 T* get() const { | 509 T* get() const { |
400 ASSERT(pointer_ != NULL); | 510 ASSERT(pointer_ != NULL); |
(...skipping 17 matching lines...) Expand all Loading... |
418 | 528 |
419 explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) { | 529 explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) { |
420 for (int i = 0; i < kSize; ++i) { | 530 for (int i = 0; i < kSize; ++i) { |
421 buffer_[i] = initial_value; | 531 buffer_[i] = initial_value; |
422 } | 532 } |
423 } | 533 } |
424 | 534 |
425 // When copying, make underlying Vector to reference our buffer. | 535 // When copying, make underlying Vector to reference our buffer. |
426 EmbeddedVector(const EmbeddedVector& rhs) | 536 EmbeddedVector(const EmbeddedVector& rhs) |
427 : Vector<T>(rhs) { | 537 : Vector<T>(rhs) { |
428 OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); | 538 // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead. |
| 539 memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize); |
429 set_start(buffer_); | 540 set_start(buffer_); |
430 } | 541 } |
431 | 542 |
432 EmbeddedVector& operator=(const EmbeddedVector& rhs) { | 543 EmbeddedVector& operator=(const EmbeddedVector& rhs) { |
433 if (this == &rhs) return *this; | 544 if (this == &rhs) return *this; |
434 Vector<T>::operator=(rhs); | 545 Vector<T>::operator=(rhs); |
435 OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); | 546 // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead. |
| 547 memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize); |
436 this->set_start(buffer_); | 548 this->set_start(buffer_); |
437 return *this; | 549 return *this; |
438 } | 550 } |
439 | 551 |
440 private: | 552 private: |
441 T buffer_[kSize]; | 553 T buffer_[kSize]; |
442 }; | 554 }; |
443 | 555 |
444 | 556 |
| 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 |
445 /* | 595 /* |
446 * A class that collects values into a backing store. | 596 * A class that collects values into a backing store. |
447 * Specialized versions of the class can allow access to the backing store | 597 * Specialized versions of the class can allow access to the backing store |
448 * in different ways. | 598 * in different ways. |
449 * There is no guarantee that the backing store is contiguous (and, as a | 599 * There is no guarantee that the backing store is contiguous (and, as a |
450 * consequence, no guarantees that consecutively added elements are adjacent | 600 * consequence, no guarantees that consecutively added elements are adjacent |
451 * in memory). The collector may move elements unless it has guaranteed not | 601 * in memory). The collector may move elements unless it has guaranteed not |
452 * to. | 602 * to. |
453 */ | 603 */ |
454 template <typename T, int growth_factor = 2, int max_growth = 1 * MB> | 604 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... |
762 | 912 |
763 // We need different implementations of BitCast for pointer and non-pointer | 913 // We need different implementations of BitCast for pointer and non-pointer |
764 // values. We use partial specialization of auxiliary struct to work around | 914 // values. We use partial specialization of auxiliary struct to work around |
765 // issues with template functions overloading. | 915 // issues with template functions overloading. |
766 template <class Dest, class Source> | 916 template <class Dest, class Source> |
767 struct BitCastHelper { | 917 struct BitCastHelper { |
768 STATIC_ASSERT(sizeof(Dest) == sizeof(Source)); | 918 STATIC_ASSERT(sizeof(Dest) == sizeof(Source)); |
769 | 919 |
770 INLINE(static Dest cast(const Source& source)) { | 920 INLINE(static Dest cast(const Source& source)) { |
771 Dest dest; | 921 Dest dest; |
772 OS::MemCopy(&dest, &source, sizeof(dest)); | 922 // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead. |
| 923 memcpy(&dest, &source, sizeof(dest)); |
773 return dest; | 924 return dest; |
774 } | 925 } |
775 }; | 926 }; |
776 | 927 |
777 template <class Dest, class Source> | 928 template <class Dest, class Source> |
778 struct BitCastHelper<Dest, Source*> { | 929 struct BitCastHelper<Dest, Source*> { |
779 INLINE(static Dest cast(Source* source)) { | 930 INLINE(static Dest cast(Source* source)) { |
780 return BitCastHelper<Dest, uintptr_t>:: | 931 return BitCastHelper<Dest, uintptr_t>:: |
781 cast(reinterpret_cast<uintptr_t>(source)); | 932 cast(reinterpret_cast<uintptr_t>(source)); |
782 } | 933 } |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 iterator end() { return container_->end(); } | 1201 iterator end() { return container_->end(); } |
1051 reverse_iterator rbegin() { return container_->rbegin(); } | 1202 reverse_iterator rbegin() { return container_->rbegin(); } |
1052 reverse_iterator rend() { return container_->rend(); } | 1203 reverse_iterator rend() { return container_->rend(); } |
1053 private: | 1204 private: |
1054 C* container_; | 1205 C* container_; |
1055 }; | 1206 }; |
1056 | 1207 |
1057 } } // namespace v8::internal | 1208 } } // namespace v8::internal |
1058 | 1209 |
1059 #endif // V8_UTILS_H_ | 1210 #endif // V8_UTILS_H_ |
OLD | NEW |