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 6664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6675 | 6675 |
6676 bool String::SlowEquals(String* other) { | 6676 bool String::SlowEquals(String* other) { |
6677 // Fast check: negative check with lengths. | 6677 // Fast check: negative check with lengths. |
6678 int len = length(); | 6678 int len = length(); |
6679 if (len != other->length()) return false; | 6679 if (len != other->length()) return false; |
6680 if (len == 0) return true; | 6680 if (len == 0) return true; |
6681 | 6681 |
6682 // Fast check: if hash code is computed for both strings | 6682 // Fast check: if hash code is computed for both strings |
6683 // a fast negative check can be performed. | 6683 // a fast negative check can be performed. |
6684 if (HasHashCode() && other->HasHashCode()) { | 6684 if (HasHashCode() && other->HasHashCode()) { |
6685 #ifdef DEBUG | |
6686 if (Hash() != other->Hash()) { | |
6687 bool found_difference = false; | |
6688 for (int i = 0; i < len; i++) { | |
6689 if (Get(i) != other->Get(i)) { | |
6690 found_difference = true; | |
6691 break; | |
6692 } | |
6693 } | |
6694 ASSERT(found_difference); | |
6695 } | |
6696 #endif | |
Vyacheslav Egorov (Chromium)
2012/01/04 14:30:57
I think this should be checked only when slow asse
Erik Corry
2012/01/04 15:48:59
Done.
| |
6685 if (Hash() != other->Hash()) return false; | 6697 if (Hash() != other->Hash()) return false; |
6686 } | 6698 } |
6687 | 6699 |
6688 // We know the strings are both non-empty. Compare the first chars | 6700 // We know the strings are both non-empty. Compare the first chars |
6689 // before we try to flatten the strings. | 6701 // before we try to flatten the strings. |
6690 if (this->Get(0) != other->Get(0)) return false; | 6702 if (this->Get(0) != other->Get(0)) return false; |
6691 | 6703 |
6692 String* lhs = this->TryFlattenGetString(); | 6704 String* lhs = this->TryFlattenGetString(); |
6693 String* rhs = other->TryFlattenGetString(); | 6705 String* rhs = other->TryFlattenGetString(); |
6694 | 6706 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6810 | 6822 |
6811 uint32_t String::ComputeAndSetHash() { | 6823 uint32_t String::ComputeAndSetHash() { |
6812 // Should only be called if hash code has not yet been computed. | 6824 // Should only be called if hash code has not yet been computed. |
6813 ASSERT(!HasHashCode()); | 6825 ASSERT(!HasHashCode()); |
6814 | 6826 |
6815 const int len = length(); | 6827 const int len = length(); |
6816 | 6828 |
6817 // Compute the hash code. | 6829 // Compute the hash code. |
6818 uint32_t field = 0; | 6830 uint32_t field = 0; |
6819 if (StringShape(this).IsSequentialAscii()) { | 6831 if (StringShape(this).IsSequentialAscii()) { |
6820 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len); | 6832 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), |
6833 len, | |
6834 GetHeap()->StringHashSeed()); | |
6821 } else if (StringShape(this).IsSequentialTwoByte()) { | 6835 } else if (StringShape(this).IsSequentialTwoByte()) { |
6822 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), len); | 6836 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), |
6837 len, | |
6838 GetHeap()->StringHashSeed()); | |
6823 } else { | 6839 } else { |
6824 StringInputBuffer buffer(this); | 6840 StringInputBuffer buffer(this); |
6825 field = ComputeHashField(&buffer, len); | 6841 field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed()); |
6826 } | 6842 } |
6827 | 6843 |
6828 // Store the hash code in the object. | 6844 // Store the hash code in the object. |
6829 set_hash_field(field); | 6845 set_hash_field(field); |
6830 | 6846 |
6831 // Check the hash code is there. | 6847 // Check the hash code is there. |
6832 ASSERT(HasHashCode()); | 6848 ASSERT(HasHashCode()); |
6833 uint32_t result = field >> kHashShift; | 6849 uint32_t result = field >> kHashShift; |
6834 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 6850 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
6835 return result; | 6851 return result; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6906 return MakeArrayIndexHash(array_index(), length_); | 6922 return MakeArrayIndexHash(array_index(), length_); |
6907 } | 6923 } |
6908 return (GetHash() << String::kHashShift) | String::kIsNotArrayIndexMask; | 6924 return (GetHash() << String::kHashShift) | String::kIsNotArrayIndexMask; |
6909 } else { | 6925 } else { |
6910 return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask; | 6926 return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask; |
6911 } | 6927 } |
6912 } | 6928 } |
6913 | 6929 |
6914 | 6930 |
6915 uint32_t String::ComputeHashField(unibrow::CharacterStream* buffer, | 6931 uint32_t String::ComputeHashField(unibrow::CharacterStream* buffer, |
6916 int length) { | 6932 int length, |
6917 StringHasher hasher(length); | 6933 uint32_t seed) { |
6934 StringHasher hasher(length, seed); | |
6918 | 6935 |
6919 // Very long strings have a trivial hash that doesn't inspect the | 6936 // Very long strings have a trivial hash that doesn't inspect the |
6920 // string contents. | 6937 // string contents. |
6921 if (hasher.has_trivial_hash()) { | 6938 if (hasher.has_trivial_hash()) { |
6922 return hasher.GetHashField(); | 6939 return hasher.GetHashField(); |
6923 } | 6940 } |
6924 | 6941 |
6925 // Do the iterative array index computation as long as there is a | 6942 // Do the iterative array index computation as long as there is a |
6926 // chance this is an array index. | 6943 // chance this is an array index. |
6927 while (buffer->has_more() && hasher.is_array_index()) { | 6944 while (buffer->has_more() && hasher.is_array_index()) { |
(...skipping 3521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10449 return string->Hash() + flags->value(); | 10466 return string->Hash() + flags->value(); |
10450 } | 10467 } |
10451 | 10468 |
10452 String* string_; | 10469 String* string_; |
10453 Smi* flags_; | 10470 Smi* flags_; |
10454 }; | 10471 }; |
10455 | 10472 |
10456 // Utf8SymbolKey carries a vector of chars as key. | 10473 // Utf8SymbolKey carries a vector of chars as key. |
10457 class Utf8SymbolKey : public HashTableKey { | 10474 class Utf8SymbolKey : public HashTableKey { |
10458 public: | 10475 public: |
10459 explicit Utf8SymbolKey(Vector<const char> string) | 10476 explicit Utf8SymbolKey(Vector<const char> string, uint32_t seed) |
10460 : string_(string), hash_field_(0) { } | 10477 : string_(string), hash_field_(0), seed_(seed) { } |
10461 | 10478 |
10462 bool IsMatch(Object* string) { | 10479 bool IsMatch(Object* string) { |
10463 return String::cast(string)->IsEqualTo(string_); | 10480 return String::cast(string)->IsEqualTo(string_); |
10464 } | 10481 } |
10465 | 10482 |
10466 uint32_t Hash() { | 10483 uint32_t Hash() { |
10467 if (hash_field_ != 0) return hash_field_ >> String::kHashShift; | 10484 if (hash_field_ != 0) return hash_field_ >> String::kHashShift; |
10468 unibrow::Utf8InputBuffer<> buffer(string_.start(), | 10485 unibrow::Utf8InputBuffer<> buffer(string_.start(), |
10469 static_cast<unsigned>(string_.length())); | 10486 static_cast<unsigned>(string_.length())); |
10470 chars_ = buffer.Length(); | 10487 chars_ = buffer.Length(); |
10471 hash_field_ = String::ComputeHashField(&buffer, chars_); | 10488 hash_field_ = String::ComputeHashField(&buffer, chars_, seed_); |
10472 uint32_t result = hash_field_ >> String::kHashShift; | 10489 uint32_t result = hash_field_ >> String::kHashShift; |
10473 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 10490 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
10474 return result; | 10491 return result; |
10475 } | 10492 } |
10476 | 10493 |
10477 uint32_t HashForObject(Object* other) { | 10494 uint32_t HashForObject(Object* other) { |
10478 return String::cast(other)->Hash(); | 10495 return String::cast(other)->Hash(); |
10479 } | 10496 } |
10480 | 10497 |
10481 MaybeObject* AsObject() { | 10498 MaybeObject* AsObject() { |
10482 if (hash_field_ == 0) Hash(); | 10499 if (hash_field_ == 0) Hash(); |
10483 return Isolate::Current()->heap()->AllocateSymbol( | 10500 return Isolate::Current()->heap()->AllocateSymbol( |
10484 string_, chars_, hash_field_); | 10501 string_, chars_, hash_field_); |
10485 } | 10502 } |
10486 | 10503 |
10487 Vector<const char> string_; | 10504 Vector<const char> string_; |
10488 uint32_t hash_field_; | 10505 uint32_t hash_field_; |
10489 int chars_; // Caches the number of characters when computing the hash code. | 10506 int chars_; // Caches the number of characters when computing the hash code. |
10507 uint32_t seed_; | |
10490 }; | 10508 }; |
10491 | 10509 |
10492 | 10510 |
10493 template <typename Char> | 10511 template <typename Char> |
10494 class SequentialSymbolKey : public HashTableKey { | 10512 class SequentialSymbolKey : public HashTableKey { |
10495 public: | 10513 public: |
10496 explicit SequentialSymbolKey(Vector<const Char> string) | 10514 explicit SequentialSymbolKey(Vector<const Char> string, uint32_t seed) |
10497 : string_(string), hash_field_(0) { } | 10515 : string_(string), hash_field_(0), seed_(seed) { } |
10498 | 10516 |
10499 uint32_t Hash() { | 10517 uint32_t Hash() { |
10500 StringHasher hasher(string_.length()); | 10518 StringHasher hasher(string_.length(), seed_); |
10501 | 10519 |
10502 // Very long strings have a trivial hash that doesn't inspect the | 10520 // Very long strings have a trivial hash that doesn't inspect the |
10503 // string contents. | 10521 // string contents. |
10504 if (hasher.has_trivial_hash()) { | 10522 if (hasher.has_trivial_hash()) { |
10505 hash_field_ = hasher.GetHashField(); | 10523 hash_field_ = hasher.GetHashField(); |
10506 } else { | 10524 } else { |
10507 int i = 0; | 10525 int i = 0; |
10508 // Do the iterative array index computation as long as there is a | 10526 // Do the iterative array index computation as long as there is a |
10509 // chance this is an array index. | 10527 // chance this is an array index. |
10510 while (i < string_.length() && hasher.is_array_index()) { | 10528 while (i < string_.length() && hasher.is_array_index()) { |
(...skipping 15 matching lines...) Expand all Loading... | |
10526 return result; | 10544 return result; |
10527 } | 10545 } |
10528 | 10546 |
10529 | 10547 |
10530 uint32_t HashForObject(Object* other) { | 10548 uint32_t HashForObject(Object* other) { |
10531 return String::cast(other)->Hash(); | 10549 return String::cast(other)->Hash(); |
10532 } | 10550 } |
10533 | 10551 |
10534 Vector<const Char> string_; | 10552 Vector<const Char> string_; |
10535 uint32_t hash_field_; | 10553 uint32_t hash_field_; |
10554 uint32_t seed_; | |
10536 }; | 10555 }; |
10537 | 10556 |
10538 | 10557 |
10539 | 10558 |
10540 class AsciiSymbolKey : public SequentialSymbolKey<char> { | 10559 class AsciiSymbolKey : public SequentialSymbolKey<char> { |
10541 public: | 10560 public: |
10542 explicit AsciiSymbolKey(Vector<const char> str) | 10561 AsciiSymbolKey(Vector<const char> str, uint32_t seed) |
10543 : SequentialSymbolKey<char>(str) { } | 10562 : SequentialSymbolKey<char>(str, seed) { } |
10544 | 10563 |
10545 bool IsMatch(Object* string) { | 10564 bool IsMatch(Object* string) { |
10546 return String::cast(string)->IsAsciiEqualTo(string_); | 10565 return String::cast(string)->IsAsciiEqualTo(string_); |
10547 } | 10566 } |
10548 | 10567 |
10549 MaybeObject* AsObject() { | 10568 MaybeObject* AsObject() { |
10550 if (hash_field_ == 0) Hash(); | 10569 if (hash_field_ == 0) Hash(); |
10551 return HEAP->AllocateAsciiSymbol(string_, hash_field_); | 10570 return HEAP->AllocateAsciiSymbol(string_, hash_field_); |
10552 } | 10571 } |
10553 }; | 10572 }; |
10554 | 10573 |
10555 | 10574 |
10556 class SubStringAsciiSymbolKey : public HashTableKey { | 10575 class SubStringAsciiSymbolKey : public HashTableKey { |
10557 public: | 10576 public: |
10558 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, | 10577 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, |
10559 int from, | 10578 int from, |
10560 int length) | 10579 int length, |
10561 : string_(string), from_(from), length_(length) { } | 10580 uint32_t seed) |
10581 : string_(string), from_(from), length_(length), seed_(seed) { } | |
10562 | 10582 |
10563 uint32_t Hash() { | 10583 uint32_t Hash() { |
10564 ASSERT(length_ >= 0); | 10584 ASSERT(length_ >= 0); |
10565 ASSERT(from_ + length_ <= string_->length()); | 10585 ASSERT(from_ + length_ <= string_->length()); |
10566 StringHasher hasher(length_); | 10586 StringHasher hasher(length_, string_->GetHeap()->StringHashSeed()); |
10567 | 10587 |
10568 // Very long strings have a trivial hash that doesn't inspect the | 10588 // Very long strings have a trivial hash that doesn't inspect the |
10569 // string contents. | 10589 // string contents. |
10570 if (hasher.has_trivial_hash()) { | 10590 if (hasher.has_trivial_hash()) { |
10571 hash_field_ = hasher.GetHashField(); | 10591 hash_field_ = hasher.GetHashField(); |
10572 } else { | 10592 } else { |
10573 int i = 0; | 10593 int i = 0; |
10574 // Do the iterative array index computation as long as there is a | 10594 // Do the iterative array index computation as long as there is a |
10575 // chance this is an array index. | 10595 // chance this is an array index. |
10576 while (i < length_ && hasher.is_array_index()) { | 10596 while (i < length_ && hasher.is_array_index()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10608 if (hash_field_ == 0) Hash(); | 10628 if (hash_field_ == 0) Hash(); |
10609 Vector<const char> chars(string_->GetChars() + from_, length_); | 10629 Vector<const char> chars(string_->GetChars() + from_, length_); |
10610 return HEAP->AllocateAsciiSymbol(chars, hash_field_); | 10630 return HEAP->AllocateAsciiSymbol(chars, hash_field_); |
10611 } | 10631 } |
10612 | 10632 |
10613 private: | 10633 private: |
10614 Handle<SeqAsciiString> string_; | 10634 Handle<SeqAsciiString> string_; |
10615 int from_; | 10635 int from_; |
10616 int length_; | 10636 int length_; |
10617 uint32_t hash_field_; | 10637 uint32_t hash_field_; |
10638 uint32_t seed_; | |
10618 }; | 10639 }; |
10619 | 10640 |
10620 | 10641 |
10621 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { | 10642 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { |
10622 public: | 10643 public: |
10623 explicit TwoByteSymbolKey(Vector<const uc16> str) | 10644 explicit TwoByteSymbolKey(Vector<const uc16> str, uint32_t seed) |
10624 : SequentialSymbolKey<uc16>(str) { } | 10645 : SequentialSymbolKey<uc16>(str, seed) { } |
10625 | 10646 |
10626 bool IsMatch(Object* string) { | 10647 bool IsMatch(Object* string) { |
10627 return String::cast(string)->IsTwoByteEqualTo(string_); | 10648 return String::cast(string)->IsTwoByteEqualTo(string_); |
10628 } | 10649 } |
10629 | 10650 |
10630 MaybeObject* AsObject() { | 10651 MaybeObject* AsObject() { |
10631 if (hash_field_ == 0) Hash(); | 10652 if (hash_field_ == 0) Hash(); |
10632 return HEAP->AllocateTwoByteSymbol(string_, hash_field_); | 10653 return HEAP->AllocateTwoByteSymbol(string_, hash_field_); |
10633 } | 10654 } |
10634 }; | 10655 }; |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11399 } | 11420 } |
11400 | 11421 |
11401 | 11422 |
11402 // This class is used for looking up two character strings in the symbol table. | 11423 // This class is used for looking up two character strings in the symbol table. |
11403 // If we don't have a hit we don't want to waste much time so we unroll the | 11424 // If we don't have a hit we don't want to waste much time so we unroll the |
11404 // string hash calculation loop here for speed. Doesn't work if the two | 11425 // string hash calculation loop here for speed. Doesn't work if the two |
11405 // characters form a decimal integer, since such strings have a different hash | 11426 // characters form a decimal integer, since such strings have a different hash |
11406 // algorithm. | 11427 // algorithm. |
11407 class TwoCharHashTableKey : public HashTableKey { | 11428 class TwoCharHashTableKey : public HashTableKey { |
11408 public: | 11429 public: |
11409 TwoCharHashTableKey(uint32_t c1, uint32_t c2) | 11430 TwoCharHashTableKey(uint32_t c1, uint32_t c2, uint32_t seed) |
11410 : c1_(c1), c2_(c2) { | 11431 : c1_(c1), c2_(c2) { |
11411 // Char 1. | 11432 // Char 1. |
11412 uint32_t hash = c1 + (c1 << 10); | 11433 uint32_t hash = seed; |
11434 hash += c1; | |
11435 hash += hash << 10; | |
11413 hash ^= hash >> 6; | 11436 hash ^= hash >> 6; |
11414 // Char 2. | 11437 // Char 2. |
11415 hash += c2; | 11438 hash += c2; |
11416 hash += hash << 10; | 11439 hash += hash << 10; |
11417 hash ^= hash >> 6; | 11440 hash ^= hash >> 6; |
11418 // GetHash. | 11441 // GetHash. |
11419 hash += hash << 3; | 11442 hash += hash << 3; |
11420 hash ^= hash >> 11; | 11443 hash ^= hash >> 11; |
11421 hash += hash << 15; | 11444 hash += hash << 15; |
11422 if (hash == 0) hash = 27; | 11445 if (hash == 0) hash = 27; |
11423 #ifdef DEBUG | 11446 #ifdef DEBUG |
11424 StringHasher hasher(2); | 11447 StringHasher hasher(2, seed); |
11425 hasher.AddCharacter(c1); | 11448 hasher.AddCharacter(c1); |
11426 hasher.AddCharacter(c2); | 11449 hasher.AddCharacter(c2); |
11427 // If this assert fails then we failed to reproduce the two-character | 11450 // If this assert fails then we failed to reproduce the two-character |
11428 // version of the string hashing algorithm above. One reason could be | 11451 // version of the string hashing algorithm above. One reason could be |
11429 // that we were passed two digits as characters, since the hash | 11452 // that we were passed two digits as characters, since the hash |
11430 // algorithm is different in that case. | 11453 // algorithm is different in that case. |
11431 ASSERT_EQ(static_cast<int>(hasher.GetHash()), static_cast<int>(hash)); | 11454 ASSERT_EQ(static_cast<int>(hasher.GetHash()), static_cast<int>(hash)); |
11432 #endif | 11455 #endif |
11433 hash_ = hash; | 11456 hash_ = hash; |
11434 } | 11457 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11471 ASSERT(StringShape(result).IsSymbol()); | 11494 ASSERT(StringShape(result).IsSymbol()); |
11472 *symbol = result; | 11495 *symbol = result; |
11473 return true; | 11496 return true; |
11474 } | 11497 } |
11475 } | 11498 } |
11476 | 11499 |
11477 | 11500 |
11478 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, | 11501 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, |
11479 uint32_t c2, | 11502 uint32_t c2, |
11480 String** symbol) { | 11503 String** symbol) { |
11481 TwoCharHashTableKey key(c1, c2); | 11504 TwoCharHashTableKey key(c1, c2, GetHeap()->StringHashSeed()); |
11482 int entry = FindEntry(&key); | 11505 int entry = FindEntry(&key); |
11483 if (entry == kNotFound) { | 11506 if (entry == kNotFound) { |
11484 return false; | 11507 return false; |
11485 } else { | 11508 } else { |
11486 String* result = String::cast(KeyAt(entry)); | 11509 String* result = String::cast(KeyAt(entry)); |
11487 ASSERT(StringShape(result).IsSymbol()); | 11510 ASSERT(StringShape(result).IsSymbol()); |
11488 *symbol = result; | 11511 *symbol = result; |
11489 return true; | 11512 return true; |
11490 } | 11513 } |
11491 } | 11514 } |
11492 | 11515 |
11493 | 11516 |
11494 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { | 11517 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, |
11495 Utf8SymbolKey key(str); | 11518 Object** s) { |
11519 Utf8SymbolKey key(str, GetHeap()->StringHashSeed()); | |
11496 return LookupKey(&key, s); | 11520 return LookupKey(&key, s); |
11497 } | 11521 } |
11498 | 11522 |
11499 | 11523 |
11500 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, | 11524 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, |
11501 Object** s) { | 11525 Object** s) { |
11502 AsciiSymbolKey key(str); | 11526 AsciiSymbolKey key(str, GetHeap()->StringHashSeed()); |
11503 return LookupKey(&key, s); | 11527 return LookupKey(&key, s); |
11504 } | 11528 } |
11505 | 11529 |
11506 | 11530 |
11507 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, | 11531 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, |
11508 int from, | 11532 int from, |
11509 int length, | 11533 int length, |
11510 Object** s) { | 11534 Object** s) { |
11511 SubStringAsciiSymbolKey key(str, from, length); | 11535 SubStringAsciiSymbolKey key(str, from, length, GetHeap()->StringHashSeed()); |
11512 return LookupKey(&key, s); | 11536 return LookupKey(&key, s); |
11513 } | 11537 } |
11514 | 11538 |
11515 | 11539 |
11516 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, | 11540 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, |
11517 Object** s) { | 11541 Object** s) { |
11518 TwoByteSymbolKey key(str); | 11542 TwoByteSymbolKey key(str, GetHeap()->StringHashSeed()); |
11519 return LookupKey(&key, s); | 11543 return LookupKey(&key, s); |
11520 } | 11544 } |
11521 | 11545 |
11522 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 11546 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
11523 int entry = FindEntry(key); | 11547 int entry = FindEntry(key); |
11524 | 11548 |
11525 // Symbol already in table. | 11549 // Symbol already in table. |
11526 if (entry != kNotFound) { | 11550 if (entry != kNotFound) { |
11527 *s = KeyAt(entry); | 11551 *s = KeyAt(entry); |
11528 return this; | 11552 return this; |
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12572 if (break_point_objects()->IsUndefined()) return 0; | 12596 if (break_point_objects()->IsUndefined()) return 0; |
12573 // Single break point. | 12597 // Single break point. |
12574 if (!break_point_objects()->IsFixedArray()) return 1; | 12598 if (!break_point_objects()->IsFixedArray()) return 1; |
12575 // Multiple break points. | 12599 // Multiple break points. |
12576 return FixedArray::cast(break_point_objects())->length(); | 12600 return FixedArray::cast(break_point_objects())->length(); |
12577 } | 12601 } |
12578 #endif // ENABLE_DEBUGGER_SUPPORT | 12602 #endif // ENABLE_DEBUGGER_SUPPORT |
12579 | 12603 |
12580 | 12604 |
12581 } } // namespace v8::internal | 12605 } } // namespace v8::internal |
OLD | NEW |