Index: src/heap.cc |
=================================================================== |
--- src/heap.cc (revision 10474) |
+++ src/heap.cc (working copy) |
@@ -6523,16 +6523,12 @@ |
int KeyedLookupCache::Lookup(Map* map, String* name) { |
int index = (Hash(map, name) & kHashMask); |
- Key& key = keys_[index]; |
- if ((key.map == map) && key.name->Equals(name)) { |
- return field_offsets_[index]; |
+ for (int i = 0; i < kEntriesPerBucket; i++) { |
+ Key& key = keys_[index + i]; |
+ if ((key.map == map) && key.name->Equals(name)) { |
+ return field_offsets_[index + i]; |
+ } |
} |
- ASSERT(kEntriesPerBucket == 2); // There are two entries to check. |
- // First entry in the bucket missed, check the second. |
- Key& key2 = keys_[index + 1]; |
- if ((key2.map == map) && key2.name->Equals(name)) { |
- return field_offsets_[index + 1]; |
- } |
return kNotFound; |
} |
@@ -6541,13 +6537,29 @@ |
String* symbol; |
if (HEAP->LookupSymbolIfExists(name, &symbol)) { |
int index = (Hash(map, symbol) & kHashMask); |
+ // After a GC there will be free slots, so we use them in order (this may |
+ // help to get the most frequently used one in position 0). |
+ for (int i = 0; i< kEntriesPerBucket; i++) { |
+ Key& key = keys_[index]; |
+ Object* free_entry_indicator = NULL; |
+ if (key.map == free_entry_indicator) { |
+ key.map = map; |
+ key.name = symbol; |
+ field_offsets_[index + i] = field_offset; |
+ return; |
+ } |
+ } |
+ // No free entry found in this bucket, so we move them all down one and |
+ // put the new entry at position zero. |
+ for (int i = kEntriesPerBucket - 1; i > 0; i--) { |
+ Key& key = keys_[index + i]; |
+ Key& key2 = keys_[index + i - 1]; |
+ key = key2; |
+ field_offsets_[index + i] = field_offsets_[index + i - 1]; |
+ } |
+ |
+ // Write the new first entry. |
Key& key = keys_[index]; |
- Key& key2 = keys_[index + 1]; // Second entry in the bucket. |
- // Demote the first entry to the second in the bucket. |
- key2.map = key.map; |
- key2.name = key.name; |
- field_offsets_[index + 1] = field_offsets_[index]; |
- // Write the new first entry. |
key.map = map; |
key.name = symbol; |
field_offsets_[index] = field_offset; |