OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_UTILS_H_ | 5 #ifndef V8_UTILS_H_ |
6 #define V8_UTILS_H_ | 6 #define V8_UTILS_H_ |
7 | 7 |
8 #include <limits.h> | 8 #include <limits.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <string.h> | 10 #include <string.h> |
11 #include <cmath> | 11 #include <cmath> |
12 | 12 |
13 #include "include/v8.h" | 13 #include "include/v8.h" |
14 #include "src/allocation.h" | 14 #include "src/allocation.h" |
15 #include "src/base/logging.h" | 15 #include "src/base/logging.h" |
16 #include "src/base/macros.h" | 16 #include "src/base/macros.h" |
17 #include "src/base/platform/platform.h" | 17 #include "src/base/platform/platform.h" |
18 #include "src/globals.h" | 18 #include "src/globals.h" |
19 #include "src/list.h" | 19 #include "src/list.h" |
20 #include "src/vector.h" | 20 #include "src/vector.h" |
21 | 21 |
22 namespace v8 { | 22 namespace v8 { |
23 namespace internal { | 23 namespace internal { |
24 | 24 |
25 // ---------------------------------------------------------------------------- | 25 // ---------------------------------------------------------------------------- |
26 // General helper functions | 26 // General helper functions |
27 | 27 |
28 // X must be a power of 2. Returns the number of trailing zeros. | 28 // X must be a power of 2. Returns the number of trailing zeros. |
29 inline int WhichPowerOf2(uint32_t x) { | 29 inline int WhichPowerOf2(uint32_t x) { |
30 ASSERT(IsPowerOf2(x)); | 30 DCHECK(IsPowerOf2(x)); |
31 int bits = 0; | 31 int bits = 0; |
32 #ifdef DEBUG | 32 #ifdef DEBUG |
33 int original_x = x; | 33 int original_x = x; |
34 #endif | 34 #endif |
35 if (x >= 0x10000) { | 35 if (x >= 0x10000) { |
36 bits += 16; | 36 bits += 16; |
37 x >>= 16; | 37 x >>= 16; |
38 } | 38 } |
39 if (x >= 0x100) { | 39 if (x >= 0x100) { |
40 bits += 8; | 40 bits += 8; |
41 x >>= 8; | 41 x >>= 8; |
42 } | 42 } |
43 if (x >= 0x10) { | 43 if (x >= 0x10) { |
44 bits += 4; | 44 bits += 4; |
45 x >>= 4; | 45 x >>= 4; |
46 } | 46 } |
47 switch (x) { | 47 switch (x) { |
48 default: UNREACHABLE(); | 48 default: UNREACHABLE(); |
49 case 8: bits++; // Fall through. | 49 case 8: bits++; // Fall through. |
50 case 4: bits++; // Fall through. | 50 case 4: bits++; // Fall through. |
51 case 2: bits++; // Fall through. | 51 case 2: bits++; // Fall through. |
52 case 1: break; | 52 case 1: break; |
53 } | 53 } |
54 ASSERT_EQ(1 << bits, original_x); | 54 DCHECK_EQ(1 << bits, original_x); |
55 return bits; | 55 return bits; |
56 return 0; | 56 return 0; |
57 } | 57 } |
58 | 58 |
59 | 59 |
60 inline int MostSignificantBit(uint32_t x) { | 60 inline int MostSignificantBit(uint32_t x) { |
61 static const int msb4[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; | 61 static const int msb4[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; |
62 int nibble = 0; | 62 int nibble = 0; |
63 if (x & 0xffff0000) { | 63 if (x & 0xffff0000) { |
64 nibble += 16; | 64 nibble += 16; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 // Value for the field with all bits set. | 194 // Value for the field with all bits set. |
195 static const T kMax = static_cast<T>((1U << size) - 1); | 195 static const T kMax = static_cast<T>((1U << size) - 1); |
196 | 196 |
197 // Tells whether the provided value fits into the bit field. | 197 // Tells whether the provided value fits into the bit field. |
198 static bool is_valid(T value) { | 198 static bool is_valid(T value) { |
199 return (static_cast<U>(value) & ~static_cast<U>(kMax)) == 0; | 199 return (static_cast<U>(value) & ~static_cast<U>(kMax)) == 0; |
200 } | 200 } |
201 | 201 |
202 // Returns a type U with the bit field value encoded. | 202 // Returns a type U with the bit field value encoded. |
203 static U encode(T value) { | 203 static U encode(T value) { |
204 ASSERT(is_valid(value)); | 204 DCHECK(is_valid(value)); |
205 return static_cast<U>(value) << shift; | 205 return static_cast<U>(value) << shift; |
206 } | 206 } |
207 | 207 |
208 // Returns a type U with the bit field value updated. | 208 // Returns a type U with the bit field value updated. |
209 static U update(U previous, T value) { | 209 static U update(U previous, T value) { |
210 return (previous & ~kMask) | encode(value); | 210 return (previous & ~kMask) | encode(value); |
211 } | 211 } |
212 | 212 |
213 // Extracts the bit field from the value. | 213 // Extracts the bit field from the value. |
214 static T decode(U value) { | 214 static T decode(U value) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 }; | 361 }; |
362 | 362 |
363 | 363 |
364 // Locally scoped access to a static resource. | 364 // Locally scoped access to a static resource. |
365 template <typename T> | 365 template <typename T> |
366 class Access { | 366 class Access { |
367 public: | 367 public: |
368 explicit Access(StaticResource<T>* resource) | 368 explicit Access(StaticResource<T>* resource) |
369 : resource_(resource) | 369 : resource_(resource) |
370 , instance_(&resource->instance_) { | 370 , instance_(&resource->instance_) { |
371 ASSERT(!resource->is_reserved_); | 371 DCHECK(!resource->is_reserved_); |
372 resource->is_reserved_ = true; | 372 resource->is_reserved_ = true; |
373 } | 373 } |
374 | 374 |
375 ~Access() { | 375 ~Access() { |
376 resource_->is_reserved_ = false; | 376 resource_->is_reserved_ = false; |
377 resource_ = NULL; | 377 resource_ = NULL; |
378 instance_ = NULL; | 378 instance_ = NULL; |
379 } | 379 } |
380 | 380 |
381 T* value() { return instance_; } | 381 T* value() { return instance_; } |
382 T* operator -> () { return instance_; } | 382 T* operator -> () { return instance_; } |
383 | 383 |
384 private: | 384 private: |
385 StaticResource<T>* resource_; | 385 StaticResource<T>* resource_; |
386 T* instance_; | 386 T* instance_; |
387 }; | 387 }; |
388 | 388 |
389 | 389 |
390 // A pointer that can only be set once and doesn't allow NULL values. | 390 // A pointer that can only be set once and doesn't allow NULL values. |
391 template<typename T> | 391 template<typename T> |
392 class SetOncePointer { | 392 class SetOncePointer { |
393 public: | 393 public: |
394 SetOncePointer() : pointer_(NULL) { } | 394 SetOncePointer() : pointer_(NULL) { } |
395 | 395 |
396 bool is_set() const { return pointer_ != NULL; } | 396 bool is_set() const { return pointer_ != NULL; } |
397 | 397 |
398 T* get() const { | 398 T* get() const { |
399 ASSERT(pointer_ != NULL); | 399 DCHECK(pointer_ != NULL); |
400 return pointer_; | 400 return pointer_; |
401 } | 401 } |
402 | 402 |
403 void set(T* value) { | 403 void set(T* value) { |
404 ASSERT(pointer_ == NULL && value != NULL); | 404 DCHECK(pointer_ == NULL && value != NULL); |
405 pointer_ = value; | 405 pointer_ = value; |
406 } | 406 } |
407 | 407 |
408 private: | 408 private: |
409 T* pointer_; | 409 T* pointer_; |
410 }; | 410 }; |
411 | 411 |
412 | 412 |
413 template <typename T, int kSize> | 413 template <typename T, int kSize> |
414 class EmbeddedVector : public Vector<T> { | 414 class EmbeddedVector : public Vector<T> { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 current_chunk_[index_] = value; | 474 current_chunk_[index_] = value; |
475 index_++; | 475 index_++; |
476 size_++; | 476 size_++; |
477 } | 477 } |
478 | 478 |
479 // Add a block of contiguous elements and return a Vector backed by the | 479 // Add a block of contiguous elements and return a Vector backed by the |
480 // memory area. | 480 // memory area. |
481 // A basic Collector will keep this vector valid as long as the Collector | 481 // A basic Collector will keep this vector valid as long as the Collector |
482 // is alive. | 482 // is alive. |
483 inline Vector<T> AddBlock(int size, T initial_value) { | 483 inline Vector<T> AddBlock(int size, T initial_value) { |
484 ASSERT(size > 0); | 484 DCHECK(size > 0); |
485 if (size > current_chunk_.length() - index_) { | 485 if (size > current_chunk_.length() - index_) { |
486 Grow(size); | 486 Grow(size); |
487 } | 487 } |
488 T* position = current_chunk_.start() + index_; | 488 T* position = current_chunk_.start() + index_; |
489 index_ += size; | 489 index_ += size; |
490 size_ += size; | 490 size_ += size; |
491 for (int i = 0; i < size; i++) { | 491 for (int i = 0; i < size; i++) { |
492 position[i] = initial_value; | 492 position[i] = initial_value; |
493 } | 493 } |
494 return Vector<T>(position, size); | 494 return Vector<T>(position, size); |
(...skipping 13 matching lines...) Expand all Loading... |
508 size_ += source.length(); | 508 size_ += source.length(); |
509 for (int i = 0; i < source.length(); i++) { | 509 for (int i = 0; i < source.length(); i++) { |
510 position[i] = source[i]; | 510 position[i] = source[i]; |
511 } | 511 } |
512 return Vector<T>(position, source.length()); | 512 return Vector<T>(position, source.length()); |
513 } | 513 } |
514 | 514 |
515 | 515 |
516 // Write the contents of the collector into the provided vector. | 516 // Write the contents of the collector into the provided vector. |
517 void WriteTo(Vector<T> destination) { | 517 void WriteTo(Vector<T> destination) { |
518 ASSERT(size_ <= destination.length()); | 518 DCHECK(size_ <= destination.length()); |
519 int position = 0; | 519 int position = 0; |
520 for (int i = 0; i < chunks_.length(); i++) { | 520 for (int i = 0; i < chunks_.length(); i++) { |
521 Vector<T> chunk = chunks_.at(i); | 521 Vector<T> chunk = chunks_.at(i); |
522 for (int j = 0; j < chunk.length(); j++) { | 522 for (int j = 0; j < chunk.length(); j++) { |
523 destination[position] = chunk[j]; | 523 destination[position] = chunk[j]; |
524 position++; | 524 position++; |
525 } | 525 } |
526 } | 526 } |
527 for (int i = 0; i < index_; i++) { | 527 for (int i = 0; i < index_; i++) { |
528 destination[position] = current_chunk_[i]; | 528 destination[position] = current_chunk_[i]; |
(...skipping 19 matching lines...) Expand all Loading... |
548 | 548 |
549 protected: | 549 protected: |
550 static const int kMinCapacity = 16; | 550 static const int kMinCapacity = 16; |
551 List<Vector<T> > chunks_; | 551 List<Vector<T> > chunks_; |
552 Vector<T> current_chunk_; // Block of memory currently being written into. | 552 Vector<T> current_chunk_; // Block of memory currently being written into. |
553 int index_; // Current index in current chunk. | 553 int index_; // Current index in current chunk. |
554 int size_; // Total number of elements in collector. | 554 int size_; // Total number of elements in collector. |
555 | 555 |
556 // Creates a new current chunk, and stores the old chunk in the chunks_ list. | 556 // Creates a new current chunk, and stores the old chunk in the chunks_ list. |
557 void Grow(int min_capacity) { | 557 void Grow(int min_capacity) { |
558 ASSERT(growth_factor > 1); | 558 DCHECK(growth_factor > 1); |
559 int new_capacity; | 559 int new_capacity; |
560 int current_length = current_chunk_.length(); | 560 int current_length = current_chunk_.length(); |
561 if (current_length < kMinCapacity) { | 561 if (current_length < kMinCapacity) { |
562 // The collector started out as empty. | 562 // The collector started out as empty. |
563 new_capacity = min_capacity * growth_factor; | 563 new_capacity = min_capacity * growth_factor; |
564 if (new_capacity < kMinCapacity) new_capacity = kMinCapacity; | 564 if (new_capacity < kMinCapacity) new_capacity = kMinCapacity; |
565 } else { | 565 } else { |
566 int growth = current_length * (growth_factor - 1); | 566 int growth = current_length * (growth_factor - 1); |
567 if (growth > max_growth) { | 567 if (growth > max_growth) { |
568 growth = max_growth; | 568 growth = max_growth; |
569 } | 569 } |
570 new_capacity = current_length + growth; | 570 new_capacity = current_length + growth; |
571 if (new_capacity < min_capacity) { | 571 if (new_capacity < min_capacity) { |
572 new_capacity = min_capacity + growth; | 572 new_capacity = min_capacity + growth; |
573 } | 573 } |
574 } | 574 } |
575 NewChunk(new_capacity); | 575 NewChunk(new_capacity); |
576 ASSERT(index_ + min_capacity <= current_chunk_.length()); | 576 DCHECK(index_ + min_capacity <= current_chunk_.length()); |
577 } | 577 } |
578 | 578 |
579 // Before replacing the current chunk, give a subclass the option to move | 579 // Before replacing the current chunk, give a subclass the option to move |
580 // some of the current data into the new chunk. The function may update | 580 // some of the current data into the new chunk. The function may update |
581 // the current index_ value to represent data no longer in the current chunk. | 581 // the current index_ value to represent data no longer in the current chunk. |
582 // Returns the initial index of the new chunk (after copied data). | 582 // Returns the initial index of the new chunk (after copied data). |
583 virtual void NewChunk(int new_capacity) { | 583 virtual void NewChunk(int new_capacity) { |
584 Vector<T> new_chunk = Vector<T>::New(new_capacity); | 584 Vector<T> new_chunk = Vector<T>::New(new_capacity); |
585 if (index_ > 0) { | 585 if (index_ > 0) { |
586 chunks_.Add(current_chunk_.SubVector(0, index_)); | 586 chunks_.Add(current_chunk_.SubVector(0, index_)); |
(...skipping 18 matching lines...) Expand all Loading... |
605 template <typename T, int growth_factor = 2, int max_growth = 1 * MB> | 605 template <typename T, int growth_factor = 2, int max_growth = 1 * MB> |
606 class SequenceCollector : public Collector<T, growth_factor, max_growth> { | 606 class SequenceCollector : public Collector<T, growth_factor, max_growth> { |
607 public: | 607 public: |
608 explicit SequenceCollector(int initial_capacity) | 608 explicit SequenceCollector(int initial_capacity) |
609 : Collector<T, growth_factor, max_growth>(initial_capacity), | 609 : Collector<T, growth_factor, max_growth>(initial_capacity), |
610 sequence_start_(kNoSequence) { } | 610 sequence_start_(kNoSequence) { } |
611 | 611 |
612 virtual ~SequenceCollector() {} | 612 virtual ~SequenceCollector() {} |
613 | 613 |
614 void StartSequence() { | 614 void StartSequence() { |
615 ASSERT(sequence_start_ == kNoSequence); | 615 DCHECK(sequence_start_ == kNoSequence); |
616 sequence_start_ = this->index_; | 616 sequence_start_ = this->index_; |
617 } | 617 } |
618 | 618 |
619 Vector<T> EndSequence() { | 619 Vector<T> EndSequence() { |
620 ASSERT(sequence_start_ != kNoSequence); | 620 DCHECK(sequence_start_ != kNoSequence); |
621 int sequence_start = sequence_start_; | 621 int sequence_start = sequence_start_; |
622 sequence_start_ = kNoSequence; | 622 sequence_start_ = kNoSequence; |
623 if (sequence_start == this->index_) return Vector<T>(); | 623 if (sequence_start == this->index_) return Vector<T>(); |
624 return this->current_chunk_.SubVector(sequence_start, this->index_); | 624 return this->current_chunk_.SubVector(sequence_start, this->index_); |
625 } | 625 } |
626 | 626 |
627 // Drops the currently added sequence, and all collected elements in it. | 627 // Drops the currently added sequence, and all collected elements in it. |
628 void DropSequence() { | 628 void DropSequence() { |
629 ASSERT(sequence_start_ != kNoSequence); | 629 DCHECK(sequence_start_ != kNoSequence); |
630 int sequence_length = this->index_ - sequence_start_; | 630 int sequence_length = this->index_ - sequence_start_; |
631 this->index_ = sequence_start_; | 631 this->index_ = sequence_start_; |
632 this->size_ -= sequence_length; | 632 this->size_ -= sequence_length; |
633 sequence_start_ = kNoSequence; | 633 sequence_start_ = kNoSequence; |
634 } | 634 } |
635 | 635 |
636 virtual void Reset() { | 636 virtual void Reset() { |
637 sequence_start_ = kNoSequence; | 637 sequence_start_ = kNoSequence; |
638 this->Collector<T, growth_factor, max_growth>::Reset(); | 638 this->Collector<T, growth_factor, max_growth>::Reset(); |
639 } | 639 } |
640 | 640 |
641 private: | 641 private: |
642 static const int kNoSequence = -1; | 642 static const int kNoSequence = -1; |
643 int sequence_start_; | 643 int sequence_start_; |
644 | 644 |
645 // Move the currently active sequence to the new chunk. | 645 // Move the currently active sequence to the new chunk. |
646 virtual void NewChunk(int new_capacity) { | 646 virtual void NewChunk(int new_capacity) { |
647 if (sequence_start_ == kNoSequence) { | 647 if (sequence_start_ == kNoSequence) { |
648 // Fall back on default behavior if no sequence has been started. | 648 // Fall back on default behavior if no sequence has been started. |
649 this->Collector<T, growth_factor, max_growth>::NewChunk(new_capacity); | 649 this->Collector<T, growth_factor, max_growth>::NewChunk(new_capacity); |
650 return; | 650 return; |
651 } | 651 } |
652 int sequence_length = this->index_ - sequence_start_; | 652 int sequence_length = this->index_ - sequence_start_; |
653 Vector<T> new_chunk = Vector<T>::New(sequence_length + new_capacity); | 653 Vector<T> new_chunk = Vector<T>::New(sequence_length + new_capacity); |
654 ASSERT(sequence_length < new_chunk.length()); | 654 DCHECK(sequence_length < new_chunk.length()); |
655 for (int i = 0; i < sequence_length; i++) { | 655 for (int i = 0; i < sequence_length; i++) { |
656 new_chunk[i] = this->current_chunk_[sequence_start_ + i]; | 656 new_chunk[i] = this->current_chunk_[sequence_start_ + i]; |
657 } | 657 } |
658 if (sequence_start_ > 0) { | 658 if (sequence_start_ > 0) { |
659 this->chunks_.Add(this->current_chunk_.SubVector(0, sequence_start_)); | 659 this->chunks_.Add(this->current_chunk_.SubVector(0, sequence_start_)); |
660 } else { | 660 } else { |
661 this->current_chunk_.Dispose(); | 661 this->current_chunk_.Dispose(); |
662 } | 662 } |
663 this->current_chunk_ = new_chunk; | 663 this->current_chunk_ = new_chunk; |
664 this->index_ = sequence_length; | 664 this->index_ = sequence_length; |
(...skipping 26 matching lines...) Expand all Loading... |
691 int r = static_cast<int>(*lhs) - static_cast<int>(*rhs); | 691 int r = static_cast<int>(*lhs) - static_cast<int>(*rhs); |
692 if (r != 0) return r; | 692 if (r != 0) return r; |
693 ++lhs; | 693 ++lhs; |
694 ++rhs; | 694 ++rhs; |
695 } | 695 } |
696 return 0; | 696 return 0; |
697 } | 697 } |
698 | 698 |
699 template<typename lchar, typename rchar> | 699 template<typename lchar, typename rchar> |
700 inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) { | 700 inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) { |
701 ASSERT(sizeof(lchar) <= 2); | 701 DCHECK(sizeof(lchar) <= 2); |
702 ASSERT(sizeof(rchar) <= 2); | 702 DCHECK(sizeof(rchar) <= 2); |
703 if (sizeof(lchar) == 1) { | 703 if (sizeof(lchar) == 1) { |
704 if (sizeof(rchar) == 1) { | 704 if (sizeof(rchar) == 1) { |
705 return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs), | 705 return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs), |
706 reinterpret_cast<const uint8_t*>(rhs), | 706 reinterpret_cast<const uint8_t*>(rhs), |
707 chars); | 707 chars); |
708 } else { | 708 } else { |
709 return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs), | 709 return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs), |
710 reinterpret_cast<const uint16_t*>(rhs), | 710 reinterpret_cast<const uint16_t*>(rhs), |
711 chars); | 711 chars); |
712 } | 712 } |
713 } else { | 713 } else { |
714 if (sizeof(rchar) == 1) { | 714 if (sizeof(rchar) == 1) { |
715 return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs), | 715 return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs), |
716 reinterpret_cast<const uint8_t*>(rhs), | 716 reinterpret_cast<const uint8_t*>(rhs), |
717 chars); | 717 chars); |
718 } else { | 718 } else { |
719 return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs), | 719 return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs), |
720 reinterpret_cast<const uint16_t*>(rhs), | 720 reinterpret_cast<const uint16_t*>(rhs), |
721 chars); | 721 chars); |
722 } | 722 } |
723 } | 723 } |
724 } | 724 } |
725 | 725 |
726 | 726 |
727 // Calculate 10^exponent. | 727 // Calculate 10^exponent. |
728 inline int TenToThe(int exponent) { | 728 inline int TenToThe(int exponent) { |
729 ASSERT(exponent <= 9); | 729 DCHECK(exponent <= 9); |
730 ASSERT(exponent >= 1); | 730 DCHECK(exponent >= 1); |
731 int answer = 10; | 731 int answer = 10; |
732 for (int i = 1; i < exponent; i++) answer *= 10; | 732 for (int i = 1; i < exponent; i++) answer *= 10; |
733 return answer; | 733 return answer; |
734 } | 734 } |
735 | 735 |
736 | 736 |
737 // The type-based aliasing rule allows the compiler to assume that pointers of | 737 // The type-based aliasing rule allows the compiler to assume that pointers of |
738 // different types (for some definition of different) never alias each other. | 738 // different types (for some definition of different) never alias each other. |
739 // Thus the following code does not work: | 739 // Thus the following code does not work: |
740 // | 740 // |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 } | 790 } |
791 | 791 |
792 | 792 |
793 template<typename ElementType, int NumElements> | 793 template<typename ElementType, int NumElements> |
794 class EmbeddedContainer { | 794 class EmbeddedContainer { |
795 public: | 795 public: |
796 EmbeddedContainer() : elems_() { } | 796 EmbeddedContainer() : elems_() { } |
797 | 797 |
798 int length() const { return NumElements; } | 798 int length() const { return NumElements; } |
799 const ElementType& operator[](int i) const { | 799 const ElementType& operator[](int i) const { |
800 ASSERT(i < length()); | 800 DCHECK(i < length()); |
801 return elems_[i]; | 801 return elems_[i]; |
802 } | 802 } |
803 ElementType& operator[](int i) { | 803 ElementType& operator[](int i) { |
804 ASSERT(i < length()); | 804 DCHECK(i < length()); |
805 return elems_[i]; | 805 return elems_[i]; |
806 } | 806 } |
807 | 807 |
808 private: | 808 private: |
809 ElementType elems_[NumElements]; | 809 ElementType elems_[NumElements]; |
810 }; | 810 }; |
811 | 811 |
812 | 812 |
813 template<typename ElementType> | 813 template<typename ElementType> |
814 class EmbeddedContainer<ElementType, 0> { | 814 class EmbeddedContainer<ElementType, 0> { |
(...skipping 25 matching lines...) Expand all Loading... |
840 | 840 |
841 SimpleStringBuilder(char* buffer, int size) | 841 SimpleStringBuilder(char* buffer, int size) |
842 : buffer_(buffer, size), position_(0) { } | 842 : buffer_(buffer, size), position_(0) { } |
843 | 843 |
844 ~SimpleStringBuilder() { if (!is_finalized()) Finalize(); } | 844 ~SimpleStringBuilder() { if (!is_finalized()) Finalize(); } |
845 | 845 |
846 int size() const { return buffer_.length(); } | 846 int size() const { return buffer_.length(); } |
847 | 847 |
848 // Get the current position in the builder. | 848 // Get the current position in the builder. |
849 int position() const { | 849 int position() const { |
850 ASSERT(!is_finalized()); | 850 DCHECK(!is_finalized()); |
851 return position_; | 851 return position_; |
852 } | 852 } |
853 | 853 |
854 // Reset the position. | 854 // Reset the position. |
855 void Reset() { position_ = 0; } | 855 void Reset() { position_ = 0; } |
856 | 856 |
857 // Add a single character to the builder. It is not allowed to add | 857 // Add a single character to the builder. It is not allowed to add |
858 // 0-characters; use the Finalize() method to terminate the string | 858 // 0-characters; use the Finalize() method to terminate the string |
859 // instead. | 859 // instead. |
860 void AddCharacter(char c) { | 860 void AddCharacter(char c) { |
861 ASSERT(c != '\0'); | 861 DCHECK(c != '\0'); |
862 ASSERT(!is_finalized() && position_ < buffer_.length()); | 862 DCHECK(!is_finalized() && position_ < buffer_.length()); |
863 buffer_[position_++] = c; | 863 buffer_[position_++] = c; |
864 } | 864 } |
865 | 865 |
866 // Add an entire string to the builder. Uses strlen() internally to | 866 // Add an entire string to the builder. Uses strlen() internally to |
867 // compute the length of the input string. | 867 // compute the length of the input string. |
868 void AddString(const char* s); | 868 void AddString(const char* s); |
869 | 869 |
870 // Add the first 'n' characters of the given string 's' to the | 870 // Add the first 'n' characters of the given string 's' to the |
871 // builder. The input string must have enough characters. | 871 // builder. The input string must have enough characters. |
872 void AddSubstring(const char* s, int n); | 872 void AddSubstring(const char* s, int n); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 void Intersect(const EnumSet& set) { bits_ &= set.bits_; } | 911 void Intersect(const EnumSet& set) { bits_ &= set.bits_; } |
912 T ToIntegral() const { return bits_; } | 912 T ToIntegral() const { return bits_; } |
913 bool operator==(const EnumSet& set) { return bits_ == set.bits_; } | 913 bool operator==(const EnumSet& set) { return bits_ == set.bits_; } |
914 bool operator!=(const EnumSet& set) { return bits_ != set.bits_; } | 914 bool operator!=(const EnumSet& set) { return bits_ != set.bits_; } |
915 EnumSet<E, T> operator|(const EnumSet& set) const { | 915 EnumSet<E, T> operator|(const EnumSet& set) const { |
916 return EnumSet<E, T>(bits_ | set.bits_); | 916 return EnumSet<E, T>(bits_ | set.bits_); |
917 } | 917 } |
918 | 918 |
919 private: | 919 private: |
920 T Mask(E element) const { | 920 T Mask(E element) const { |
921 // The strange typing in ASSERT is necessary to avoid stupid warnings, see: | 921 // The strange typing in DCHECK is necessary to avoid stupid warnings, see: |
922 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680 | 922 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680 |
923 ASSERT(static_cast<int>(element) < static_cast<int>(sizeof(T) * CHAR_BIT)); | 923 DCHECK(static_cast<int>(element) < static_cast<int>(sizeof(T) * CHAR_BIT)); |
924 return static_cast<T>(1) << element; | 924 return static_cast<T>(1) << element; |
925 } | 925 } |
926 | 926 |
927 T bits_; | 927 T bits_; |
928 }; | 928 }; |
929 | 929 |
930 // Bit field extraction. | 930 // Bit field extraction. |
931 inline uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x) { | 931 inline uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x) { |
932 return (x >> lsb) & ((1 << (1 + msb - lsb)) - 1); | 932 return (x >> lsb) & ((1 << (1 + msb - lsb)) - 1); |
933 } | 933 } |
934 | 934 |
935 inline uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x) { | 935 inline uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x) { |
936 return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1); | 936 return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1); |
937 } | 937 } |
938 | 938 |
939 inline int32_t signed_bitextract_32(int msb, int lsb, int32_t x) { | 939 inline int32_t signed_bitextract_32(int msb, int lsb, int32_t x) { |
940 return (x << (31 - msb)) >> (lsb + 31 - msb); | 940 return (x << (31 - msb)) >> (lsb + 31 - msb); |
941 } | 941 } |
942 | 942 |
943 inline int signed_bitextract_64(int msb, int lsb, int x) { | 943 inline int signed_bitextract_64(int msb, int lsb, int x) { |
944 // TODO(jbramley): This is broken for big bitfields. | 944 // TODO(jbramley): This is broken for big bitfields. |
945 return (x << (63 - msb)) >> (lsb + 63 - msb); | 945 return (x << (63 - msb)) >> (lsb + 63 - msb); |
946 } | 946 } |
947 | 947 |
948 // Check number width. | 948 // Check number width. |
949 inline bool is_intn(int64_t x, unsigned n) { | 949 inline bool is_intn(int64_t x, unsigned n) { |
950 ASSERT((0 < n) && (n < 64)); | 950 DCHECK((0 < n) && (n < 64)); |
951 int64_t limit = static_cast<int64_t>(1) << (n - 1); | 951 int64_t limit = static_cast<int64_t>(1) << (n - 1); |
952 return (-limit <= x) && (x < limit); | 952 return (-limit <= x) && (x < limit); |
953 } | 953 } |
954 | 954 |
955 inline bool is_uintn(int64_t x, unsigned n) { | 955 inline bool is_uintn(int64_t x, unsigned n) { |
956 ASSERT((0 < n) && (n < (sizeof(x) * kBitsPerByte))); | 956 DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte))); |
957 return !(x >> n); | 957 return !(x >> n); |
958 } | 958 } |
959 | 959 |
960 template <class T> | 960 template <class T> |
961 inline T truncate_to_intn(T x, unsigned n) { | 961 inline T truncate_to_intn(T x, unsigned n) { |
962 ASSERT((0 < n) && (n < (sizeof(x) * kBitsPerByte))); | 962 DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte))); |
963 return (x & ((static_cast<T>(1) << n) - 1)); | 963 return (x & ((static_cast<T>(1) << n) - 1)); |
964 } | 964 } |
965 | 965 |
966 #define INT_1_TO_63_LIST(V) \ | 966 #define INT_1_TO_63_LIST(V) \ |
967 V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) \ | 967 V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) \ |
968 V(9) V(10) V(11) V(12) V(13) V(14) V(15) V(16) \ | 968 V(9) V(10) V(11) V(12) V(13) V(14) V(15) V(16) \ |
969 V(17) V(18) V(19) V(20) V(21) V(22) V(23) V(24) \ | 969 V(17) V(18) V(19) V(20) V(21) V(22) V(23) V(24) \ |
970 V(25) V(26) V(27) V(28) V(29) V(30) V(31) V(32) \ | 970 V(25) V(26) V(27) V(28) V(29) V(30) V(31) V(32) \ |
971 V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40) \ | 971 V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40) \ |
972 V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) \ | 972 V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) \ |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 // ---------------------------------------------------------------------------- | 1158 // ---------------------------------------------------------------------------- |
1159 // Memory | 1159 // Memory |
1160 | 1160 |
1161 // Copies words from |src| to |dst|. The data spans must not overlap. | 1161 // Copies words from |src| to |dst|. The data spans must not overlap. |
1162 template <typename T> | 1162 template <typename T> |
1163 inline void CopyWords(T* dst, const T* src, size_t num_words) { | 1163 inline void CopyWords(T* dst, const T* src, size_t num_words) { |
1164 STATIC_ASSERT(sizeof(T) == kPointerSize); | 1164 STATIC_ASSERT(sizeof(T) == kPointerSize); |
1165 // TODO(mvstanton): disabled because mac builds are bogus failing on this | 1165 // TODO(mvstanton): disabled because mac builds are bogus failing on this |
1166 // assert. They are doing a signed comparison. Investigate in | 1166 // assert. They are doing a signed comparison. Investigate in |
1167 // the morning. | 1167 // the morning. |
1168 // ASSERT(Min(dst, const_cast<T*>(src)) + num_words <= | 1168 // DCHECK(Min(dst, const_cast<T*>(src)) + num_words <= |
1169 // Max(dst, const_cast<T*>(src))); | 1169 // Max(dst, const_cast<T*>(src))); |
1170 ASSERT(num_words > 0); | 1170 DCHECK(num_words > 0); |
1171 | 1171 |
1172 // Use block copying MemCopy if the segment we're copying is | 1172 // Use block copying MemCopy if the segment we're copying is |
1173 // enough to justify the extra call/setup overhead. | 1173 // enough to justify the extra call/setup overhead. |
1174 static const size_t kBlockCopyLimit = 16; | 1174 static const size_t kBlockCopyLimit = 16; |
1175 | 1175 |
1176 if (num_words < kBlockCopyLimit) { | 1176 if (num_words < kBlockCopyLimit) { |
1177 do { | 1177 do { |
1178 num_words--; | 1178 num_words--; |
1179 *dst++ = *src++; | 1179 *dst++ = *src++; |
1180 } while (num_words > 0); | 1180 } while (num_words > 0); |
1181 } else { | 1181 } else { |
1182 MemCopy(dst, src, num_words * kPointerSize); | 1182 MemCopy(dst, src, num_words * kPointerSize); |
1183 } | 1183 } |
1184 } | 1184 } |
1185 | 1185 |
1186 | 1186 |
1187 // Copies words from |src| to |dst|. No restrictions. | 1187 // Copies words from |src| to |dst|. No restrictions. |
1188 template <typename T> | 1188 template <typename T> |
1189 inline void MoveWords(T* dst, const T* src, size_t num_words) { | 1189 inline void MoveWords(T* dst, const T* src, size_t num_words) { |
1190 STATIC_ASSERT(sizeof(T) == kPointerSize); | 1190 STATIC_ASSERT(sizeof(T) == kPointerSize); |
1191 ASSERT(num_words > 0); | 1191 DCHECK(num_words > 0); |
1192 | 1192 |
1193 // Use block copying MemCopy if the segment we're copying is | 1193 // Use block copying MemCopy if the segment we're copying is |
1194 // enough to justify the extra call/setup overhead. | 1194 // enough to justify the extra call/setup overhead. |
1195 static const size_t kBlockCopyLimit = 16; | 1195 static const size_t kBlockCopyLimit = 16; |
1196 | 1196 |
1197 if (num_words < kBlockCopyLimit && | 1197 if (num_words < kBlockCopyLimit && |
1198 ((dst < src) || (dst >= (src + num_words * kPointerSize)))) { | 1198 ((dst < src) || (dst >= (src + num_words * kPointerSize)))) { |
1199 T* end = dst + num_words; | 1199 T* end = dst + num_words; |
1200 do { | 1200 do { |
1201 num_words--; | 1201 num_words--; |
1202 *dst++ = *src++; | 1202 *dst++ = *src++; |
1203 } while (num_words > 0); | 1203 } while (num_words > 0); |
1204 } else { | 1204 } else { |
1205 MemMove(dst, src, num_words * kPointerSize); | 1205 MemMove(dst, src, num_words * kPointerSize); |
1206 } | 1206 } |
1207 } | 1207 } |
1208 | 1208 |
1209 | 1209 |
1210 // Copies data from |src| to |dst|. The data spans must not overlap. | 1210 // Copies data from |src| to |dst|. The data spans must not overlap. |
1211 template <typename T> | 1211 template <typename T> |
1212 inline void CopyBytes(T* dst, const T* src, size_t num_bytes) { | 1212 inline void CopyBytes(T* dst, const T* src, size_t num_bytes) { |
1213 STATIC_ASSERT(sizeof(T) == 1); | 1213 STATIC_ASSERT(sizeof(T) == 1); |
1214 ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <= | 1214 DCHECK(Min(dst, const_cast<T*>(src)) + num_bytes <= |
1215 Max(dst, const_cast<T*>(src))); | 1215 Max(dst, const_cast<T*>(src))); |
1216 if (num_bytes == 0) return; | 1216 if (num_bytes == 0) return; |
1217 | 1217 |
1218 // Use block copying MemCopy if the segment we're copying is | 1218 // Use block copying MemCopy if the segment we're copying is |
1219 // enough to justify the extra call/setup overhead. | 1219 // enough to justify the extra call/setup overhead. |
1220 static const int kBlockCopyLimit = kMinComplexMemCopy; | 1220 static const int kBlockCopyLimit = kMinComplexMemCopy; |
1221 | 1221 |
1222 if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) { | 1222 if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) { |
1223 do { | 1223 do { |
1224 num_bytes--; | 1224 num_bytes--; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars)); | 1315 INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars)); |
1316 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars)); | 1316 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars)); |
1317 #endif | 1317 #endif |
1318 | 1318 |
1319 // Copy from ASCII/16bit chars to ASCII/16bit chars. | 1319 // Copy from ASCII/16bit chars to ASCII/16bit chars. |
1320 template <typename sourcechar, typename sinkchar> | 1320 template <typename sourcechar, typename sinkchar> |
1321 INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars)); | 1321 INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars)); |
1322 | 1322 |
1323 template<typename sourcechar, typename sinkchar> | 1323 template<typename sourcechar, typename sinkchar> |
1324 void CopyChars(sinkchar* dest, const sourcechar* src, int chars) { | 1324 void CopyChars(sinkchar* dest, const sourcechar* src, int chars) { |
1325 ASSERT(sizeof(sourcechar) <= 2); | 1325 DCHECK(sizeof(sourcechar) <= 2); |
1326 ASSERT(sizeof(sinkchar) <= 2); | 1326 DCHECK(sizeof(sinkchar) <= 2); |
1327 if (sizeof(sinkchar) == 1) { | 1327 if (sizeof(sinkchar) == 1) { |
1328 if (sizeof(sourcechar) == 1) { | 1328 if (sizeof(sourcechar) == 1) { |
1329 CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest), | 1329 CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest), |
1330 reinterpret_cast<const uint8_t*>(src), | 1330 reinterpret_cast<const uint8_t*>(src), |
1331 chars); | 1331 chars); |
1332 } else { | 1332 } else { |
1333 CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest), | 1333 CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest), |
1334 reinterpret_cast<const uint16_t*>(src), | 1334 reinterpret_cast<const uint16_t*>(src), |
1335 chars); | 1335 chars); |
1336 } | 1336 } |
(...skipping 14 matching lines...) Expand all Loading... |
1351 void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) { | 1351 void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) { |
1352 sinkchar* limit = dest + chars; | 1352 sinkchar* limit = dest + chars; |
1353 #ifdef V8_HOST_CAN_READ_UNALIGNED | 1353 #ifdef V8_HOST_CAN_READ_UNALIGNED |
1354 if (sizeof(*dest) == sizeof(*src)) { | 1354 if (sizeof(*dest) == sizeof(*src)) { |
1355 if (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest))) { | 1355 if (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest))) { |
1356 MemCopy(dest, src, chars * sizeof(*dest)); | 1356 MemCopy(dest, src, chars * sizeof(*dest)); |
1357 return; | 1357 return; |
1358 } | 1358 } |
1359 // Number of characters in a uintptr_t. | 1359 // Number of characters in a uintptr_t. |
1360 static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT | 1360 static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT |
1361 ASSERT(dest + kStepSize > dest); // Check for overflow. | 1361 DCHECK(dest + kStepSize > dest); // Check for overflow. |
1362 while (dest + kStepSize <= limit) { | 1362 while (dest + kStepSize <= limit) { |
1363 *reinterpret_cast<uintptr_t*>(dest) = | 1363 *reinterpret_cast<uintptr_t*>(dest) = |
1364 *reinterpret_cast<const uintptr_t*>(src); | 1364 *reinterpret_cast<const uintptr_t*>(src); |
1365 dest += kStepSize; | 1365 dest += kStepSize; |
1366 src += kStepSize; | 1366 src += kStepSize; |
1367 } | 1367 } |
1368 } | 1368 } |
1369 #endif | 1369 #endif |
1370 while (dest < limit) { | 1370 while (dest < limit) { |
1371 *dest++ = static_cast<sinkchar>(*src++); | 1371 *dest++ = static_cast<sinkchar>(*src++); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1531 } | 1531 } |
1532 | 1532 |
1533 *index = result; | 1533 *index = result; |
1534 return true; | 1534 return true; |
1535 } | 1535 } |
1536 | 1536 |
1537 | 1537 |
1538 } } // namespace v8::internal | 1538 } } // namespace v8::internal |
1539 | 1539 |
1540 #endif // V8_UTILS_H_ | 1540 #endif // V8_UTILS_H_ |
OLD | NEW |