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 |