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

Side by Side Diff: src/ia32/ic-ia32.cc

Issue 6932010: Unroll more StringDictionary lookup probes both for positive and negative dictionary lookups. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ported to arm&x64, cleaned up ia32 impl Created 9 years, 7 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 __ test_b(FieldOperand(r1, Map::kBitFieldOffset), 90 __ test_b(FieldOperand(r1, Map::kBitFieldOffset),
91 (1 << Map::kIsAccessCheckNeeded) | 91 (1 << Map::kIsAccessCheckNeeded) |
92 (1 << Map::kHasNamedInterceptor)); 92 (1 << Map::kHasNamedInterceptor));
93 __ j(not_zero, miss, not_taken); 93 __ j(not_zero, miss, not_taken);
94 94
95 __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset)); 95 __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset));
96 __ CheckMap(r0, FACTORY->hash_table_map(), miss, true); 96 __ CheckMap(r0, FACTORY->hash_table_map(), miss, true);
97 } 97 }
98 98
99 99
100 // Probe the string dictionary in the |elements| register. Jump to the
101 // |done| label if a property with the given name is found leaving the
102 // index into the dictionary in |r0|. Jump to the |miss| label
103 // otherwise.
104 static void GenerateStringDictionaryProbes(MacroAssembler* masm,
105 Label* miss,
106 Label* done,
107 Register elements,
108 Register name,
109 Register r0,
110 Register r1) {
111 // Assert that name contains a string.
112 if (FLAG_debug_code) __ AbortIfNotString(name);
113
114 // Compute the capacity mask.
115 const int kCapacityOffset =
116 StringDictionary::kHeaderSize +
117 StringDictionary::kCapacityIndex * kPointerSize;
118 __ mov(r1, FieldOperand(elements, kCapacityOffset));
119 __ shr(r1, kSmiTagSize); // convert smi to int
120 __ dec(r1);
121
122 // Generate an unrolled loop that performs a few probes before
123 // giving up. Measurements done on Gmail indicate that 2 probes
124 // cover ~93% of loads from dictionaries.
125 static const int kProbes = 4;
126 const int kElementsStartOffset =
127 StringDictionary::kHeaderSize +
128 StringDictionary::kElementsStartIndex * kPointerSize;
129 for (int i = 0; i < kProbes; i++) {
130 // Compute the masked index: (hash + i + i * i) & mask.
131 __ mov(r0, FieldOperand(name, String::kHashFieldOffset));
132 __ shr(r0, String::kHashShift);
133 if (i > 0) {
134 __ add(Operand(r0), Immediate(StringDictionary::GetProbeOffset(i)));
135 }
136 __ and_(r0, Operand(r1));
137
138 // Scale the index by multiplying by the entry size.
139 ASSERT(StringDictionary::kEntrySize == 3);
140 __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3
141
142 // Check if the key is identical to the name.
143 __ cmp(name, Operand(elements, r0, times_4,
144 kElementsStartOffset - kHeapObjectTag));
145 if (i != kProbes - 1) {
146 __ j(equal, done, taken);
147 } else {
148 __ j(not_equal, miss, not_taken);
149 }
150 }
151 }
152
153
154 100
155 // Helper function used to load a property from a dictionary backing 101 // Helper function used to load a property from a dictionary backing
156 // storage. This function may fail to load a property even though it is 102 // storage. This function may fail to load a property even though it is
157 // in the dictionary, so code at miss_label must always call a backup 103 // in the dictionary, so code at miss_label must always call a backup
158 // property load that is complete. This function is safe to call if 104 // property load that is complete. This function is safe to call if
159 // name is not a symbol, and will jump to the miss_label in that 105 // name is not a symbol, and will jump to the miss_label in that
160 // case. The generated code assumes that the receiver has slow 106 // case. The generated code assumes that the receiver has slow
161 // properties, is not a global object and does not have interceptors. 107 // properties, is not a global object and does not have interceptors.
162 static void GenerateDictionaryLoad(MacroAssembler* masm, 108 static void GenerateDictionaryLoad(MacroAssembler* masm,
163 Label* miss_label, 109 Label* miss_label,
(...skipping 12 matching lines...) Expand all
176 // 122 //
177 // r0 - used for the index into the property dictionary 123 // r0 - used for the index into the property dictionary
178 // 124 //
179 // r1 - used to hold the capacity of the property dictionary. 125 // r1 - used to hold the capacity of the property dictionary.
180 // 126 //
181 // result - holds the result on exit. 127 // result - holds the result on exit.
182 128
183 Label done; 129 Label done;
184 130
185 // Probe the dictionary. 131 // Probe the dictionary.
186 GenerateStringDictionaryProbes(masm, 132 StringDictionaryLookupStub::GeneratePositiveLookup(masm,
187 miss_label, 133 miss_label,
188 &done, 134 &done,
189 elements, 135 elements,
190 name, 136 name,
191 r0, 137 r0,
192 r1); 138 r1);
193 139
194 // If probing finds an entry in the dictionary, r0 contains the 140 // If probing finds an entry in the dictionary, r0 contains the
195 // index into the dictionary. Check that the value is a normal 141 // index into the dictionary. Check that the value is a normal
196 // property. 142 // property.
197 __ bind(&done); 143 __ bind(&done);
198 const int kElementsStartOffset = 144 const int kElementsStartOffset =
199 StringDictionary::kHeaderSize + 145 StringDictionary::kHeaderSize +
200 StringDictionary::kElementsStartIndex * kPointerSize; 146 StringDictionary::kElementsStartIndex * kPointerSize;
201 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 147 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
202 __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), 148 __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag),
(...skipping 28 matching lines...) Expand all
231 // 177 //
232 // value - holds the value to store and is unchanged. 178 // value - holds the value to store and is unchanged.
233 // 179 //
234 // r0 - used for index into the property dictionary and is clobbered. 180 // r0 - used for index into the property dictionary and is clobbered.
235 // 181 //
236 // r1 - used to hold the capacity of the property dictionary and is clobbered. 182 // r1 - used to hold the capacity of the property dictionary and is clobbered.
237 Label done; 183 Label done;
238 184
239 185
240 // Probe the dictionary. 186 // Probe the dictionary.
241 GenerateStringDictionaryProbes(masm, 187 StringDictionaryLookupStub::GeneratePositiveLookup(masm,
242 miss_label, 188 miss_label,
243 &done, 189 &done,
244 elements, 190 elements,
245 name, 191 name,
246 r0, 192 r0,
247 r1); 193 r1);
248 194
249 // If probing finds an entry in the dictionary, r0 contains the 195 // If probing finds an entry in the dictionary, r0 contains the
250 // index into the dictionary. Check that the value is a normal 196 // index into the dictionary. Check that the value is a normal
251 // property that is not read only. 197 // property that is not read only.
252 __ bind(&done); 198 __ bind(&done);
253 const int kElementsStartOffset = 199 const int kElementsStartOffset =
254 StringDictionary::kHeaderSize + 200 StringDictionary::kHeaderSize +
255 StringDictionary::kElementsStartIndex * kPointerSize; 201 StringDictionary::kElementsStartIndex * kPointerSize;
256 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 202 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
257 const int kTypeAndReadOnlyMask 203 const int kTypeAndReadOnlyMask
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 Condition cc = *jmp_address == Assembler::kJncShortOpcode 1538 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1593 ? not_zero 1539 ? not_zero
1594 : zero; 1540 : zero;
1595 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1541 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1596 } 1542 }
1597 1543
1598 1544
1599 } } // namespace v8::internal 1545 } } // namespace v8::internal
1600 1546
1601 #endif // V8_TARGET_ARCH_IA32 1547 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698