| 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 6059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6070 // 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. |
| 6071 ASSERT(!HasHashCode()); | 6071 ASSERT(!HasHashCode()); |
| 6072 | 6072 |
| 6073 const int len = length(); | 6073 const int len = length(); |
| 6074 | 6074 |
| 6075 // Compute the hash code. | 6075 // Compute the hash code. |
| 6076 uint32_t field = 0; | 6076 uint32_t field = 0; |
| 6077 if (StringShape(this).IsSequentialAscii()) { | 6077 if (StringShape(this).IsSequentialAscii()) { |
| 6078 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), | 6078 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), |
| 6079 len, | 6079 len, |
| 6080 GetHeap()->StringHashSeed()); | 6080 GetHeap()->HashSeed()); |
| 6081 } else if (StringShape(this).IsSequentialTwoByte()) { | 6081 } else if (StringShape(this).IsSequentialTwoByte()) { |
| 6082 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), | 6082 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), |
| 6083 len, | 6083 len, |
| 6084 GetHeap()->StringHashSeed()); | 6084 GetHeap()->HashSeed()); |
| 6085 } else { | 6085 } else { |
| 6086 StringInputBuffer buffer(this); | 6086 StringInputBuffer buffer(this); |
| 6087 field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed()); | 6087 field = ComputeHashField(&buffer, len, GetHeap()->HashSeed()); |
| 6088 } | 6088 } |
| 6089 | 6089 |
| 6090 // Store the hash code in the object. | 6090 // Store the hash code in the object. |
| 6091 set_hash_field(field); | 6091 set_hash_field(field); |
| 6092 | 6092 |
| 6093 // Check the hash code is there. | 6093 // Check the hash code is there. |
| 6094 ASSERT(HasHashCode()); | 6094 ASSERT(HasHashCode()); |
| 6095 uint32_t result = field >> kHashShift; | 6095 uint32_t result = field >> kHashShift; |
| 6096 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. |
| 6097 return result; | 6097 return result; |
| (...skipping 3566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9664 public: | 9664 public: |
| 9665 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, | 9665 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, |
| 9666 int from, | 9666 int from, |
| 9667 int length, | 9667 int length, |
| 9668 uint32_t seed) | 9668 uint32_t seed) |
| 9669 : string_(string), from_(from), length_(length), seed_(seed) { } | 9669 : string_(string), from_(from), length_(length), seed_(seed) { } |
| 9670 | 9670 |
| 9671 uint32_t Hash() { | 9671 uint32_t Hash() { |
| 9672 ASSERT(length_ >= 0); | 9672 ASSERT(length_ >= 0); |
| 9673 ASSERT(from_ + length_ <= string_->length()); | 9673 ASSERT(from_ + length_ <= string_->length()); |
| 9674 StringHasher hasher(length_, string_->GetHeap()->StringHashSeed()); | 9674 StringHasher hasher(length_, string_->GetHeap()->HashSeed()); |
| 9675 | 9675 |
| 9676 // 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 |
| 9677 // string contents. | 9677 // string contents. |
| 9678 if (hasher.has_trivial_hash()) { | 9678 if (hasher.has_trivial_hash()) { |
| 9679 hash_field_ = hasher.GetHashField(); | 9679 hash_field_ = hasher.GetHashField(); |
| 9680 } else { | 9680 } else { |
| 9681 int i = 0; | 9681 int i = 0; |
| 9682 // 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 |
| 9683 // chance this is an array index. | 9683 // chance this is an array index. |
| 9684 while (i < length_ && hasher.is_array_index()) { | 9684 while (i < length_ && hasher.is_array_index()) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9873 i++) { | 9873 i++) { |
| 9874 new_table->set(i, get(i), mode); | 9874 new_table->set(i, get(i), mode); |
| 9875 } | 9875 } |
| 9876 | 9876 |
| 9877 // Rehash the elements. | 9877 // Rehash the elements. |
| 9878 int capacity = Capacity(); | 9878 int capacity = Capacity(); |
| 9879 for (int i = 0; i < capacity; i++) { | 9879 for (int i = 0; i < capacity; i++) { |
| 9880 uint32_t from_index = EntryToIndex(i); | 9880 uint32_t from_index = EntryToIndex(i); |
| 9881 Object* k = get(from_index); | 9881 Object* k = get(from_index); |
| 9882 if (IsKey(k)) { | 9882 if (IsKey(k)) { |
| 9883 uint32_t hash = Shape::HashForObject(key, k); | 9883 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); |
| 9884 uint32_t insertion_index = | 9884 uint32_t insertion_index = |
| 9885 EntryToIndex(new_table->FindInsertionEntry(hash)); | 9885 EntryToIndex(new_table->FindInsertionEntry(hash)); |
| 9886 for (int j = 0; j < Shape::kEntrySize; j++) { | 9886 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 9887 new_table->set(insertion_index + j, get(from_index + j), mode); | 9887 new_table->set(insertion_index + j, get(from_index + j), mode); |
| 9888 } | 9888 } |
| 9889 } | 9889 } |
| 9890 } | 9890 } |
| 9891 new_table->SetNumberOfElements(NumberOfElements()); | 9891 new_table->SetNumberOfElements(NumberOfElements()); |
| 9892 new_table->SetNumberOfDeletedElements(0); | 9892 new_table->SetNumberOfDeletedElements(0); |
| 9893 return new_table; | 9893 return new_table; |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10569 ASSERT(StringShape(result).IsSymbol()); | 10569 ASSERT(StringShape(result).IsSymbol()); |
| 10570 *symbol = result; | 10570 *symbol = result; |
| 10571 return true; | 10571 return true; |
| 10572 } | 10572 } |
| 10573 } | 10573 } |
| 10574 | 10574 |
| 10575 | 10575 |
| 10576 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, | 10576 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, |
| 10577 uint32_t c2, | 10577 uint32_t c2, |
| 10578 String** symbol) { | 10578 String** symbol) { |
| 10579 TwoCharHashTableKey key(c1, c2, GetHeap()->StringHashSeed()); | 10579 TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed()); |
| 10580 int entry = FindEntry(&key); | 10580 int entry = FindEntry(&key); |
| 10581 if (entry == kNotFound) { | 10581 if (entry == kNotFound) { |
| 10582 return false; | 10582 return false; |
| 10583 } else { | 10583 } else { |
| 10584 String* result = String::cast(KeyAt(entry)); | 10584 String* result = String::cast(KeyAt(entry)); |
| 10585 ASSERT(StringShape(result).IsSymbol()); | 10585 ASSERT(StringShape(result).IsSymbol()); |
| 10586 *symbol = result; | 10586 *symbol = result; |
| 10587 return true; | 10587 return true; |
| 10588 } | 10588 } |
| 10589 } | 10589 } |
| 10590 | 10590 |
| 10591 | 10591 |
| 10592 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, | 10592 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, |
| 10593 Object** s) { | 10593 Object** s) { |
| 10594 Utf8SymbolKey key(str, GetHeap()->StringHashSeed()); | 10594 Utf8SymbolKey key(str, GetHeap()->HashSeed()); |
| 10595 return LookupKey(&key, s); | 10595 return LookupKey(&key, s); |
| 10596 } | 10596 } |
| 10597 | 10597 |
| 10598 | 10598 |
| 10599 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, | 10599 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, |
| 10600 Object** s) { | 10600 Object** s) { |
| 10601 AsciiSymbolKey key(str, GetHeap()->StringHashSeed()); | 10601 AsciiSymbolKey key(str, GetHeap()->HashSeed()); |
| 10602 return LookupKey(&key, s); | 10602 return LookupKey(&key, s); |
| 10603 } | 10603 } |
| 10604 | 10604 |
| 10605 | 10605 |
| 10606 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, | 10606 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, |
| 10607 int from, | 10607 int from, |
| 10608 int length, | 10608 int length, |
| 10609 Object** s) { | 10609 Object** s) { |
| 10610 SubStringAsciiSymbolKey key(str, from, length, GetHeap()->StringHashSeed()); | 10610 SubStringAsciiSymbolKey key(str, from, length, GetHeap()->HashSeed()); |
| 10611 return LookupKey(&key, s); | 10611 return LookupKey(&key, s); |
| 10612 } | 10612 } |
| 10613 | 10613 |
| 10614 | 10614 |
| 10615 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, | 10615 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, |
| 10616 Object** s) { | 10616 Object** s) { |
| 10617 TwoByteSymbolKey key(str, GetHeap()->StringHashSeed()); | 10617 TwoByteSymbolKey key(str, GetHeap()->HashSeed()); |
| 10618 return LookupKey(&key, s); | 10618 return LookupKey(&key, s); |
| 10619 } | 10619 } |
| 10620 | 10620 |
| 10621 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 10621 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
| 10622 int entry = FindEntry(key); | 10622 int entry = FindEntry(key); |
| 10623 | 10623 |
| 10624 // Symbol already in table. | 10624 // Symbol already in table. |
| 10625 if (entry != kNotFound) { | 10625 if (entry != kNotFound) { |
| 10626 *s = KeyAt(entry); | 10626 *s = KeyAt(entry); |
| 10627 return this; | 10627 return this; |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10964 Object* obj; | 10964 Object* obj; |
| 10965 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 10965 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 10966 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 10966 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 10967 } | 10967 } |
| 10968 | 10968 |
| 10969 Object* k; | 10969 Object* k; |
| 10970 { MaybeObject* maybe_k = Shape::AsObject(key); | 10970 { MaybeObject* maybe_k = Shape::AsObject(key); |
| 10971 if (!maybe_k->ToObject(&k)) return maybe_k; | 10971 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 10972 } | 10972 } |
| 10973 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 10973 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
| 10974 return Dictionary<Shape, Key>::cast(obj)-> | 10974 |
| 10975 AddEntry(key, value, details, Shape::Hash(key)); | 10975 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, |
| 10976 Dictionary<Shape, Key>::Hash(key)); |
| 10976 } | 10977 } |
| 10977 | 10978 |
| 10978 | 10979 |
| 10979 template<typename Shape, typename Key> | 10980 template<typename Shape, typename Key> |
| 10980 MaybeObject* Dictionary<Shape, Key>::Add(Key key, | 10981 MaybeObject* Dictionary<Shape, Key>::Add(Key key, |
| 10981 Object* value, | 10982 Object* value, |
| 10982 PropertyDetails details) { | 10983 PropertyDetails details) { |
| 10983 // Valdate key is absent. | 10984 // Valdate key is absent. |
| 10984 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); | 10985 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); |
| 10985 // Check whether the dictionary should be extended. | 10986 // Check whether the dictionary should be extended. |
| 10986 Object* obj; | 10987 Object* obj; |
| 10987 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 10988 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 10988 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 10989 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 10989 } | 10990 } |
| 10990 return Dictionary<Shape, Key>::cast(obj)-> | 10991 |
| 10991 AddEntry(key, value, details, Shape::Hash(key)); | 10992 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, |
| 10993 Dictionary<Shape, Key>::Hash(key)); |
| 10992 } | 10994 } |
| 10993 | 10995 |
| 10994 | 10996 |
| 10995 // Add a key, value pair to the dictionary. | 10997 // Add a key, value pair to the dictionary. |
| 10996 template<typename Shape, typename Key> | 10998 template<typename Shape, typename Key> |
| 10997 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, | 10999 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, |
| 10998 Object* value, | 11000 Object* value, |
| 10999 PropertyDetails details, | 11001 PropertyDetails details, |
| 11000 uint32_t hash) { | 11002 uint32_t hash) { |
| 11001 // Compute the key object. | 11003 // Compute the key object. |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11624 if (break_point_objects()->IsUndefined()) return 0; | 11626 if (break_point_objects()->IsUndefined()) return 0; |
| 11625 // Single break point. | 11627 // Single break point. |
| 11626 if (!break_point_objects()->IsFixedArray()) return 1; | 11628 if (!break_point_objects()->IsFixedArray()) return 1; |
| 11627 // Multiple break points. | 11629 // Multiple break points. |
| 11628 return FixedArray::cast(break_point_objects())->length(); | 11630 return FixedArray::cast(break_point_objects())->length(); |
| 11629 } | 11631 } |
| 11630 #endif | 11632 #endif |
| 11631 | 11633 |
| 11632 | 11634 |
| 11633 } } // namespace v8::internal | 11635 } } // namespace v8::internal |
| OLD | NEW |