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 |