| 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 |