| 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 |