Index: src/arm/ic-arm.cc |
=================================================================== |
--- src/arm/ic-arm.cc (revision 10474) |
+++ src/arm/ic-arm.cc (working copy) |
@@ -1036,21 +1036,29 @@ |
// Load the key (consisting of map and symbol) from the cache and |
// check for match. |
- Label try_second_entry, hit_on_first_entry, load_in_object_property; |
+ Label load_in_object_property; |
+ static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; |
+ Label hit_on_nth_entry[kEntriesPerBucket]; |
ExternalReference cache_keys = |
ExternalReference::keyed_lookup_cache_keys(isolate); |
+ |
__ mov(r4, Operand(cache_keys)); |
__ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1)); |
- // Move r4 to second entry. |
- __ ldr(r5, MemOperand(r4, kPointerSize * 2, PostIndex)); |
- __ cmp(r2, r5); |
- __ b(ne, &try_second_entry); |
- __ ldr(r5, MemOperand(r4, -kPointerSize)); // Load symbol |
- __ cmp(r0, r5); |
- __ b(eq, &hit_on_first_entry); |
- __ bind(&try_second_entry); |
- __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); // Move r4 to symbol. |
+ for (int i = 0; i < kEntriesPerBucket - 1; i++) { |
+ Label try_next_entry; |
+ // Load map and move r4 to next entry. |
+ __ ldr(r5, MemOperand(r4, kPointerSize * 2, PostIndex)); |
+ __ cmp(r2, r5); |
+ __ b(ne, &try_next_entry); |
+ __ ldr(r5, MemOperand(r4, -kPointerSize)); // Load symbol |
+ __ cmp(r0, r5); |
+ __ b(eq, &hit_on_nth_entry[i]); |
+ __ bind(&try_next_entry); |
+ } |
+ |
+ // Last entry: Load map and move r4 to symbol. |
+ __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); |
__ cmp(r2, r5); |
__ b(ne, &slow); |
__ ldr(r5, MemOperand(r4)); |
@@ -1065,23 +1073,22 @@ |
ExternalReference cache_field_offsets = |
ExternalReference::keyed_lookup_cache_field_offsets(isolate); |
- // Hit on second entry. |
- __ mov(r4, Operand(cache_field_offsets)); |
- __ add(r3, r3, Operand(1)); |
- __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); |
- __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); |
- __ sub(r5, r5, r6, SetCC); |
- __ b(ge, &property_array_property); |
- __ jmp(&load_in_object_property); |
+ // Hit on nth entry. |
+ for (int i = kEntriesPerBucket - 1; i >= 0; i--) { |
+ __ bind(&hit_on_nth_entry[i]); |
+ __ mov(r4, Operand(cache_field_offsets)); |
+ if (i != 0) { |
+ __ add(r3, r3, Operand(i)); |
+ } |
+ __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); |
+ __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); |
+ __ sub(r5, r5, r6, SetCC); |
+ __ b(ge, &property_array_property); |
+ if (i != 0) { |
+ __ jmp(&load_in_object_property); |
+ } |
+ } |
- // Hit on first entry. |
- __ bind(&hit_on_first_entry); |
- __ mov(r4, Operand(cache_field_offsets)); |
- __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); |
- __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); |
- __ sub(r5, r5, r6, SetCC); |
- __ b(ge, &property_array_property); |
- |
// Load in-object property. |
__ bind(&load_in_object_property); |
__ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset)); |