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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 | 375 |
376 | 376 |
377 uint32_t StringShape::full_representation_tag() { | 377 uint32_t StringShape::full_representation_tag() { |
378 return (type_ & (kStringRepresentationMask | kStringEncodingMask)); | 378 return (type_ & (kStringRepresentationMask | kStringEncodingMask)); |
379 } | 379 } |
380 | 380 |
381 | 381 |
382 STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) == | 382 STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) == |
383 Internals::kFullStringRepresentationMask); | 383 Internals::kFullStringRepresentationMask); |
384 | 384 |
385 STATIC_CHECK(static_cast<uint32_t>(kStringEncodingMask) == | |
386 Internals::kStringEncodingMask); | |
387 | |
388 | 385 |
389 bool StringShape::IsSequentialAscii() { | 386 bool StringShape::IsSequentialAscii() { |
390 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag); | 387 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag); |
391 } | 388 } |
392 | 389 |
393 | 390 |
394 bool StringShape::IsSequentialTwoByte() { | 391 bool StringShape::IsSequentialTwoByte() { |
395 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag); | 392 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag); |
396 } | 393 } |
397 | 394 |
398 | 395 |
399 bool StringShape::IsExternalAscii() { | 396 bool StringShape::IsExternalAscii() { |
400 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag); | 397 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag); |
401 } | 398 } |
402 | 399 |
403 | 400 |
404 STATIC_CHECK((kExternalStringTag | kAsciiStringTag) == | |
405 Internals::kExternalAsciiRepresentationTag); | |
406 | |
407 STATIC_CHECK(v8::String::ASCII_ENCODING == kAsciiStringTag); | |
408 | |
409 | |
410 bool StringShape::IsExternalTwoByte() { | 401 bool StringShape::IsExternalTwoByte() { |
411 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag); | 402 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag); |
412 } | 403 } |
413 | 404 |
414 | 405 |
415 STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) == | 406 STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) == |
416 Internals::kExternalTwoByteRepresentationTag); | 407 Internals::kExternalTwoByteRepresentationTag); |
417 | 408 |
418 STATIC_CHECK(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag); | |
419 | 409 |
420 uc32 FlatStringReader::Get(int index) { | 410 uc32 FlatStringReader::Get(int index) { |
421 ASSERT(0 <= index && index <= length_); | 411 ASSERT(0 <= index && index <= length_); |
422 if (is_ascii_) { | 412 if (is_ascii_) { |
423 return static_cast<const byte*>(start_)[index]; | 413 return static_cast<const byte*>(start_)[index]; |
424 } else { | 414 } else { |
425 return static_cast<const uc16*>(start_)[index]; | 415 return static_cast<const uc16*>(start_)[index]; |
426 } | 416 } |
427 } | 417 } |
428 | 418 |
(...skipping 1470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1899 } | 1889 } |
1900 | 1890 |
1901 | 1891 |
1902 bool DescriptorArray::IsEmpty() { | 1892 bool DescriptorArray::IsEmpty() { |
1903 ASSERT(length() >= kFirstIndex || | 1893 ASSERT(length() >= kFirstIndex || |
1904 this == HEAP->empty_descriptor_array()); | 1894 this == HEAP->empty_descriptor_array()); |
1905 return length() < kFirstIndex; | 1895 return length() < kFirstIndex; |
1906 } | 1896 } |
1907 | 1897 |
1908 | 1898 |
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 | 1899 // 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 | 1900 // there are three entries in this array it should be called with low=0 and |
1917 // high=2. | 1901 // high=2. |
1918 template<typename T> | 1902 template<typename T> |
1919 int BinarySearch(T* array, String* name, int low, int high) { | 1903 int BinarySearch(T* array, String* name, int low, int high) { |
1920 uint32_t hash = name->Hash(); | 1904 uint32_t hash = name->Hash(); |
1921 int limit = high; | 1905 int limit = high; |
1922 | 1906 |
1923 ASSERT(low <= high); | 1907 ASSERT(low <= high); |
1924 | 1908 |
(...skipping 14 matching lines...) Expand all Loading... |
1939 String* entry = array->GetKey(sort_index); | 1923 String* entry = array->GetKey(sort_index); |
1940 if (entry->Hash() != hash) break; | 1924 if (entry->Hash() != hash) break; |
1941 if (entry->Equals(name)) return sort_index; | 1925 if (entry->Equals(name)) return sort_index; |
1942 } | 1926 } |
1943 | 1927 |
1944 return T::kNotFound; | 1928 return T::kNotFound; |
1945 } | 1929 } |
1946 | 1930 |
1947 // Perform a linear search in this fixed array. len is the number of entry | 1931 // Perform a linear search in this fixed array. len is the number of entry |
1948 // indices that are valid. | 1932 // indices that are valid. |
1949 template<SearchMode search_mode, typename T> | 1933 template<typename T> |
1950 int LinearSearch(T* array, String* name, int len, int valid_entries) { | 1934 int LinearSearch(T* array, String* name, int len) { |
1951 uint32_t hash = name->Hash(); | 1935 uint32_t hash = name->Hash(); |
1952 if (search_mode == ALL_ENTRIES) { | 1936 for (int number = 0; number < len; number++) { |
1953 for (int number = 0; number < len; number++) { | 1937 int sorted_index = array->GetSortedKeyIndex(number); |
1954 int sorted_index = array->GetSortedKeyIndex(number); | 1938 String* entry = array->GetKey(sorted_index); |
1955 String* entry = array->GetKey(sorted_index); | 1939 uint32_t current_hash = entry->Hash(); |
1956 uint32_t current_hash = entry->Hash(); | 1940 if (current_hash > hash) break; |
1957 if (current_hash > hash) break; | 1941 if (current_hash == hash && entry->Equals(name)) return sorted_index; |
1958 if (current_hash == hash && entry->Equals(name)) return sorted_index; | |
1959 } | |
1960 } else { | |
1961 ASSERT(len >= valid_entries); | |
1962 for (int number = 0; number < valid_entries; number++) { | |
1963 String* entry = array->GetKey(number); | |
1964 uint32_t current_hash = entry->Hash(); | |
1965 if (current_hash == hash && entry->Equals(name)) return number; | |
1966 } | |
1967 } | 1942 } |
1968 return T::kNotFound; | 1943 return T::kNotFound; |
1969 } | 1944 } |
1970 | 1945 |
1971 | 1946 |
1972 template<SearchMode search_mode, typename T> | 1947 template<typename T> |
1973 int Search(T* array, String* name, int valid_entries) { | 1948 int Search(T* array, String* name) { |
1974 if (search_mode == VALID_ENTRIES) { | 1949 SLOW_ASSERT(array->IsSortedNoDuplicates()); |
1975 SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries)); | |
1976 } else { | |
1977 SLOW_ASSERT(array->IsSortedNoDuplicates()); | |
1978 } | |
1979 | 1950 |
1980 int nof = array->number_of_entries(); | 1951 int nof = array->number_of_entries(); |
1981 if (nof == 0) return T::kNotFound; | 1952 if (nof == 0) return T::kNotFound; |
1982 | 1953 |
1983 // Fast case: do linear search for small arrays. | 1954 // Fast case: do linear search for small arrays. |
1984 const int kMaxElementsForLinearSearch = 8; | 1955 const int kMaxElementsForLinearSearch = 8; |
1985 if (search_mode == VALID_ENTRIES || | 1956 if (nof < kMaxElementsForLinearSearch) { |
1986 (search_mode == ALL_ENTRIES && nof < kMaxElementsForLinearSearch)) { | 1957 return LinearSearch(array, name, nof); |
1987 return LinearSearch<search_mode>(array, name, nof, valid_entries); | |
1988 } | 1958 } |
1989 | 1959 |
1990 // Slow case: perform binary search. | 1960 // Slow case: perform binary search. |
1991 return BinarySearch(array, name, 0, nof - 1); | 1961 return BinarySearch(array, name, 0, nof - 1); |
1992 } | 1962 } |
1993 | 1963 |
1994 | 1964 |
1995 int DescriptorArray::Search(String* name, int valid_descriptors) { | 1965 int DescriptorArray::Search(String* name) { |
1996 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors); | 1966 return internal::Search(this, name); |
1997 } | 1967 } |
1998 | 1968 |
1999 | 1969 |
2000 int DescriptorArray::SearchWithCache(String* name, Map* map) { | 1970 int DescriptorArray::SearchWithCache(String* name) { |
2001 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 1971 if (number_of_descriptors() == 0) return kNotFound; |
2002 if (number_of_own_descriptors == 0) return kNotFound; | |
2003 | 1972 |
2004 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache(); | 1973 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache(); |
2005 int number = cache->Lookup(map, name); | 1974 int number = cache->Lookup(this, name); |
2006 | 1975 |
2007 if (number == DescriptorLookupCache::kAbsent) { | 1976 if (number == DescriptorLookupCache::kAbsent) { |
2008 number = Search(name, number_of_own_descriptors); | 1977 number = Search(name); |
2009 cache->Update(map, name, number); | 1978 cache->Update(this, name, number); |
2010 } | 1979 } |
2011 | 1980 |
2012 return number; | 1981 return number; |
2013 } | 1982 } |
2014 | 1983 |
2015 | 1984 |
2016 void Map::LookupDescriptor(JSObject* holder, | 1985 void Map::LookupDescriptor(JSObject* holder, |
2017 String* name, | 1986 String* name, |
2018 LookupResult* result) { | 1987 LookupResult* result) { |
2019 DescriptorArray* descriptors = this->instance_descriptors(); | 1988 DescriptorArray* descriptors = this->instance_descriptors(); |
2020 int number = descriptors->SearchWithCache(name, this); | 1989 int number = descriptors->SearchWithCache(name); |
2021 if (number == DescriptorArray::kNotFound) return result->NotFound(); | 1990 if (number == DescriptorArray::kNotFound) return result->NotFound(); |
2022 result->DescriptorResult(holder, descriptors->GetDetails(number), number); | 1991 result->DescriptorResult(holder, descriptors->GetDetails(number), number); |
2023 } | 1992 } |
2024 | 1993 |
2025 | 1994 |
2026 void Map::LookupTransition(JSObject* holder, | 1995 void Map::LookupTransition(JSObject* holder, |
2027 String* name, | 1996 String* name, |
2028 LookupResult* result) { | 1997 LookupResult* result) { |
2029 if (HasTransitionArray()) { | 1998 if (HasTransitionArray()) { |
2030 TransitionArray* transition_array = transitions(); | 1999 TransitionArray* transition_array = transitions(); |
(...skipping 23 matching lines...) Expand all Loading... |
2054 int DescriptorArray::GetSortedKeyIndex(int descriptor_number) { | 2023 int DescriptorArray::GetSortedKeyIndex(int descriptor_number) { |
2055 return GetDetails(descriptor_number).pointer(); | 2024 return GetDetails(descriptor_number).pointer(); |
2056 } | 2025 } |
2057 | 2026 |
2058 | 2027 |
2059 String* DescriptorArray::GetSortedKey(int descriptor_number) { | 2028 String* DescriptorArray::GetSortedKey(int descriptor_number) { |
2060 return GetKey(GetSortedKeyIndex(descriptor_number)); | 2029 return GetKey(GetSortedKeyIndex(descriptor_number)); |
2061 } | 2030 } |
2062 | 2031 |
2063 | 2032 |
2064 void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) { | 2033 void DescriptorArray::SetSortedKey(int pointer, int descriptor_number) { |
2065 PropertyDetails details = GetDetails(descriptor_index); | 2034 int details_index = ToDetailsIndex(pointer); |
2066 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi()); | 2035 PropertyDetails details = PropertyDetails(Smi::cast(get(details_index))); |
| 2036 set_unchecked(details_index, details.set_pointer(descriptor_number).AsSmi()); |
2067 } | 2037 } |
2068 | 2038 |
2069 | 2039 |
2070 Object** DescriptorArray::GetValueSlot(int descriptor_number) { | 2040 Object** DescriptorArray::GetValueSlot(int descriptor_number) { |
2071 ASSERT(descriptor_number < number_of_descriptors()); | 2041 ASSERT(descriptor_number < number_of_descriptors()); |
2072 return HeapObject::RawField( | 2042 return HeapObject::RawField( |
2073 reinterpret_cast<HeapObject*>(this), | 2043 reinterpret_cast<HeapObject*>(this), |
2074 OffsetOfElementAt(ToValueIndex(descriptor_number))); | 2044 OffsetOfElementAt(ToValueIndex(descriptor_number))); |
2075 } | 2045 } |
2076 | 2046 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2137 desc->GetKey()); | 2107 desc->GetKey()); |
2138 NoIncrementalWriteBarrierSet(this, | 2108 NoIncrementalWriteBarrierSet(this, |
2139 ToValueIndex(descriptor_number), | 2109 ToValueIndex(descriptor_number), |
2140 desc->GetValue()); | 2110 desc->GetValue()); |
2141 NoIncrementalWriteBarrierSet(this, | 2111 NoIncrementalWriteBarrierSet(this, |
2142 ToDetailsIndex(descriptor_number), | 2112 ToDetailsIndex(descriptor_number), |
2143 desc->GetDetails().AsSmi()); | 2113 desc->GetDetails().AsSmi()); |
2144 } | 2114 } |
2145 | 2115 |
2146 | 2116 |
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, | 2117 void DescriptorArray::Append(Descriptor* desc, |
2167 const WhitenessWitness& witness) { | 2118 const WhitenessWitness& witness, |
2168 int descriptor_number = number_of_descriptors(); | 2119 int number_of_set_descriptors) { |
2169 int enumeration_index = descriptor_number + 1; | 2120 int enumeration_index = number_of_set_descriptors + 1; |
2170 SetNumberOfDescriptors(descriptor_number + 1); | |
2171 desc->SetEnumerationIndex(enumeration_index); | 2121 desc->SetEnumerationIndex(enumeration_index); |
2172 Set(descriptor_number, desc, witness); | 2122 Set(number_of_set_descriptors, desc, witness); |
2173 | 2123 |
2174 uint32_t hash = desc->GetKey()->Hash(); | 2124 uint32_t hash = desc->GetKey()->Hash(); |
2175 | 2125 |
2176 int insertion; | 2126 int insertion; |
2177 | 2127 |
2178 for (insertion = descriptor_number; insertion > 0; --insertion) { | 2128 for (insertion = number_of_set_descriptors; insertion > 0; --insertion) { |
2179 String* key = GetSortedKey(insertion - 1); | 2129 String* key = GetSortedKey(insertion - 1); |
2180 if (key->Hash() <= hash) break; | 2130 if (key->Hash() <= hash) break; |
2181 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); | 2131 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); |
2182 } | 2132 } |
2183 | 2133 |
2184 SetSortedKey(insertion, descriptor_number); | 2134 SetSortedKey(insertion, number_of_set_descriptors); |
2185 } | 2135 } |
2186 | 2136 |
2187 | 2137 |
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) { | 2138 void DescriptorArray::SwapSortedKeys(int first, int second) { |
2210 int first_key = GetSortedKeyIndex(first); | 2139 int first_key = GetSortedKeyIndex(first); |
2211 SetSortedKey(first, GetSortedKeyIndex(second)); | 2140 SetSortedKey(first, GetSortedKeyIndex(second)); |
2212 SetSortedKey(second, first_key); | 2141 SetSortedKey(second, first_key); |
2213 } | 2142 } |
2214 | 2143 |
2215 | 2144 |
2216 DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array) | 2145 FixedArray::WhitenessWitness::WhitenessWitness(FixedArray* array) |
2217 : marking_(array->GetHeap()->incremental_marking()) { | 2146 : marking_(array->GetHeap()->incremental_marking()) { |
2218 marking_->EnterNoMarkingScope(); | 2147 marking_->EnterNoMarkingScope(); |
2219 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT); | 2148 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT); |
2220 } | 2149 } |
2221 | 2150 |
2222 | 2151 |
2223 DescriptorArray::WhitenessWitness::~WhitenessWitness() { | 2152 FixedArray::WhitenessWitness::~WhitenessWitness() { |
2224 marking_->LeaveNoMarkingScope(); | 2153 marking_->LeaveNoMarkingScope(); |
2225 } | 2154 } |
2226 | 2155 |
2227 | 2156 |
2228 template<typename Shape, typename Key> | 2157 template<typename Shape, typename Key> |
2229 int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) { | 2158 int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) { |
2230 const int kMinCapacity = 32; | 2159 const int kMinCapacity = 32; |
2231 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); | 2160 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); |
2232 if (capacity < kMinCapacity) { | 2161 if (capacity < kMinCapacity) { |
2233 capacity = kMinCapacity; // Guarantee min capacity. | 2162 capacity = kMinCapacity; // Guarantee min capacity. |
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3094 JSFunction* Map::unchecked_constructor() { | 3023 JSFunction* Map::unchecked_constructor() { |
3095 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset)); | 3024 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset)); |
3096 } | 3025 } |
3097 | 3026 |
3098 | 3027 |
3099 Code::Flags Code::flags() { | 3028 Code::Flags Code::flags() { |
3100 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); | 3029 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); |
3101 } | 3030 } |
3102 | 3031 |
3103 | 3032 |
3104 void Map::set_owns_descriptors(bool is_shared) { | |
3105 set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared)); | |
3106 } | |
3107 | |
3108 | |
3109 bool Map::owns_descriptors() { | |
3110 return OwnsDescriptors::decode(bit_field3()); | |
3111 } | |
3112 | |
3113 | |
3114 void Code::set_flags(Code::Flags flags) { | 3033 void Code::set_flags(Code::Flags flags) { |
3115 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); | 3034 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); |
3116 // Make sure that all call stubs have an arguments count. | 3035 // Make sure that all call stubs have an arguments count. |
3117 ASSERT((ExtractKindFromFlags(flags) != CALL_IC && | 3036 ASSERT((ExtractKindFromFlags(flags) != CALL_IC && |
3118 ExtractKindFromFlags(flags) != KEYED_CALL_IC) || | 3037 ExtractKindFromFlags(flags) != KEYED_CALL_IC) || |
3119 ExtractArgumentsCountFromFlags(flags) >= 0); | 3038 ExtractArgumentsCountFromFlags(flags) >= 0); |
3120 WRITE_INT_FIELD(this, kFlagsOffset, flags); | 3039 WRITE_INT_FIELD(this, kFlagsOffset, flags); |
3121 } | 3040 } |
3122 | 3041 |
3123 | 3042 |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3539 } | 3458 } |
3540 | 3459 |
3541 | 3460 |
3542 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 3461 void Map::set_prototype(Object* value, WriteBarrierMode mode) { |
3543 ASSERT(value->IsNull() || value->IsJSReceiver()); | 3462 ASSERT(value->IsNull() || value->IsJSReceiver()); |
3544 WRITE_FIELD(this, kPrototypeOffset, value); | 3463 WRITE_FIELD(this, kPrototypeOffset, value); |
3545 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); | 3464 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); |
3546 } | 3465 } |
3547 | 3466 |
3548 | 3467 |
3549 JSGlobalPropertyCell* Map::descriptors_pointer() { | |
3550 ASSERT(HasTransitionArray()); | |
3551 return transitions()->descriptors_pointer(); | |
3552 } | |
3553 | |
3554 | |
3555 DescriptorArray* Map::instance_descriptors() { | 3468 DescriptorArray* Map::instance_descriptors() { |
3556 if (HasTransitionArray()) return transitions()->descriptors(); | 3469 if (!HasTransitionArray()) return GetHeap()->empty_descriptor_array(); |
3557 Object* back_pointer = GetBackPointer(); | 3470 return transitions()->descriptors(); |
3558 if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array(); | |
3559 return Map::cast(back_pointer)->instance_descriptors(); | |
3560 } | 3471 } |
3561 | 3472 |
3562 | 3473 |
3563 enum TransitionsKind { DESCRIPTORS_HOLDER, FULL_TRANSITION_ARRAY }; | |
3564 | |
3565 | |
3566 // If the descriptor is using the empty transition array, install a new empty | 3474 // If the descriptor is using the empty transition array, install a new empty |
3567 // transition array that will have place for an element transition. | 3475 // transition array that will have place for an element transition. |
3568 static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) { | 3476 static MaybeObject* EnsureHasTransitionArray(Map* map) { |
| 3477 if (map->HasTransitionArray()) return map; |
| 3478 |
3569 TransitionArray* transitions; | 3479 TransitionArray* transitions; |
3570 MaybeObject* maybe_transitions; | 3480 MaybeObject* maybe_transitions = TransitionArray::Allocate(0); |
3571 if (map->HasTransitionArray()) { | 3481 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
3572 if (kind != FULL_TRANSITION_ARRAY || | |
3573 map->transitions()->IsFullTransitionArray()) { | |
3574 return map; | |
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); | 3482 map->set_transitions(transitions); |
3589 return transitions; | 3483 return transitions; |
3590 } | 3484 } |
3591 | 3485 |
3592 | 3486 |
3593 MaybeObject* Map::SetDescriptors(DescriptorArray* value) { | 3487 MaybeObject* Map::SetDescriptors(DescriptorArray* value, |
| 3488 WriteBarrierMode mode) { |
3594 ASSERT(!is_shared()); | 3489 ASSERT(!is_shared()); |
3595 MaybeObject* maybe_failure = | 3490 MaybeObject* maybe_failure = EnsureHasTransitionArray(this); |
3596 EnsureHasTransitionArray(this, DESCRIPTORS_HOLDER); | |
3597 if (maybe_failure->IsFailure()) return maybe_failure; | 3491 if (maybe_failure->IsFailure()) return maybe_failure; |
3598 | 3492 |
3599 ASSERT(NumberOfOwnDescriptors() <= value->number_of_descriptors()); | 3493 transitions()->set_descriptors(value, mode); |
3600 transitions()->set_descriptors(value); | |
3601 return this; | 3494 return this; |
3602 } | 3495 } |
3603 | 3496 |
3604 | 3497 |
3605 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { | 3498 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { |
| 3499 #ifdef DEBUG |
3606 int len = descriptors->number_of_descriptors(); | 3500 int len = descriptors->number_of_descriptors(); |
3607 #ifdef DEBUG | |
3608 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); | 3501 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); |
| 3502 SLOW_ASSERT(descriptors->IsSortedNoDuplicates()); |
3609 | 3503 |
3610 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; | 3504 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; |
3611 for (int i = 0; i < len; ++i) used_indices[i] = false; | 3505 for (int i = 0; i < len; ++i) used_indices[i] = false; |
3612 | 3506 |
3613 // Ensure that all enumeration indexes between 1 and length occur uniquely in | 3507 // Ensure that all enumeration indexes between 1 and length occur uniquely in |
3614 // the descriptor array. | 3508 // the descriptor array. |
3615 for (int i = 0; i < len; ++i) { | 3509 for (int i = 0; i < len; ++i) { |
3616 int enum_index = descriptors->GetDetails(i).descriptor_index() - | 3510 int enum_index = descriptors->GetDetails(i).descriptor_index() - |
3617 PropertyDetails::kInitialIndex; | 3511 PropertyDetails::kInitialIndex; |
3618 ASSERT(0 <= enum_index && enum_index < len); | 3512 ASSERT(0 <= enum_index && enum_index < len); |
3619 ASSERT(!used_indices[enum_index]); | 3513 ASSERT(!used_indices[enum_index]); |
3620 used_indices[enum_index] = true; | 3514 used_indices[enum_index] = true; |
3621 } | 3515 } |
3622 #endif | 3516 #endif |
3623 | 3517 |
3624 MaybeObject* maybe_failure = SetDescriptors(descriptors); | 3518 MaybeObject* maybe_failure = SetDescriptors(descriptors); |
3625 if (maybe_failure->IsFailure()) return maybe_failure; | 3519 if (maybe_failure->IsFailure()) return maybe_failure; |
3626 | 3520 |
3627 SetNumberOfOwnDescriptors(len); | 3521 SetNumberOfOwnDescriptors(descriptors->number_of_descriptors()); |
| 3522 |
3628 return this; | 3523 return this; |
3629 } | 3524 } |
3630 | 3525 |
3631 | 3526 |
3632 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) | 3527 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) |
3633 | 3528 |
3634 | 3529 |
3635 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { | 3530 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { |
3636 Object* back_pointer = GetBackPointer(); | 3531 Object* back_pointer = GetBackPointer(); |
3637 #ifdef DEBUG | 3532 #ifdef DEBUG |
3638 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); | 3533 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
3639 if (object->IsTransitionArray()) { | 3534 if (object->IsTransitionArray()) { |
3640 ZapTransitions(); | 3535 ZapTransitions(); |
3641 } else { | 3536 } else { |
3642 ASSERT(object->IsMap() || object->IsUndefined()); | 3537 ASSERT(object->IsMap() || object->IsUndefined()); |
3643 } | 3538 } |
3644 #endif | 3539 #endif |
3645 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer); | 3540 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer); |
3646 CONDITIONAL_WRITE_BARRIER( | 3541 CONDITIONAL_WRITE_BARRIER( |
3647 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode); | 3542 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode); |
3648 } | 3543 } |
3649 | 3544 |
3650 | 3545 |
3651 void Map::AppendDescriptor(Descriptor* desc, | 3546 void Map::AppendDescriptor(Descriptor* desc, |
3652 const DescriptorArray::WhitenessWitness& witness) { | 3547 const DescriptorArray::WhitenessWitness& witness) { |
3653 DescriptorArray* descriptors = instance_descriptors(); | 3548 DescriptorArray* descriptors = instance_descriptors(); |
3654 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 3549 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
3655 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); | 3550 ASSERT(number_of_own_descriptors < descriptors->number_of_descriptors()); |
3656 descriptors->Append(desc, witness); | 3551 descriptors->Append(desc, witness, number_of_own_descriptors); |
3657 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); | 3552 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); |
3658 } | 3553 } |
3659 | 3554 |
3660 | 3555 |
3661 Object* Map::GetBackPointer() { | 3556 Object* Map::GetBackPointer() { |
3662 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); | 3557 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
3663 if (object->IsDescriptorArray()) { | 3558 if (object->IsDescriptorArray()) { |
3664 return TransitionArray::cast(object)->back_pointer_storage(); | 3559 return TransitionArray::cast(object)->back_pointer_storage(); |
3665 } else { | 3560 } else { |
3666 ASSERT(object->IsMap() || object->IsUndefined()); | 3561 ASSERT(object->IsMap() || object->IsUndefined()); |
(...skipping 19 matching lines...) Expand all Loading... |
3686 | 3581 |
3687 | 3582 |
3688 bool Map::CanHaveMoreTransitions() { | 3583 bool Map::CanHaveMoreTransitions() { |
3689 if (!HasTransitionArray()) return true; | 3584 if (!HasTransitionArray()) return true; |
3690 return FixedArray::SizeFor(transitions()->length() + | 3585 return FixedArray::SizeFor(transitions()->length() + |
3691 TransitionArray::kTransitionSize) | 3586 TransitionArray::kTransitionSize) |
3692 <= Page::kMaxNonCodeHeapObjectSize; | 3587 <= Page::kMaxNonCodeHeapObjectSize; |
3693 } | 3588 } |
3694 | 3589 |
3695 | 3590 |
3696 JSGlobalPropertyCell* Map::RetrieveDescriptorsPointer() { | 3591 MaybeObject* Map::AddTransition(String* key, Map* target) { |
3697 if (!owns_descriptors()) return NULL; | 3592 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); |
3698 Object* back_pointer = GetBackPointer(); | 3593 return TransitionArray::NewWith(key, target); |
3699 if (back_pointer->IsUndefined()) return NULL; | |
3700 Map* map = Map::cast(back_pointer); | |
3701 ASSERT(map->HasTransitionArray()); | |
3702 return map->transitions()->descriptors_pointer(); | |
3703 } | 3594 } |
3704 | 3595 |
3705 | 3596 |
3706 MaybeObject* Map::AddTransition(String* key, | |
3707 Map* target, | |
3708 SimpleTransitionFlag flag) { | |
3709 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); | |
3710 JSGlobalPropertyCell* descriptors_pointer = RetrieveDescriptorsPointer(); | |
3711 return TransitionArray::NewWith( | |
3712 flag, key, target, descriptors_pointer, GetBackPointer()); | |
3713 } | |
3714 | |
3715 | |
3716 void Map::SetTransition(int transition_index, Map* target) { | 3597 void Map::SetTransition(int transition_index, Map* target) { |
3717 transitions()->SetTarget(transition_index, target); | 3598 transitions()->SetTarget(transition_index, target); |
3718 } | 3599 } |
3719 | 3600 |
3720 | 3601 |
3721 Map* Map::GetTransition(int transition_index) { | |
3722 return transitions()->GetTarget(transition_index); | |
3723 } | |
3724 | |
3725 | |
3726 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { | 3602 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { |
3727 MaybeObject* allow_elements = | 3603 MaybeObject* allow_elements = EnsureHasTransitionArray(this); |
3728 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); | |
3729 if (allow_elements->IsFailure()) return allow_elements; | 3604 if (allow_elements->IsFailure()) return allow_elements; |
3730 transitions()->set_elements_transition(transitioned_map); | 3605 transitions()->set_elements_transition(transitioned_map); |
3731 return this; | 3606 return this; |
3732 } | 3607 } |
3733 | 3608 |
3734 | 3609 |
3735 FixedArray* Map::GetPrototypeTransitions() { | 3610 FixedArray* Map::GetPrototypeTransitions() { |
3736 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); | 3611 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); |
3737 if (!transitions()->HasPrototypeTransitions()) { | 3612 if (!transitions()->HasPrototypeTransitions()) { |
3738 return GetHeap()->empty_fixed_array(); | 3613 return GetHeap()->empty_fixed_array(); |
3739 } | 3614 } |
3740 return transitions()->GetPrototypeTransitions(); | 3615 return transitions()->GetPrototypeTransitions(); |
3741 } | 3616 } |
3742 | 3617 |
3743 | 3618 |
3744 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { | 3619 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { |
3745 MaybeObject* allow_prototype = | 3620 MaybeObject* allow_prototype = EnsureHasTransitionArray(this); |
3746 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); | |
3747 if (allow_prototype->IsFailure()) return allow_prototype; | 3621 if (allow_prototype->IsFailure()) return allow_prototype; |
3748 #ifdef DEBUG | 3622 #ifdef DEBUG |
3749 if (HasPrototypeTransitions()) { | 3623 if (HasPrototypeTransitions()) { |
3750 ASSERT(GetPrototypeTransitions() != proto_transitions); | 3624 ASSERT(GetPrototypeTransitions() != proto_transitions); |
3751 ZapPrototypeTransitions(); | 3625 ZapPrototypeTransitions(); |
3752 } | 3626 } |
3753 #endif | 3627 #endif |
3754 transitions()->SetPrototypeTransitions(proto_transitions); | 3628 transitions()->SetPrototypeTransitions(proto_transitions); |
3755 return this; | 3629 return this; |
3756 } | 3630 } |
3757 | 3631 |
3758 | 3632 |
3759 bool Map::HasPrototypeTransitions() { | 3633 bool Map::HasPrototypeTransitions() { |
3760 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); | 3634 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); |
3761 } | 3635 } |
3762 | 3636 |
3763 | 3637 |
3764 TransitionArray* Map::transitions() { | 3638 TransitionArray* Map::transitions() { |
3765 ASSERT(HasTransitionArray()); | 3639 ASSERT(HasTransitionArray()); |
3766 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); | 3640 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
3767 return TransitionArray::cast(object); | 3641 return TransitionArray::cast(object); |
3768 } | 3642 } |
3769 | 3643 |
3770 | 3644 |
3771 void Map::set_transitions(TransitionArray* transition_array, | 3645 void Map::set_transitions(TransitionArray* transition_array, |
3772 WriteBarrierMode mode) { | 3646 WriteBarrierMode mode) { |
| 3647 transition_array->set_descriptors(instance_descriptors()); |
| 3648 transition_array->set_back_pointer_storage(GetBackPointer()); |
3773 #ifdef DEBUG | 3649 #ifdef DEBUG |
3774 if (HasTransitionArray()) { | 3650 if (HasTransitionArray()) { |
3775 ASSERT(transitions() != transition_array); | 3651 ASSERT(transitions() != transition_array); |
3776 ZapTransitions(); | 3652 ZapTransitions(); |
3777 } | 3653 } |
3778 #endif | 3654 #endif |
3779 | 3655 |
3780 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); | 3656 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); |
3781 CONDITIONAL_WRITE_BARRIER( | 3657 CONDITIONAL_WRITE_BARRIER( |
3782 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); | 3658 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); |
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4942 // Slow case: compute hash code and set it. | 4818 // Slow case: compute hash code and set it. |
4943 return ComputeAndSetHash(); | 4819 return ComputeAndSetHash(); |
4944 } | 4820 } |
4945 | 4821 |
4946 | 4822 |
4947 StringHasher::StringHasher(int length, uint32_t seed) | 4823 StringHasher::StringHasher(int length, uint32_t seed) |
4948 : length_(length), | 4824 : length_(length), |
4949 raw_running_hash_(seed), | 4825 raw_running_hash_(seed), |
4950 array_index_(0), | 4826 array_index_(0), |
4951 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), | 4827 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), |
4952 is_first_char_(true) { | 4828 is_first_char_(true), |
| 4829 is_valid_(true) { |
4953 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0); | 4830 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0); |
4954 } | 4831 } |
4955 | 4832 |
4956 | 4833 |
4957 bool StringHasher::has_trivial_hash() { | 4834 bool StringHasher::has_trivial_hash() { |
4958 return length_ > String::kMaxHashCalcLength; | 4835 return length_ > String::kMaxHashCalcLength; |
4959 } | 4836 } |
4960 | 4837 |
4961 | 4838 |
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) { | 4839 void StringHasher::AddCharacter(uint32_t c) { |
4982 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { | 4840 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { |
4983 AddSurrogatePair(c); // Not inlined. | 4841 AddSurrogatePair(c); // Not inlined. |
4984 return; | 4842 return; |
4985 } | 4843 } |
4986 // Use the Jenkins one-at-a-time hash function to update the hash | 4844 // Use the Jenkins one-at-a-time hash function to update the hash |
4987 // for the given character. | 4845 // for the given character. |
4988 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c); | 4846 raw_running_hash_ += c; |
| 4847 raw_running_hash_ += (raw_running_hash_ << 10); |
| 4848 raw_running_hash_ ^= (raw_running_hash_ >> 6); |
4989 // Incremental array index computation. | 4849 // Incremental array index computation. |
4990 if (is_array_index_) { | 4850 if (is_array_index_) { |
4991 if (c < '0' || c > '9') { | 4851 if (c < '0' || c > '9') { |
4992 is_array_index_ = false; | 4852 is_array_index_ = false; |
4993 } else { | 4853 } else { |
4994 int d = c - '0'; | 4854 int d = c - '0'; |
4995 if (is_first_char_) { | 4855 if (is_first_char_) { |
4996 is_first_char_ = false; | 4856 is_first_char_ = false; |
4997 if (c == '0' && length_ > 1) { | 4857 if (c == '0' && length_ > 1) { |
4998 is_array_index_ = false; | 4858 is_array_index_ = false; |
4999 return; | 4859 return; |
5000 } | 4860 } |
5001 } | 4861 } |
5002 if (array_index_ > 429496729U - ((d + 2) >> 3)) { | 4862 if (array_index_ > 429496729U - ((d + 2) >> 3)) { |
5003 is_array_index_ = false; | 4863 is_array_index_ = false; |
5004 } else { | 4864 } else { |
5005 array_index_ = array_index_ * 10 + d; | 4865 array_index_ = array_index_ * 10 + d; |
5006 } | 4866 } |
5007 } | 4867 } |
5008 } | 4868 } |
5009 } | 4869 } |
5010 | 4870 |
5011 | 4871 |
5012 void StringHasher::AddCharacterNoIndex(uint32_t c) { | 4872 void StringHasher::AddCharacterNoIndex(uint32_t c) { |
5013 ASSERT(!is_array_index()); | 4873 ASSERT(!is_array_index()); |
5014 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { | 4874 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { |
5015 AddSurrogatePairNoIndex(c); // Not inlined. | 4875 AddSurrogatePairNoIndex(c); // Not inlined. |
5016 return; | 4876 return; |
5017 } | 4877 } |
5018 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c); | 4878 raw_running_hash_ += c; |
| 4879 raw_running_hash_ += (raw_running_hash_ << 10); |
| 4880 raw_running_hash_ ^= (raw_running_hash_ >> 6); |
5019 } | 4881 } |
5020 | 4882 |
5021 | 4883 |
5022 uint32_t StringHasher::GetHash() { | 4884 uint32_t StringHasher::GetHash() { |
5023 // Get the calculated raw hash value and do some more bit ops to distribute | 4885 // 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. | 4886 // the hash further. Ensure that we never return zero as the hash value. |
5025 return GetHashCore(raw_running_hash_); | 4887 uint32_t result = raw_running_hash_; |
| 4888 result += (result << 3); |
| 4889 result ^= (result >> 11); |
| 4890 result += (result << 15); |
| 4891 if ((result & String::kHashBitMask) == 0) { |
| 4892 result = 27; |
| 4893 } |
| 4894 return result; |
5026 } | 4895 } |
5027 | 4896 |
5028 | 4897 |
5029 template <typename schar> | 4898 template <typename schar> |
5030 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) { | 4899 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) { |
5031 StringHasher hasher(length, seed); | 4900 StringHasher hasher(length, seed); |
5032 if (!hasher.has_trivial_hash()) { | 4901 if (!hasher.has_trivial_hash()) { |
5033 int i; | 4902 int i; |
5034 for (i = 0; hasher.is_array_index() && (i < length); i++) { | 4903 for (i = 0; hasher.is_array_index() && (i < length); i++) { |
5035 hasher.AddCharacter(chars[i]); | 4904 hasher.AddCharacter(chars[i]); |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5557 #undef WRITE_UINT32_FIELD | 5426 #undef WRITE_UINT32_FIELD |
5558 #undef READ_SHORT_FIELD | 5427 #undef READ_SHORT_FIELD |
5559 #undef WRITE_SHORT_FIELD | 5428 #undef WRITE_SHORT_FIELD |
5560 #undef READ_BYTE_FIELD | 5429 #undef READ_BYTE_FIELD |
5561 #undef WRITE_BYTE_FIELD | 5430 #undef WRITE_BYTE_FIELD |
5562 | 5431 |
5563 | 5432 |
5564 } } // namespace v8::internal | 5433 } } // namespace v8::internal |
5565 | 5434 |
5566 #endif // V8_OBJECTS_INL_H_ | 5435 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |