Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/objects.cc

Issue 9124004: Backport hash collision workaround to 3.6. (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.6/
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698