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

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

Issue 852313002: Add fast-path OOB support to KeyedLoadIC_Generic (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix negative indices Created 5 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
« no previous file with comments | « src/ic/ia32/ic-ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 161
162 // Check bit field. 162 // Check bit field.
163 __ testb( 163 __ testb(
164 FieldOperand(map, Map::kBitFieldOffset), 164 FieldOperand(map, Map::kBitFieldOffset),
165 Immediate((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit))); 165 Immediate((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)));
166 __ j(not_zero, slow); 166 __ j(not_zero, slow);
167 } 167 }
168 168
169 169
170 // Loads an indexed element from a fast case array. 170 // Loads an indexed element from a fast case array.
171 // If not_fast_array is NULL, doesn't perform the elements map check.
172 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, 171 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
173 Register key, Register elements, 172 Register key, Register elements,
174 Register scratch, Register result, 173 Register scratch, Register result,
175 Label* not_fast_array, Label* out_of_range) { 174 Label* slow) {
176 // Register use: 175 // Register use:
177 // 176 //
178 // receiver - holds the receiver on entry. 177 // receiver - holds the receiver on entry.
179 // Unchanged unless 'result' is the same register. 178 // Unchanged unless 'result' is the same register.
180 // 179 //
181 // key - holds the smi key on entry. 180 // key - holds the smi key on entry.
182 // Unchanged unless 'result' is the same register. 181 // Unchanged unless 'result' is the same register.
183 // 182 //
184 // elements - holds the elements of the receiver on exit.
185 //
186 // result - holds the result on exit if the load succeeded. 183 // result - holds the result on exit if the load succeeded.
187 // Allowed to be the the same as 'receiver' or 'key'. 184 // Allowed to be the the same as 'receiver' or 'key'.
188 // Unchanged on bailout so 'receiver' and 'key' can be safely 185 // Unchanged on bailout so 'receiver' and 'key' can be safely
189 // used by further computation. 186 // used by further computation.
190 // 187 //
191 // Scratch registers: 188 // Scratch registers:
192 // 189 //
193 // scratch - used to hold elements of the receiver and the loaded value. 190 // elements - holds the elements of the receiver and its prototypes.
191 //
192 // scratch - used to hold maps, prototypes, and the loaded value.
193 Label check_prototypes, check_next_prototype;
194 Label done, in_bounds, return_undefined;
194 195
195 __ movp(elements, FieldOperand(receiver, JSObject::kElementsOffset)); 196 __ movp(elements, FieldOperand(receiver, JSObject::kElementsOffset));
196 if (not_fast_array != NULL) { 197 __ AssertFastElements(elements);
197 // Check that the object is in fast mode and writable.
198 __ CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
199 Heap::kFixedArrayMapRootIndex);
200 __ j(not_equal, not_fast_array);
201 } else {
202 __ AssertFastElements(elements);
203 }
204 // Check that the key (index) is within bounds. 198 // Check that the key (index) is within bounds.
205 __ SmiCompare(key, FieldOperand(elements, FixedArray::kLengthOffset)); 199 __ SmiCompare(key, FieldOperand(elements, FixedArray::kLengthOffset));
206 // Unsigned comparison rejects negative indices. 200 // Unsigned comparison rejects negative indices.
207 __ j(above_equal, out_of_range); 201 __ j(below, &in_bounds);
202
203 // Out-of-bounds. Check the prototype chain to see if we can just return
204 // 'undefined'.
205 __ SmiCompare(key, Smi::FromInt(0));
206 __ j(less, slow); // Negative keys can't take the fast OOB path.
207 __ bind(&check_prototypes);
208 __ movp(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
209 __ bind(&check_next_prototype);
210 __ movp(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
211 // scratch: current prototype
212 __ CompareRoot(scratch, Heap::kNullValueRootIndex);
213 __ j(equal, &return_undefined);
214 __ movp(elements, FieldOperand(scratch, JSObject::kElementsOffset));
215 __ movp(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
216 // elements: elements of current prototype
217 // scratch: map of current prototype
218 __ CmpInstanceType(scratch, JS_OBJECT_TYPE);
219 __ j(below, slow);
220 __ testb(FieldOperand(scratch, Map::kBitFieldOffset),
221 Immediate((1 << Map::kIsAccessCheckNeeded) |
222 (1 << Map::kHasIndexedInterceptor)));
223 __ j(not_zero, slow);
224 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
225 __ j(not_equal, slow);
226 __ jmp(&check_next_prototype);
227
228 __ bind(&return_undefined);
229 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
230 __ jmp(&done);
231
232 __ bind(&in_bounds);
208 // Fast case: Do the load. 233 // Fast case: Do the load.
209 SmiIndex index = masm->SmiToIndex(scratch, key, kPointerSizeLog2); 234 SmiIndex index = masm->SmiToIndex(scratch, key, kPointerSizeLog2);
210 __ movp(scratch, FieldOperand(elements, index.reg, index.scale, 235 __ movp(scratch, FieldOperand(elements, index.reg, index.scale,
211 FixedArray::kHeaderSize)); 236 FixedArray::kHeaderSize));
212 __ CompareRoot(scratch, Heap::kTheHoleValueRootIndex); 237 __ CompareRoot(scratch, Heap::kTheHoleValueRootIndex);
213 // In case the loaded value is the_hole we have to consult GetProperty 238 // In case the loaded value is the_hole we have to check the prototype chain.
214 // to ensure the prototype chain is searched. 239 __ j(equal, &check_prototypes);
215 __ j(equal, out_of_range); 240 __ Move(result, scratch);
216 if (!result.is(scratch)) { 241 __ bind(&done);
217 __ movp(result, scratch);
218 }
219 } 242 }
220 243
221 244
222 // Checks whether a key is an array index string or a unique name. 245 // Checks whether a key is an array index string or a unique name.
223 // Falls through if the key is a unique name. 246 // Falls through if the key is a unique name.
224 static void GenerateKeyNameCheck(MacroAssembler* masm, Register key, 247 static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
225 Register map, Register hash, 248 Register map, Register hash,
226 Label* index_string, Label* not_unique) { 249 Label* index_string, Label* not_unique) {
227 // Register use: 250 // Register use:
228 // key - holds the key and is unchanged. Assumed to be non-smi. 251 // key - holds the key and is unchanged. Assumed to be non-smi.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 __ bind(&index_smi); 289 __ bind(&index_smi);
267 // Now the key is known to be a smi. This place is also jumped to from below 290 // Now the key is known to be a smi. This place is also jumped to from below
268 // where a numeric string is converted to a smi. 291 // where a numeric string is converted to a smi.
269 292
270 GenerateKeyedLoadReceiverCheck(masm, receiver, rax, 293 GenerateKeyedLoadReceiverCheck(masm, receiver, rax,
271 Map::kHasIndexedInterceptor, &slow); 294 Map::kHasIndexedInterceptor, &slow);
272 295
273 // Check the receiver's map to see if it has fast elements. 296 // Check the receiver's map to see if it has fast elements.
274 __ CheckFastElements(rax, &check_number_dictionary); 297 __ CheckFastElements(rax, &check_number_dictionary);
275 298
276 GenerateFastArrayLoad(masm, receiver, key, rax, rbx, rax, NULL, &slow); 299 GenerateFastArrayLoad(masm, receiver, key, rax, rbx, rax, &slow);
277 Counters* counters = masm->isolate()->counters(); 300 Counters* counters = masm->isolate()->counters();
278 __ IncrementCounter(counters->keyed_load_generic_smi(), 1); 301 __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
279 __ ret(0); 302 __ ret(0);
280 303
281 __ bind(&check_number_dictionary); 304 __ bind(&check_number_dictionary);
282 __ SmiToInteger32(rbx, key); 305 __ SmiToInteger32(rbx, key);
283 __ movp(rax, FieldOperand(receiver, JSObject::kElementsOffset)); 306 __ movp(rax, FieldOperand(receiver, JSObject::kElementsOffset));
284 307
285 // Check whether the elements is a number dictionary. 308 // Check whether the elements is a number dictionary.
286 // rbx: key as untagged int32 309 // rbx: key as untagged int32
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 Condition cc = 1013 Condition cc =
991 (check == ENABLE_INLINED_SMI_CHECK) 1014 (check == ENABLE_INLINED_SMI_CHECK)
992 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1015 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
993 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1016 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
994 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1017 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
995 } 1018 }
996 } 1019 }
997 } // namespace v8::internal 1020 } // namespace v8::internal
998 1021
999 #endif // V8_TARGET_ARCH_X64 1022 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ic/ia32/ic-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698