Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(456)

Side by Side Diff: src/objects-inl.h

Issue 9124004: Backport hash collision workaround to 3.6. (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.6/
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 2064 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 2075
2076 // Find entry for key otherwise return kNotFound. 2076 // Find entry for key otherwise return kNotFound.
2077 template<typename Shape, typename Key> 2077 template<typename Shape, typename Key>
2078 int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) { 2078 int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2079 uint32_t capacity = Capacity(); 2079 uint32_t capacity = Capacity();
2080 uint32_t entry = FirstProbe(Shape::Hash(key), capacity); 2080 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2081 uint32_t count = 1; 2081 uint32_t count = 1;
2082 // EnsureCapacity will guarantee the hash table is never full. 2082 // EnsureCapacity will guarantee the hash table is never full.
2083 while (true) { 2083 while (true) {
2084 Object* element = KeyAt(entry); 2084 Object* element = KeyAt(entry);
2085 if (element == isolate->heap()->undefined_value()) break; // Empty entry. 2085 // Empty entry.
2086 if (element != isolate->heap()->null_value() && 2086 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2087 if (element != isolate->heap()->raw_unchecked_null_value() &&
2087 Shape::IsMatch(key, element)) return entry; 2088 Shape::IsMatch(key, element)) return entry;
2088 entry = NextProbe(entry, count++, capacity); 2089 entry = NextProbe(entry, count++, capacity);
2089 } 2090 }
2090 return kNotFound; 2091 return kNotFound;
2091 } 2092 }
2092 2093
2093 2094
2094 bool NumberDictionary::requires_slow_elements() { 2095 bool NumberDictionary::requires_slow_elements() {
2095 Object* max_index_object = get(kMaxNumberKeyIndex); 2096 Object* max_index_object = get(kMaxNumberKeyIndex);
2096 if (!max_index_object->IsSmi()) return false; 2097 if (!max_index_object->IsSmi()) return false;
(...skipping 2131 matching lines...) Expand 10 before | Expand all | Expand 10 after
4228 4229
4229 uint32_t String::Hash() { 4230 uint32_t String::Hash() {
4230 // Fast case: has hash code already been computed? 4231 // Fast case: has hash code already been computed?
4231 uint32_t field = hash_field(); 4232 uint32_t field = hash_field();
4232 if (IsHashFieldComputed(field)) return field >> kHashShift; 4233 if (IsHashFieldComputed(field)) return field >> kHashShift;
4233 // Slow case: compute hash code and set it. 4234 // Slow case: compute hash code and set it.
4234 return ComputeAndSetHash(); 4235 return ComputeAndSetHash();
4235 } 4236 }
4236 4237
4237 4238
4238 StringHasher::StringHasher(int length) 4239 StringHasher::StringHasher(int length, uint32_t seed)
4239 : length_(length), 4240 : length_(length),
4240 raw_running_hash_(0), 4241 raw_running_hash_(seed),
4241 array_index_(0), 4242 array_index_(0),
4242 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), 4243 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4243 is_first_char_(true), 4244 is_first_char_(true),
4244 is_valid_(true) { } 4245 is_valid_(true) {
4246 ASSERT(FLAG_randomize_string_hashes || raw_running_hash_ == 0);
4247 }
4245 4248
4246 4249
4247 bool StringHasher::has_trivial_hash() { 4250 bool StringHasher::has_trivial_hash() {
4248 return length_ > String::kMaxHashCalcLength; 4251 return length_ > String::kMaxHashCalcLength;
4249 } 4252 }
4250 4253
4251 4254
4252 void StringHasher::AddCharacter(uc32 c) { 4255 void StringHasher::AddCharacter(uc32 c) {
4253 // Use the Jenkins one-at-a-time hash function to update the hash 4256 // Use the Jenkins one-at-a-time hash function to update the hash
4254 // for the given character. 4257 // for the given character.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4286 } 4289 }
4287 4290
4288 4291
4289 uint32_t StringHasher::GetHash() { 4292 uint32_t StringHasher::GetHash() {
4290 // Get the calculated raw hash value and do some more bit ops to distribute 4293 // Get the calculated raw hash value and do some more bit ops to distribute
4291 // the hash further. Ensure that we never return zero as the hash value. 4294 // the hash further. Ensure that we never return zero as the hash value.
4292 uint32_t result = raw_running_hash_; 4295 uint32_t result = raw_running_hash_;
4293 result += (result << 3); 4296 result += (result << 3);
4294 result ^= (result >> 11); 4297 result ^= (result >> 11);
4295 result += (result << 15); 4298 result += (result << 15);
4296 if (result == 0) { 4299 if ((result & String::kHashBitMask) == 0) {
4297 result = 27; 4300 result = 27;
4298 } 4301 }
4299 return result; 4302 return result;
4300 } 4303 }
4301 4304
4302 4305
4303 template <typename schar> 4306 template <typename schar>
4304 uint32_t HashSequentialString(const schar* chars, int length) { 4307 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4305 StringHasher hasher(length); 4308 StringHasher hasher(length, seed);
4306 if (!hasher.has_trivial_hash()) { 4309 if (!hasher.has_trivial_hash()) {
4307 int i; 4310 int i;
4308 for (i = 0; hasher.is_array_index() && (i < length); i++) { 4311 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4309 hasher.AddCharacter(chars[i]); 4312 hasher.AddCharacter(chars[i]);
4310 } 4313 }
4311 for (; i < length; i++) { 4314 for (; i < length; i++) {
4312 hasher.AddCharacterNoIndex(chars[i]); 4315 hasher.AddCharacterNoIndex(chars[i]);
4313 } 4316 }
4314 } 4317 }
4315 return hasher.GetHashField(); 4318 return hasher.GetHashField();
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
4686 #undef WRITE_INT_FIELD 4689 #undef WRITE_INT_FIELD
4687 #undef READ_SHORT_FIELD 4690 #undef READ_SHORT_FIELD
4688 #undef WRITE_SHORT_FIELD 4691 #undef WRITE_SHORT_FIELD
4689 #undef READ_BYTE_FIELD 4692 #undef READ_BYTE_FIELD
4690 #undef WRITE_BYTE_FIELD 4693 #undef WRITE_BYTE_FIELD
4691 4694
4692 4695
4693 } } // namespace v8::internal 4696 } } // namespace v8::internal
4694 4697
4695 #endif // V8_OBJECTS_INL_H_ 4698 #endif // V8_OBJECTS_INL_H_
OLDNEW
« src/objects.h ('K') | « src/objects.cc ('k') | src/profile-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698