OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1899 } | 1899 } |
1900 | 1900 |
1901 | 1901 |
1902 bool DescriptorArray::IsEmpty() { | 1902 bool DescriptorArray::IsEmpty() { |
1903 ASSERT(length() >= kFirstIndex || | 1903 ASSERT(length() >= kFirstIndex || |
1904 this == HEAP->empty_descriptor_array()); | 1904 this == HEAP->empty_descriptor_array()); |
1905 return length() < kFirstIndex; | 1905 return length() < kFirstIndex; |
1906 } | 1906 } |
1907 | 1907 |
1908 | 1908 |
1909 void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) { | |
1910 WRITE_FIELD( | |
1911 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors)); | |
1912 } | |
1913 | |
1914 | |
1915 // Perform a binary search in a fixed array. Low and high are entry indices. If | 1909 // Perform a binary search in a fixed array. Low and high are entry indices. If |
1916 // there are three entries in this array it should be called with low=0 and | 1910 // there are three entries in this array it should be called with low=0 and |
1917 // high=2. | 1911 // high=2. |
1918 template<typename T> | 1912 template<typename T> |
1919 int BinarySearch(T* array, String* name, int low, int high) { | 1913 int BinarySearch(T* array, String* name, int low, int high) { |
1920 uint32_t hash = name->Hash(); | 1914 uint32_t hash = name->Hash(); |
1921 int limit = high; | 1915 int limit = high; |
1922 | 1916 |
1923 ASSERT(low <= high); | 1917 ASSERT(low <= high); |
1924 | 1918 |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2137 desc->GetKey()); | 2131 desc->GetKey()); |
2138 NoIncrementalWriteBarrierSet(this, | 2132 NoIncrementalWriteBarrierSet(this, |
2139 ToValueIndex(descriptor_number), | 2133 ToValueIndex(descriptor_number), |
2140 desc->GetValue()); | 2134 desc->GetValue()); |
2141 NoIncrementalWriteBarrierSet(this, | 2135 NoIncrementalWriteBarrierSet(this, |
2142 ToDetailsIndex(descriptor_number), | 2136 ToDetailsIndex(descriptor_number), |
2143 desc->GetDetails().AsSmi()); | 2137 desc->GetDetails().AsSmi()); |
2144 } | 2138 } |
2145 | 2139 |
2146 | 2140 |
2147 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { | |
2148 // Range check. | |
2149 ASSERT(descriptor_number < number_of_descriptors()); | |
2150 ASSERT(desc->GetDetails().descriptor_index() <= | |
2151 number_of_descriptors()); | |
2152 ASSERT(desc->GetDetails().descriptor_index() > 0); | |
2153 | |
2154 set(ToKeyIndex(descriptor_number), desc->GetKey()); | |
2155 set(ToValueIndex(descriptor_number), desc->GetValue()); | |
2156 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi()); | |
2157 } | |
2158 | |
2159 | |
2160 void DescriptorArray::EraseDescriptor(Heap* heap, int descriptor_number) { | |
2161 set_null_unchecked(heap, ToKeyIndex(descriptor_number)); | |
2162 set_null_unchecked(heap, ToValueIndex(descriptor_number)); | |
2163 } | |
2164 | |
2165 | |
2166 void DescriptorArray::Append(Descriptor* desc, | 2141 void DescriptorArray::Append(Descriptor* desc, |
2167 const WhitenessWitness& witness) { | 2142 const WhitenessWitness& witness, |
2168 int descriptor_number = number_of_descriptors(); | 2143 int number_of_set_descriptors) { |
| 2144 int descriptor_number = number_of_set_descriptors; |
2169 int enumeration_index = descriptor_number + 1; | 2145 int enumeration_index = descriptor_number + 1; |
2170 SetNumberOfDescriptors(descriptor_number + 1); | |
2171 desc->SetEnumerationIndex(enumeration_index); | 2146 desc->SetEnumerationIndex(enumeration_index); |
2172 Set(descriptor_number, desc, witness); | 2147 Set(descriptor_number, desc, witness); |
2173 | 2148 |
2174 uint32_t hash = desc->GetKey()->Hash(); | 2149 uint32_t hash = desc->GetKey()->Hash(); |
2175 | 2150 |
2176 int insertion; | 2151 int insertion; |
2177 | 2152 |
2178 for (insertion = descriptor_number; insertion > 0; --insertion) { | 2153 for (insertion = descriptor_number; insertion > 0; --insertion) { |
2179 String* key = GetSortedKey(insertion - 1); | 2154 String* key = GetSortedKey(insertion - 1); |
2180 if (key->Hash() <= hash) break; | 2155 if (key->Hash() <= hash) break; |
2181 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); | 2156 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); |
2182 } | 2157 } |
2183 | 2158 |
2184 SetSortedKey(insertion, descriptor_number); | 2159 SetSortedKey(insertion, descriptor_number); |
2185 } | 2160 } |
2186 | 2161 |
2187 | 2162 |
2188 void DescriptorArray::Append(Descriptor* desc) { | |
2189 int descriptor_number = number_of_descriptors(); | |
2190 int enumeration_index = descriptor_number + 1; | |
2191 SetNumberOfDescriptors(descriptor_number + 1); | |
2192 desc->SetEnumerationIndex(enumeration_index); | |
2193 Set(descriptor_number, desc); | |
2194 | |
2195 uint32_t hash = desc->GetKey()->Hash(); | |
2196 | |
2197 int insertion; | |
2198 | |
2199 for (insertion = descriptor_number; insertion > 0; --insertion) { | |
2200 String* key = GetSortedKey(insertion - 1); | |
2201 if (key->Hash() <= hash) break; | |
2202 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); | |
2203 } | |
2204 | |
2205 SetSortedKey(insertion, descriptor_number); | |
2206 } | |
2207 | |
2208 | |
2209 void DescriptorArray::SwapSortedKeys(int first, int second) { | 2163 void DescriptorArray::SwapSortedKeys(int first, int second) { |
2210 int first_key = GetSortedKeyIndex(first); | 2164 int first_key = GetSortedKeyIndex(first); |
2211 SetSortedKey(first, GetSortedKeyIndex(second)); | 2165 SetSortedKey(first, GetSortedKeyIndex(second)); |
2212 SetSortedKey(second, first_key); | 2166 SetSortedKey(second, first_key); |
2213 } | 2167 } |
2214 | 2168 |
2215 | 2169 |
2216 DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array) | 2170 DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array) |
2217 : marking_(array->GetHeap()->incremental_marking()) { | 2171 : marking_(array->GetHeap()->incremental_marking()) { |
2218 marking_->EnterNoMarkingScope(); | 2172 marking_->EnterNoMarkingScope(); |
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3553 | 3507 |
3554 | 3508 |
3555 DescriptorArray* Map::instance_descriptors() { | 3509 DescriptorArray* Map::instance_descriptors() { |
3556 if (HasTransitionArray()) return transitions()->descriptors(); | 3510 if (HasTransitionArray()) return transitions()->descriptors(); |
3557 Object* back_pointer = GetBackPointer(); | 3511 Object* back_pointer = GetBackPointer(); |
3558 if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array(); | 3512 if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array(); |
3559 return Map::cast(back_pointer)->instance_descriptors(); | 3513 return Map::cast(back_pointer)->instance_descriptors(); |
3560 } | 3514 } |
3561 | 3515 |
3562 | 3516 |
3563 enum TransitionsKind { DESCRIPTORS_HOLDER, FULL_TRANSITION_ARRAY }; | |
3564 | |
3565 | |
3566 // If the descriptor is using the empty transition array, install a new empty | 3517 // If the descriptor is using the empty transition array, install a new empty |
3567 // transition array that will have place for an element transition. | 3518 // transition array that will have place for an element transition. |
3568 static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) { | 3519 static MaybeObject* EnsureHasTransitionArray(Map* map) { |
| 3520 if (map->HasTransitionArray()) return map; |
| 3521 |
3569 TransitionArray* transitions; | 3522 TransitionArray* transitions; |
3570 MaybeObject* maybe_transitions; | 3523 JSGlobalPropertyCell* pointer = map->RetrieveDescriptorsPointer(); |
3571 if (map->HasTransitionArray()) { | 3524 MaybeObject* maybe_transitions = TransitionArray::Allocate(0, pointer); |
3572 if (kind != FULL_TRANSITION_ARRAY || | 3525 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
3573 map->transitions()->IsFullTransitionArray()) { | 3526 |
3574 return map; | 3527 transitions->set_back_pointer_storage(map->GetBackPointer()); |
3575 } | |
3576 maybe_transitions = map->transitions()->ExtendToFullTransitionArray(); | |
3577 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | |
3578 } else { | |
3579 JSGlobalPropertyCell* pointer = map->RetrieveDescriptorsPointer(); | |
3580 if (kind == FULL_TRANSITION_ARRAY) { | |
3581 maybe_transitions = TransitionArray::Allocate(0, pointer); | |
3582 } else { | |
3583 maybe_transitions = TransitionArray::AllocateDescriptorsHolder(pointer); | |
3584 } | |
3585 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | |
3586 transitions->set_back_pointer_storage(map->GetBackPointer()); | |
3587 } | |
3588 map->set_transitions(transitions); | 3528 map->set_transitions(transitions); |
3589 return transitions; | 3529 return transitions; |
3590 } | 3530 } |
3591 | 3531 |
3592 | 3532 |
3593 MaybeObject* Map::SetDescriptors(DescriptorArray* value) { | 3533 MaybeObject* Map::SetDescriptors(DescriptorArray* value) { |
3594 ASSERT(!is_shared()); | 3534 ASSERT(!is_shared()); |
3595 MaybeObject* maybe_failure = | 3535 MaybeObject* maybe_failure = EnsureHasTransitionArray(this); |
3596 EnsureHasTransitionArray(this, DESCRIPTORS_HOLDER); | |
3597 if (maybe_failure->IsFailure()) return maybe_failure; | 3536 if (maybe_failure->IsFailure()) return maybe_failure; |
3598 | 3537 |
3599 ASSERT(NumberOfOwnDescriptors() <= value->number_of_descriptors()); | 3538 ASSERT(NumberOfOwnDescriptors() <= value->number_of_descriptors()); |
3600 transitions()->set_descriptors(value); | 3539 transitions()->set_descriptors(value); |
3601 return this; | 3540 return this; |
3602 } | 3541 } |
3603 | 3542 |
3604 | 3543 |
3605 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { | 3544 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { |
3606 int len = descriptors->number_of_descriptors(); | 3545 int len = descriptors->number_of_descriptors(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3645 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer); | 3584 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer); |
3646 CONDITIONAL_WRITE_BARRIER( | 3585 CONDITIONAL_WRITE_BARRIER( |
3647 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode); | 3586 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode); |
3648 } | 3587 } |
3649 | 3588 |
3650 | 3589 |
3651 void Map::AppendDescriptor(Descriptor* desc, | 3590 void Map::AppendDescriptor(Descriptor* desc, |
3652 const DescriptorArray::WhitenessWitness& witness) { | 3591 const DescriptorArray::WhitenessWitness& witness) { |
3653 DescriptorArray* descriptors = instance_descriptors(); | 3592 DescriptorArray* descriptors = instance_descriptors(); |
3654 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 3593 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
3655 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); | 3594 ASSERT(number_of_own_descriptors < descriptors->number_of_descriptors()); |
3656 descriptors->Append(desc, witness); | 3595 descriptors->Append(desc, witness, number_of_own_descriptors); |
3657 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); | 3596 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); |
3658 } | 3597 } |
3659 | 3598 |
3660 | 3599 |
3661 Object* Map::GetBackPointer() { | 3600 Object* Map::GetBackPointer() { |
3662 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); | 3601 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
3663 if (object->IsDescriptorArray()) { | 3602 if (object->IsDescriptorArray()) { |
3664 return TransitionArray::cast(object)->back_pointer_storage(); | 3603 return TransitionArray::cast(object)->back_pointer_storage(); |
3665 } else { | 3604 } else { |
3666 ASSERT(object->IsMap() || object->IsUndefined()); | 3605 ASSERT(object->IsMap() || object->IsUndefined()); |
(...skipping 29 matching lines...) Expand all Loading... |
3696 JSGlobalPropertyCell* Map::RetrieveDescriptorsPointer() { | 3635 JSGlobalPropertyCell* Map::RetrieveDescriptorsPointer() { |
3697 if (!owns_descriptors()) return NULL; | 3636 if (!owns_descriptors()) return NULL; |
3698 Object* back_pointer = GetBackPointer(); | 3637 Object* back_pointer = GetBackPointer(); |
3699 if (back_pointer->IsUndefined()) return NULL; | 3638 if (back_pointer->IsUndefined()) return NULL; |
3700 Map* map = Map::cast(back_pointer); | 3639 Map* map = Map::cast(back_pointer); |
3701 ASSERT(map->HasTransitionArray()); | 3640 ASSERT(map->HasTransitionArray()); |
3702 return map->transitions()->descriptors_pointer(); | 3641 return map->transitions()->descriptors_pointer(); |
3703 } | 3642 } |
3704 | 3643 |
3705 | 3644 |
3706 MaybeObject* Map::AddTransition(String* key, | 3645 MaybeObject* Map::AddTransition(String* key, Map* target) { |
3707 Map* target, | |
3708 SimpleTransitionFlag flag) { | |
3709 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); | 3646 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); |
3710 JSGlobalPropertyCell* descriptors_pointer = RetrieveDescriptorsPointer(); | 3647 JSGlobalPropertyCell* descriptors_pointer = RetrieveDescriptorsPointer(); |
3711 return TransitionArray::NewWith( | 3648 return TransitionArray::NewWith( |
3712 flag, key, target, descriptors_pointer, GetBackPointer()); | 3649 key, target, descriptors_pointer, GetBackPointer()); |
3713 } | 3650 } |
3714 | 3651 |
3715 | 3652 |
3716 void Map::SetTransition(int transition_index, Map* target) { | 3653 void Map::SetTransition(int transition_index, Map* target) { |
3717 transitions()->SetTarget(transition_index, target); | 3654 transitions()->SetTarget(transition_index, target); |
3718 } | 3655 } |
3719 | 3656 |
3720 | 3657 |
3721 Map* Map::GetTransition(int transition_index) { | 3658 Map* Map::GetTransition(int transition_index) { |
3722 return transitions()->GetTarget(transition_index); | 3659 return transitions()->GetTarget(transition_index); |
3723 } | 3660 } |
3724 | 3661 |
3725 | 3662 |
3726 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { | 3663 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { |
3727 MaybeObject* allow_elements = | 3664 MaybeObject* allow_elements = EnsureHasTransitionArray(this); |
3728 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); | |
3729 if (allow_elements->IsFailure()) return allow_elements; | 3665 if (allow_elements->IsFailure()) return allow_elements; |
3730 transitions()->set_elements_transition(transitioned_map); | 3666 transitions()->set_elements_transition(transitioned_map); |
3731 return this; | 3667 return this; |
3732 } | 3668 } |
3733 | 3669 |
3734 | 3670 |
3735 FixedArray* Map::GetPrototypeTransitions() { | 3671 FixedArray* Map::GetPrototypeTransitions() { |
3736 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); | 3672 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); |
3737 if (!transitions()->HasPrototypeTransitions()) { | 3673 if (!transitions()->HasPrototypeTransitions()) { |
3738 return GetHeap()->empty_fixed_array(); | 3674 return GetHeap()->empty_fixed_array(); |
3739 } | 3675 } |
3740 return transitions()->GetPrototypeTransitions(); | 3676 return transitions()->GetPrototypeTransitions(); |
3741 } | 3677 } |
3742 | 3678 |
3743 | 3679 |
3744 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { | 3680 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { |
3745 MaybeObject* allow_prototype = | 3681 MaybeObject* allow_prototype = EnsureHasTransitionArray(this); |
3746 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); | |
3747 if (allow_prototype->IsFailure()) return allow_prototype; | 3682 if (allow_prototype->IsFailure()) return allow_prototype; |
3748 #ifdef DEBUG | 3683 #ifdef DEBUG |
3749 if (HasPrototypeTransitions()) { | 3684 if (HasPrototypeTransitions()) { |
3750 ASSERT(GetPrototypeTransitions() != proto_transitions); | 3685 ASSERT(GetPrototypeTransitions() != proto_transitions); |
3751 ZapPrototypeTransitions(); | 3686 ZapPrototypeTransitions(); |
3752 } | 3687 } |
3753 #endif | 3688 #endif |
3754 transitions()->SetPrototypeTransitions(proto_transitions); | 3689 transitions()->SetPrototypeTransitions(proto_transitions); |
3755 return this; | 3690 return this; |
3756 } | 3691 } |
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4942 // Slow case: compute hash code and set it. | 4877 // Slow case: compute hash code and set it. |
4943 return ComputeAndSetHash(); | 4878 return ComputeAndSetHash(); |
4944 } | 4879 } |
4945 | 4880 |
4946 | 4881 |
4947 StringHasher::StringHasher(int length, uint32_t seed) | 4882 StringHasher::StringHasher(int length, uint32_t seed) |
4948 : length_(length), | 4883 : length_(length), |
4949 raw_running_hash_(seed), | 4884 raw_running_hash_(seed), |
4950 array_index_(0), | 4885 array_index_(0), |
4951 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), | 4886 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), |
4952 is_first_char_(true) { | 4887 is_first_char_(true), |
| 4888 is_valid_(true) { |
4953 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0); | 4889 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0); |
4954 } | 4890 } |
4955 | 4891 |
4956 | 4892 |
4957 bool StringHasher::has_trivial_hash() { | 4893 bool StringHasher::has_trivial_hash() { |
4958 return length_ > String::kMaxHashCalcLength; | 4894 return length_ > String::kMaxHashCalcLength; |
4959 } | 4895 } |
4960 | 4896 |
4961 | 4897 |
4962 uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint32_t c) { | |
4963 running_hash += c; | |
4964 running_hash += (running_hash << 10); | |
4965 running_hash ^= (running_hash >> 6); | |
4966 return running_hash; | |
4967 } | |
4968 | |
4969 | |
4970 uint32_t StringHasher::GetHashCore(uint32_t running_hash) { | |
4971 running_hash += (running_hash << 3); | |
4972 running_hash ^= (running_hash >> 11); | |
4973 running_hash += (running_hash << 15); | |
4974 if ((running_hash & String::kHashBitMask) == 0) { | |
4975 return 27; | |
4976 } | |
4977 return running_hash; | |
4978 } | |
4979 | |
4980 | |
4981 void StringHasher::AddCharacter(uint32_t c) { | 4898 void StringHasher::AddCharacter(uint32_t c) { |
4982 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { | 4899 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { |
4983 AddSurrogatePair(c); // Not inlined. | 4900 AddSurrogatePair(c); // Not inlined. |
4984 return; | 4901 return; |
4985 } | 4902 } |
4986 // Use the Jenkins one-at-a-time hash function to update the hash | 4903 // Use the Jenkins one-at-a-time hash function to update the hash |
4987 // for the given character. | 4904 // for the given character. |
4988 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c); | 4905 raw_running_hash_ += c; |
| 4906 raw_running_hash_ += (raw_running_hash_ << 10); |
| 4907 raw_running_hash_ ^= (raw_running_hash_ >> 6); |
4989 // Incremental array index computation. | 4908 // Incremental array index computation. |
4990 if (is_array_index_) { | 4909 if (is_array_index_) { |
4991 if (c < '0' || c > '9') { | 4910 if (c < '0' || c > '9') { |
4992 is_array_index_ = false; | 4911 is_array_index_ = false; |
4993 } else { | 4912 } else { |
4994 int d = c - '0'; | 4913 int d = c - '0'; |
4995 if (is_first_char_) { | 4914 if (is_first_char_) { |
4996 is_first_char_ = false; | 4915 is_first_char_ = false; |
4997 if (c == '0' && length_ > 1) { | 4916 if (c == '0' && length_ > 1) { |
4998 is_array_index_ = false; | 4917 is_array_index_ = false; |
4999 return; | 4918 return; |
5000 } | 4919 } |
5001 } | 4920 } |
5002 if (array_index_ > 429496729U - ((d + 2) >> 3)) { | 4921 if (array_index_ > 429496729U - ((d + 2) >> 3)) { |
5003 is_array_index_ = false; | 4922 is_array_index_ = false; |
5004 } else { | 4923 } else { |
5005 array_index_ = array_index_ * 10 + d; | 4924 array_index_ = array_index_ * 10 + d; |
5006 } | 4925 } |
5007 } | 4926 } |
5008 } | 4927 } |
5009 } | 4928 } |
5010 | 4929 |
5011 | 4930 |
5012 void StringHasher::AddCharacterNoIndex(uint32_t c) { | 4931 void StringHasher::AddCharacterNoIndex(uint32_t c) { |
5013 ASSERT(!is_array_index()); | 4932 ASSERT(!is_array_index()); |
5014 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { | 4933 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { |
5015 AddSurrogatePairNoIndex(c); // Not inlined. | 4934 AddSurrogatePairNoIndex(c); // Not inlined. |
5016 return; | 4935 return; |
5017 } | 4936 } |
5018 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c); | 4937 raw_running_hash_ += c; |
| 4938 raw_running_hash_ += (raw_running_hash_ << 10); |
| 4939 raw_running_hash_ ^= (raw_running_hash_ >> 6); |
5019 } | 4940 } |
5020 | 4941 |
5021 | 4942 |
5022 uint32_t StringHasher::GetHash() { | 4943 uint32_t StringHasher::GetHash() { |
5023 // Get the calculated raw hash value and do some more bit ops to distribute | 4944 // Get the calculated raw hash value and do some more bit ops to distribute |
5024 // the hash further. Ensure that we never return zero as the hash value. | 4945 // the hash further. Ensure that we never return zero as the hash value. |
5025 return GetHashCore(raw_running_hash_); | 4946 uint32_t result = raw_running_hash_; |
| 4947 result += (result << 3); |
| 4948 result ^= (result >> 11); |
| 4949 result += (result << 15); |
| 4950 if ((result & String::kHashBitMask) == 0) { |
| 4951 result = 27; |
| 4952 } |
| 4953 return result; |
5026 } | 4954 } |
5027 | 4955 |
5028 | 4956 |
5029 template <typename schar> | 4957 template <typename schar> |
5030 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) { | 4958 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) { |
5031 StringHasher hasher(length, seed); | 4959 StringHasher hasher(length, seed); |
5032 if (!hasher.has_trivial_hash()) { | 4960 if (!hasher.has_trivial_hash()) { |
5033 int i; | 4961 int i; |
5034 for (i = 0; hasher.is_array_index() && (i < length); i++) { | 4962 for (i = 0; hasher.is_array_index() && (i < length); i++) { |
5035 hasher.AddCharacter(chars[i]); | 4963 hasher.AddCharacter(chars[i]); |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5557 #undef WRITE_UINT32_FIELD | 5485 #undef WRITE_UINT32_FIELD |
5558 #undef READ_SHORT_FIELD | 5486 #undef READ_SHORT_FIELD |
5559 #undef WRITE_SHORT_FIELD | 5487 #undef WRITE_SHORT_FIELD |
5560 #undef READ_BYTE_FIELD | 5488 #undef READ_BYTE_FIELD |
5561 #undef WRITE_BYTE_FIELD | 5489 #undef WRITE_BYTE_FIELD |
5562 | 5490 |
5563 | 5491 |
5564 } } // namespace v8::internal | 5492 } } // namespace v8::internal |
5565 | 5493 |
5566 #endif // V8_OBJECTS_INL_H_ | 5494 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |