OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 5908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5919 | 5919 |
5920 bool String::SlowEquals(String* other) { | 5920 bool String::SlowEquals(String* other) { |
5921 // Fast check: negative check with lengths. | 5921 // Fast check: negative check with lengths. |
5922 int len = length(); | 5922 int len = length(); |
5923 if (len != other->length()) return false; | 5923 if (len != other->length()) return false; |
5924 if (len == 0) return true; | 5924 if (len == 0) return true; |
5925 | 5925 |
5926 // Fast check: if hash code is computed for both strings | 5926 // Fast check: if hash code is computed for both strings |
5927 // a fast negative check can be performed. | 5927 // a fast negative check can be performed. |
5928 if (HasHashCode() && other->HasHashCode()) { | 5928 if (HasHashCode() && other->HasHashCode()) { |
| 5929 #ifdef DEBUG |
| 5930 if (FLAG_enable_slow_asserts) { |
| 5931 if (Hash() != other->Hash()) { |
| 5932 bool found_difference = false; |
| 5933 for (int i = 0; i < len; i++) { |
| 5934 if (Get(i) != other->Get(i)) { |
| 5935 found_difference = true; |
| 5936 break; |
| 5937 } |
| 5938 } |
| 5939 ASSERT(found_difference); |
| 5940 } |
| 5941 } |
| 5942 #endif |
5929 if (Hash() != other->Hash()) return false; | 5943 if (Hash() != other->Hash()) return false; |
5930 } | 5944 } |
5931 | 5945 |
5932 // We know the strings are both non-empty. Compare the first chars | 5946 // We know the strings are both non-empty. Compare the first chars |
5933 // before we try to flatten the strings. | 5947 // before we try to flatten the strings. |
5934 if (this->Get(0) != other->Get(0)) return false; | 5948 if (this->Get(0) != other->Get(0)) return false; |
5935 | 5949 |
5936 String* lhs = this->TryFlattenGetString(); | 5950 String* lhs = this->TryFlattenGetString(); |
5937 String* rhs = other->TryFlattenGetString(); | 5951 String* rhs = other->TryFlattenGetString(); |
5938 | 5952 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6054 | 6068 |
6055 uint32_t String::ComputeAndSetHash() { | 6069 uint32_t String::ComputeAndSetHash() { |
6056 // Should only be called if hash code has not yet been computed. | 6070 // Should only be called if hash code has not yet been computed. |
6057 ASSERT(!HasHashCode()); | 6071 ASSERT(!HasHashCode()); |
6058 | 6072 |
6059 const int len = length(); | 6073 const int len = length(); |
6060 | 6074 |
6061 // Compute the hash code. | 6075 // Compute the hash code. |
6062 uint32_t field = 0; | 6076 uint32_t field = 0; |
6063 if (StringShape(this).IsSequentialAscii()) { | 6077 if (StringShape(this).IsSequentialAscii()) { |
6064 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len); | 6078 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), |
| 6079 len, |
| 6080 GetHeap()->StringHashSeed()); |
6065 } else if (StringShape(this).IsSequentialTwoByte()) { | 6081 } else if (StringShape(this).IsSequentialTwoByte()) { |
6066 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), len); | 6082 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), |
| 6083 len, |
| 6084 GetHeap()->StringHashSeed()); |
6067 } else { | 6085 } else { |
6068 StringInputBuffer buffer(this); | 6086 StringInputBuffer buffer(this); |
6069 field = ComputeHashField(&buffer, len); | 6087 field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed()); |
6070 } | 6088 } |
6071 | 6089 |
6072 // Store the hash code in the object. | 6090 // Store the hash code in the object. |
6073 set_hash_field(field); | 6091 set_hash_field(field); |
6074 | 6092 |
6075 // Check the hash code is there. | 6093 // Check the hash code is there. |
6076 ASSERT(HasHashCode()); | 6094 ASSERT(HasHashCode()); |
6077 uint32_t result = field >> kHashShift; | 6095 uint32_t result = field >> kHashShift; |
6078 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 6096 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
6079 return result; | 6097 return result; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6150 return MakeArrayIndexHash(array_index(), length_); | 6168 return MakeArrayIndexHash(array_index(), length_); |
6151 } | 6169 } |
6152 return (GetHash() << String::kHashShift) | String::kIsNotArrayIndexMask; | 6170 return (GetHash() << String::kHashShift) | String::kIsNotArrayIndexMask; |
6153 } else { | 6171 } else { |
6154 return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask; | 6172 return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask; |
6155 } | 6173 } |
6156 } | 6174 } |
6157 | 6175 |
6158 | 6176 |
6159 uint32_t String::ComputeHashField(unibrow::CharacterStream* buffer, | 6177 uint32_t String::ComputeHashField(unibrow::CharacterStream* buffer, |
6160 int length) { | 6178 int length, |
6161 StringHasher hasher(length); | 6179 uint32_t seed) { |
| 6180 StringHasher hasher(length, seed); |
6162 | 6181 |
6163 // Very long strings have a trivial hash that doesn't inspect the | 6182 // Very long strings have a trivial hash that doesn't inspect the |
6164 // string contents. | 6183 // string contents. |
6165 if (hasher.has_trivial_hash()) { | 6184 if (hasher.has_trivial_hash()) { |
6166 return hasher.GetHashField(); | 6185 return hasher.GetHashField(); |
6167 } | 6186 } |
6168 | 6187 |
6169 // Do the iterative array index computation as long as there is a | 6188 // Do the iterative array index computation as long as there is a |
6170 // chance this is an array index. | 6189 // chance this is an array index. |
6171 while (buffer->has_more() && hasher.is_array_index()) { | 6190 while (buffer->has_more() && hasher.is_array_index()) { |
(...skipping 3363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9535 return string->Hash() + flags->value(); | 9554 return string->Hash() + flags->value(); |
9536 } | 9555 } |
9537 | 9556 |
9538 String* string_; | 9557 String* string_; |
9539 Smi* flags_; | 9558 Smi* flags_; |
9540 }; | 9559 }; |
9541 | 9560 |
9542 // Utf8SymbolKey carries a vector of chars as key. | 9561 // Utf8SymbolKey carries a vector of chars as key. |
9543 class Utf8SymbolKey : public HashTableKey { | 9562 class Utf8SymbolKey : public HashTableKey { |
9544 public: | 9563 public: |
9545 explicit Utf8SymbolKey(Vector<const char> string) | 9564 explicit Utf8SymbolKey(Vector<const char> string, uint32_t seed) |
9546 : string_(string), hash_field_(0) { } | 9565 : string_(string), hash_field_(0), seed_(seed) { } |
9547 | 9566 |
9548 bool IsMatch(Object* string) { | 9567 bool IsMatch(Object* string) { |
9549 return String::cast(string)->IsEqualTo(string_); | 9568 return String::cast(string)->IsEqualTo(string_); |
9550 } | 9569 } |
9551 | 9570 |
9552 uint32_t Hash() { | 9571 uint32_t Hash() { |
9553 if (hash_field_ != 0) return hash_field_ >> String::kHashShift; | 9572 if (hash_field_ != 0) return hash_field_ >> String::kHashShift; |
9554 unibrow::Utf8InputBuffer<> buffer(string_.start(), | 9573 unibrow::Utf8InputBuffer<> buffer(string_.start(), |
9555 static_cast<unsigned>(string_.length())); | 9574 static_cast<unsigned>(string_.length())); |
9556 chars_ = buffer.Length(); | 9575 chars_ = buffer.Length(); |
9557 hash_field_ = String::ComputeHashField(&buffer, chars_); | 9576 hash_field_ = String::ComputeHashField(&buffer, chars_, seed_); |
9558 uint32_t result = hash_field_ >> String::kHashShift; | 9577 uint32_t result = hash_field_ >> String::kHashShift; |
9559 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 9578 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
9560 return result; | 9579 return result; |
9561 } | 9580 } |
9562 | 9581 |
9563 uint32_t HashForObject(Object* other) { | 9582 uint32_t HashForObject(Object* other) { |
9564 return String::cast(other)->Hash(); | 9583 return String::cast(other)->Hash(); |
9565 } | 9584 } |
9566 | 9585 |
9567 MaybeObject* AsObject() { | 9586 MaybeObject* AsObject() { |
9568 if (hash_field_ == 0) Hash(); | 9587 if (hash_field_ == 0) Hash(); |
9569 return Isolate::Current()->heap()->AllocateSymbol( | 9588 return Isolate::Current()->heap()->AllocateSymbol( |
9570 string_, chars_, hash_field_); | 9589 string_, chars_, hash_field_); |
9571 } | 9590 } |
9572 | 9591 |
9573 Vector<const char> string_; | 9592 Vector<const char> string_; |
9574 uint32_t hash_field_; | 9593 uint32_t hash_field_; |
9575 int chars_; // Caches the number of characters when computing the hash code. | 9594 int chars_; // Caches the number of characters when computing the hash code. |
| 9595 uint32_t seed_; |
9576 }; | 9596 }; |
9577 | 9597 |
9578 | 9598 |
9579 template <typename Char> | 9599 template <typename Char> |
9580 class SequentialSymbolKey : public HashTableKey { | 9600 class SequentialSymbolKey : public HashTableKey { |
9581 public: | 9601 public: |
9582 explicit SequentialSymbolKey(Vector<const Char> string) | 9602 explicit SequentialSymbolKey(Vector<const Char> string, uint32_t seed) |
9583 : string_(string), hash_field_(0) { } | 9603 : string_(string), hash_field_(0), seed_(seed) { } |
9584 | 9604 |
9585 uint32_t Hash() { | 9605 uint32_t Hash() { |
9586 StringHasher hasher(string_.length()); | 9606 StringHasher hasher(string_.length(), seed_); |
9587 | 9607 |
9588 // Very long strings have a trivial hash that doesn't inspect the | 9608 // Very long strings have a trivial hash that doesn't inspect the |
9589 // string contents. | 9609 // string contents. |
9590 if (hasher.has_trivial_hash()) { | 9610 if (hasher.has_trivial_hash()) { |
9591 hash_field_ = hasher.GetHashField(); | 9611 hash_field_ = hasher.GetHashField(); |
9592 } else { | 9612 } else { |
9593 int i = 0; | 9613 int i = 0; |
9594 // Do the iterative array index computation as long as there is a | 9614 // Do the iterative array index computation as long as there is a |
9595 // chance this is an array index. | 9615 // chance this is an array index. |
9596 while (i < string_.length() && hasher.is_array_index()) { | 9616 while (i < string_.length() && hasher.is_array_index()) { |
(...skipping 15 matching lines...) Expand all Loading... |
9612 return result; | 9632 return result; |
9613 } | 9633 } |
9614 | 9634 |
9615 | 9635 |
9616 uint32_t HashForObject(Object* other) { | 9636 uint32_t HashForObject(Object* other) { |
9617 return String::cast(other)->Hash(); | 9637 return String::cast(other)->Hash(); |
9618 } | 9638 } |
9619 | 9639 |
9620 Vector<const Char> string_; | 9640 Vector<const Char> string_; |
9621 uint32_t hash_field_; | 9641 uint32_t hash_field_; |
| 9642 uint32_t seed_; |
9622 }; | 9643 }; |
9623 | 9644 |
9624 | 9645 |
9625 | 9646 |
9626 class AsciiSymbolKey : public SequentialSymbolKey<char> { | 9647 class AsciiSymbolKey : public SequentialSymbolKey<char> { |
9627 public: | 9648 public: |
9628 explicit AsciiSymbolKey(Vector<const char> str) | 9649 AsciiSymbolKey(Vector<const char> str, uint32_t seed) |
9629 : SequentialSymbolKey<char>(str) { } | 9650 : SequentialSymbolKey<char>(str, seed) { } |
9630 | 9651 |
9631 bool IsMatch(Object* string) { | 9652 bool IsMatch(Object* string) { |
9632 return String::cast(string)->IsAsciiEqualTo(string_); | 9653 return String::cast(string)->IsAsciiEqualTo(string_); |
9633 } | 9654 } |
9634 | 9655 |
9635 MaybeObject* AsObject() { | 9656 MaybeObject* AsObject() { |
9636 if (hash_field_ == 0) Hash(); | 9657 if (hash_field_ == 0) Hash(); |
9637 return HEAP->AllocateAsciiSymbol(string_, hash_field_); | 9658 return HEAP->AllocateAsciiSymbol(string_, hash_field_); |
9638 } | 9659 } |
9639 }; | 9660 }; |
9640 | 9661 |
9641 | 9662 |
9642 class SubStringAsciiSymbolKey : public HashTableKey { | 9663 class SubStringAsciiSymbolKey : public HashTableKey { |
9643 public: | 9664 public: |
9644 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, | 9665 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, |
9645 int from, | 9666 int from, |
9646 int length) | 9667 int length, |
9647 : string_(string), from_(from), length_(length) { } | 9668 uint32_t seed) |
| 9669 : string_(string), from_(from), length_(length), seed_(seed) { } |
9648 | 9670 |
9649 uint32_t Hash() { | 9671 uint32_t Hash() { |
9650 ASSERT(length_ >= 0); | 9672 ASSERT(length_ >= 0); |
9651 ASSERT(from_ + length_ <= string_->length()); | 9673 ASSERT(from_ + length_ <= string_->length()); |
9652 StringHasher hasher(length_); | 9674 StringHasher hasher(length_, string_->GetHeap()->StringHashSeed()); |
9653 | 9675 |
9654 // Very long strings have a trivial hash that doesn't inspect the | 9676 // Very long strings have a trivial hash that doesn't inspect the |
9655 // string contents. | 9677 // string contents. |
9656 if (hasher.has_trivial_hash()) { | 9678 if (hasher.has_trivial_hash()) { |
9657 hash_field_ = hasher.GetHashField(); | 9679 hash_field_ = hasher.GetHashField(); |
9658 } else { | 9680 } else { |
9659 int i = 0; | 9681 int i = 0; |
9660 // Do the iterative array index computation as long as there is a | 9682 // Do the iterative array index computation as long as there is a |
9661 // chance this is an array index. | 9683 // chance this is an array index. |
9662 while (i < length_ && hasher.is_array_index()) { | 9684 while (i < length_ && hasher.is_array_index()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9694 if (hash_field_ == 0) Hash(); | 9716 if (hash_field_ == 0) Hash(); |
9695 Vector<const char> chars(string_->GetChars() + from_, length_); | 9717 Vector<const char> chars(string_->GetChars() + from_, length_); |
9696 return HEAP->AllocateAsciiSymbol(chars, hash_field_); | 9718 return HEAP->AllocateAsciiSymbol(chars, hash_field_); |
9697 } | 9719 } |
9698 | 9720 |
9699 private: | 9721 private: |
9700 Handle<SeqAsciiString> string_; | 9722 Handle<SeqAsciiString> string_; |
9701 int from_; | 9723 int from_; |
9702 int length_; | 9724 int length_; |
9703 uint32_t hash_field_; | 9725 uint32_t hash_field_; |
| 9726 uint32_t seed_; |
9704 }; | 9727 }; |
9705 | 9728 |
9706 | 9729 |
9707 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { | 9730 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { |
9708 public: | 9731 public: |
9709 explicit TwoByteSymbolKey(Vector<const uc16> str) | 9732 explicit TwoByteSymbolKey(Vector<const uc16> str, uint32_t seed) |
9710 : SequentialSymbolKey<uc16>(str) { } | 9733 : SequentialSymbolKey<uc16>(str, seed) { } |
9711 | 9734 |
9712 bool IsMatch(Object* string) { | 9735 bool IsMatch(Object* string) { |
9713 return String::cast(string)->IsTwoByteEqualTo(string_); | 9736 return String::cast(string)->IsTwoByteEqualTo(string_); |
9714 } | 9737 } |
9715 | 9738 |
9716 MaybeObject* AsObject() { | 9739 MaybeObject* AsObject() { |
9717 if (hash_field_ == 0) Hash(); | 9740 if (hash_field_ == 0) Hash(); |
9718 return HEAP->AllocateTwoByteSymbol(string_, hash_field_); | 9741 return HEAP->AllocateTwoByteSymbol(string_, hash_field_); |
9719 } | 9742 } |
9720 }; | 9743 }; |
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10472 } | 10495 } |
10473 | 10496 |
10474 | 10497 |
10475 // This class is used for looking up two character strings in the symbol table. | 10498 // This class is used for looking up two character strings in the symbol table. |
10476 // If we don't have a hit we don't want to waste much time so we unroll the | 10499 // If we don't have a hit we don't want to waste much time so we unroll the |
10477 // string hash calculation loop here for speed. Doesn't work if the two | 10500 // string hash calculation loop here for speed. Doesn't work if the two |
10478 // characters form a decimal integer, since such strings have a different hash | 10501 // characters form a decimal integer, since such strings have a different hash |
10479 // algorithm. | 10502 // algorithm. |
10480 class TwoCharHashTableKey : public HashTableKey { | 10503 class TwoCharHashTableKey : public HashTableKey { |
10481 public: | 10504 public: |
10482 TwoCharHashTableKey(uint32_t c1, uint32_t c2) | 10505 TwoCharHashTableKey(uint32_t c1, uint32_t c2, uint32_t seed) |
10483 : c1_(c1), c2_(c2) { | 10506 : c1_(c1), c2_(c2) { |
10484 // Char 1. | 10507 // Char 1. |
10485 uint32_t hash = c1 + (c1 << 10); | 10508 uint32_t hash = seed; |
| 10509 hash += c1; |
| 10510 hash += hash << 10; |
10486 hash ^= hash >> 6; | 10511 hash ^= hash >> 6; |
10487 // Char 2. | 10512 // Char 2. |
10488 hash += c2; | 10513 hash += c2; |
10489 hash += hash << 10; | 10514 hash += hash << 10; |
10490 hash ^= hash >> 6; | 10515 hash ^= hash >> 6; |
10491 // GetHash. | 10516 // GetHash. |
10492 hash += hash << 3; | 10517 hash += hash << 3; |
10493 hash ^= hash >> 11; | 10518 hash ^= hash >> 11; |
10494 hash += hash << 15; | 10519 hash += hash << 15; |
10495 if (hash == 0) hash = 27; | 10520 if ((hash & String::kHashBitMask) == 0) hash = 27; |
10496 #ifdef DEBUG | 10521 #ifdef DEBUG |
10497 StringHasher hasher(2); | 10522 StringHasher hasher(2, seed); |
10498 hasher.AddCharacter(c1); | 10523 hasher.AddCharacter(c1); |
10499 hasher.AddCharacter(c2); | 10524 hasher.AddCharacter(c2); |
10500 // If this assert fails then we failed to reproduce the two-character | 10525 // If this assert fails then we failed to reproduce the two-character |
10501 // version of the string hashing algorithm above. One reason could be | 10526 // version of the string hashing algorithm above. One reason could be |
10502 // that we were passed two digits as characters, since the hash | 10527 // that we were passed two digits as characters, since the hash |
10503 // algorithm is different in that case. | 10528 // algorithm is different in that case. |
10504 ASSERT_EQ(static_cast<int>(hasher.GetHash()), static_cast<int>(hash)); | 10529 ASSERT_EQ(static_cast<int>(hasher.GetHash()), static_cast<int>(hash)); |
10505 #endif | 10530 #endif |
10506 hash_ = hash; | 10531 hash_ = hash; |
10507 } | 10532 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10544 ASSERT(StringShape(result).IsSymbol()); | 10569 ASSERT(StringShape(result).IsSymbol()); |
10545 *symbol = result; | 10570 *symbol = result; |
10546 return true; | 10571 return true; |
10547 } | 10572 } |
10548 } | 10573 } |
10549 | 10574 |
10550 | 10575 |
10551 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, | 10576 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, |
10552 uint32_t c2, | 10577 uint32_t c2, |
10553 String** symbol) { | 10578 String** symbol) { |
10554 TwoCharHashTableKey key(c1, c2); | 10579 TwoCharHashTableKey key(c1, c2, GetHeap()->StringHashSeed()); |
10555 int entry = FindEntry(&key); | 10580 int entry = FindEntry(&key); |
10556 if (entry == kNotFound) { | 10581 if (entry == kNotFound) { |
10557 return false; | 10582 return false; |
10558 } else { | 10583 } else { |
10559 String* result = String::cast(KeyAt(entry)); | 10584 String* result = String::cast(KeyAt(entry)); |
10560 ASSERT(StringShape(result).IsSymbol()); | 10585 ASSERT(StringShape(result).IsSymbol()); |
10561 *symbol = result; | 10586 *symbol = result; |
10562 return true; | 10587 return true; |
10563 } | 10588 } |
10564 } | 10589 } |
10565 | 10590 |
10566 | 10591 |
10567 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { | 10592 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, |
10568 Utf8SymbolKey key(str); | 10593 Object** s) { |
| 10594 Utf8SymbolKey key(str, GetHeap()->StringHashSeed()); |
10569 return LookupKey(&key, s); | 10595 return LookupKey(&key, s); |
10570 } | 10596 } |
10571 | 10597 |
10572 | 10598 |
10573 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, | 10599 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, |
10574 Object** s) { | 10600 Object** s) { |
10575 AsciiSymbolKey key(str); | 10601 AsciiSymbolKey key(str, GetHeap()->StringHashSeed()); |
10576 return LookupKey(&key, s); | 10602 return LookupKey(&key, s); |
10577 } | 10603 } |
10578 | 10604 |
10579 | 10605 |
10580 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, | 10606 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, |
10581 int from, | 10607 int from, |
10582 int length, | 10608 int length, |
10583 Object** s) { | 10609 Object** s) { |
10584 SubStringAsciiSymbolKey key(str, from, length); | 10610 SubStringAsciiSymbolKey key(str, from, length, GetHeap()->StringHashSeed()); |
10585 return LookupKey(&key, s); | 10611 return LookupKey(&key, s); |
10586 } | 10612 } |
10587 | 10613 |
10588 | 10614 |
10589 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, | 10615 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, |
10590 Object** s) { | 10616 Object** s) { |
10591 TwoByteSymbolKey key(str); | 10617 TwoByteSymbolKey key(str, GetHeap()->StringHashSeed()); |
10592 return LookupKey(&key, s); | 10618 return LookupKey(&key, s); |
10593 } | 10619 } |
10594 | 10620 |
10595 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 10621 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
10596 int entry = FindEntry(key); | 10622 int entry = FindEntry(key); |
10597 | 10623 |
10598 // Symbol already in table. | 10624 // Symbol already in table. |
10599 if (entry != kNotFound) { | 10625 if (entry != kNotFound) { |
10600 *s = KeyAt(entry); | 10626 *s = KeyAt(entry); |
10601 return this; | 10627 return this; |
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11598 if (break_point_objects()->IsUndefined()) return 0; | 11624 if (break_point_objects()->IsUndefined()) return 0; |
11599 // Single break point. | 11625 // Single break point. |
11600 if (!break_point_objects()->IsFixedArray()) return 1; | 11626 if (!break_point_objects()->IsFixedArray()) return 1; |
11601 // Multiple break points. | 11627 // Multiple break points. |
11602 return FixedArray::cast(break_point_objects())->length(); | 11628 return FixedArray::cast(break_point_objects())->length(); |
11603 } | 11629 } |
11604 #endif | 11630 #endif |
11605 | 11631 |
11606 | 11632 |
11607 } } // namespace v8::internal | 11633 } } // namespace v8::internal |
OLD | NEW |