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

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

Issue 1149053004: Make KeyedStores from a sloppy arguments array use a handler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Code comments. Created 5 years, 6 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/arm/ic-arm.cc ('k') | src/ic/ia32/ic-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 7 #if V8_TARGET_ARCH_ARM64
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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 // enough. 251 // enough.
252 __ Ldrb(hash_scratch, FieldMemOperand(map_scratch, Map::kInstanceTypeOffset)); 252 __ Ldrb(hash_scratch, FieldMemOperand(map_scratch, Map::kInstanceTypeOffset));
253 STATIC_ASSERT(kInternalizedTag == 0); 253 STATIC_ASSERT(kInternalizedTag == 0);
254 __ TestAndBranchIfAnySet(hash_scratch, kIsNotInternalizedMask, not_unique); 254 __ TestAndBranchIfAnySet(hash_scratch, kIsNotInternalizedMask, not_unique);
255 255
256 __ Bind(&unique); 256 __ Bind(&unique);
257 // Fall through if the key is a unique name. 257 // Fall through if the key is a unique name.
258 } 258 }
259 259
260 260
261 // Neither 'object' nor 'key' are modified by this function.
262 //
263 // If the 'unmapped_case' or 'slow_case' exit is taken, the 'map' register is
264 // left with the object's elements map. Otherwise, it is used as a scratch
265 // register.
266 static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
267 Register object, Register key,
268 Register map, Register scratch1,
269 Register scratch2,
270 Label* unmapped_case,
271 Label* slow_case) {
272 DCHECK(!AreAliased(object, key, map, scratch1, scratch2));
273
274 Heap* heap = masm->isolate()->heap();
275
276 // Check that the receiver is a JSObject. Because of the elements
277 // map check later, we do not need to check for interceptors or
278 // whether it requires access checks.
279 __ JumpIfSmi(object, slow_case);
280 // Check that the object is some kind of JSObject.
281 __ JumpIfObjectType(object, map, scratch1, FIRST_JS_RECEIVER_TYPE, slow_case,
282 lt);
283
284 // Check that the key is a positive smi.
285 __ JumpIfNotSmi(key, slow_case);
286 __ Tbnz(key, kXSignBit, slow_case);
287
288 // Load the elements object and check its map.
289 Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
290 __ Ldr(map, FieldMemOperand(object, JSObject::kElementsOffset));
291 __ CheckMap(map, scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK);
292
293 // Check if element is in the range of mapped arguments. If not, jump
294 // to the unmapped lookup.
295 __ Ldr(scratch1, FieldMemOperand(map, FixedArray::kLengthOffset));
296 __ Sub(scratch1, scratch1, Smi::FromInt(2));
297 __ Cmp(key, scratch1);
298 __ B(hs, unmapped_case);
299
300 // Load element index and check whether it is the hole.
301 static const int offset =
302 FixedArray::kHeaderSize + 2 * kPointerSize - kHeapObjectTag;
303
304 __ Add(scratch1, map, offset);
305 __ SmiUntag(scratch2, key);
306 __ Ldr(scratch1, MemOperand(scratch1, scratch2, LSL, kPointerSizeLog2));
307 __ JumpIfRoot(scratch1, Heap::kTheHoleValueRootIndex, unmapped_case);
308
309 // Load value from context and return it.
310 __ Ldr(scratch2, FieldMemOperand(map, FixedArray::kHeaderSize));
311 __ SmiUntag(scratch1);
312 __ Lsl(scratch1, scratch1, kPointerSizeLog2);
313 __ Add(scratch1, scratch1, Context::kHeaderSize - kHeapObjectTag);
314 // The base of the result (scratch2) is passed to RecordWrite in
315 // KeyedStoreIC::GenerateSloppyArguments and it must be a HeapObject.
316 return MemOperand(scratch2, scratch1);
317 }
318
319
320 // The 'parameter_map' register must be loaded with the parameter map of the
321 // arguments object and is overwritten.
322 static MemOperand GenerateUnmappedArgumentsLookup(MacroAssembler* masm,
323 Register key,
324 Register parameter_map,
325 Register scratch,
326 Label* slow_case) {
327 DCHECK(!AreAliased(key, parameter_map, scratch));
328
329 // Element is in arguments backing store, which is referenced by the
330 // second element of the parameter_map.
331 const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize;
332 Register backing_store = parameter_map;
333 __ Ldr(backing_store, FieldMemOperand(parameter_map, kBackingStoreOffset));
334 Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map());
335 __ CheckMap(backing_store, scratch, fixed_array_map, slow_case,
336 DONT_DO_SMI_CHECK);
337 __ Ldr(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset));
338 __ Cmp(key, scratch);
339 __ B(hs, slow_case);
340
341 __ Add(backing_store, backing_store,
342 FixedArray::kHeaderSize - kHeapObjectTag);
343 __ SmiUntag(scratch, key);
344 return MemOperand(backing_store, scratch, LSL, kPointerSizeLog2);
345 }
346
347
348 void LoadIC::GenerateNormal(MacroAssembler* masm) { 261 void LoadIC::GenerateNormal(MacroAssembler* masm) {
349 Register dictionary = x0; 262 Register dictionary = x0;
350 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); 263 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister()));
351 DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); 264 DCHECK(!dictionary.is(LoadDescriptor::NameRegister()));
352 Label slow; 265 Label slow;
353 266
354 __ Ldr(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), 267 __ Ldr(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
355 JSObject::kPropertiesOffset)); 268 JSObject::kPropertiesOffset));
356 GenerateDictionaryLoad(masm, &slow, dictionary, 269 GenerateDictionaryLoad(masm, &slow, dictionary,
357 LoadDescriptor::NameRegister(), x0, x3, x4); 270 LoadDescriptor::NameRegister(), x0, x3, x4);
(...skipping 25 matching lines...) Expand all
383 } 296 }
384 297
385 298
386 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 299 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
387 // The return address is in lr. 300 // The return address is in lr.
388 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); 301 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
389 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); 302 __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
390 } 303 }
391 304
392 305
393 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
394 ASM_LOCATION("KeyedStoreIC::GenerateSloppyArguments");
395 Label slow, notin;
396 Register value = StoreDescriptor::ValueRegister();
397 Register key = StoreDescriptor::NameRegister();
398 Register receiver = StoreDescriptor::ReceiverRegister();
399 DCHECK(receiver.is(x1));
400 DCHECK(key.is(x2));
401 DCHECK(value.is(x0));
402
403 Register map = x3;
404
405 // These registers are used by GenerateMappedArgumentsLookup to build a
406 // MemOperand. They are live for as long as the MemOperand is live.
407 Register mapped1 = x4;
408 Register mapped2 = x5;
409
410 MemOperand mapped = GenerateMappedArgumentsLookup(
411 masm, receiver, key, map, mapped1, mapped2, &notin, &slow);
412 Operand mapped_offset = mapped.OffsetAsOperand();
413 __ Str(value, mapped);
414 __ Add(x10, mapped.base(), mapped_offset);
415 __ Mov(x11, value);
416 __ RecordWrite(mapped.base(), x10, x11, kLRHasNotBeenSaved, kDontSaveFPRegs);
417 __ Ret();
418
419 __ Bind(&notin);
420
421 // These registers are used by GenerateMappedArgumentsLookup to build a
422 // MemOperand. They are live for as long as the MemOperand is live.
423 Register unmapped1 = map; // This is assumed to alias 'map'.
424 Register unmapped2 = x4;
425 MemOperand unmapped =
426 GenerateUnmappedArgumentsLookup(masm, key, unmapped1, unmapped2, &slow);
427 Operand unmapped_offset = unmapped.OffsetAsOperand();
428 __ Str(value, unmapped);
429 __ Add(x10, unmapped.base(), unmapped_offset);
430 __ Mov(x11, value);
431 __ RecordWrite(unmapped.base(), x10, x11, kLRHasNotBeenSaved,
432 kDontSaveFPRegs);
433 __ Ret();
434 __ Bind(&slow);
435 GenerateMiss(masm);
436 }
437
438
439 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 306 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
440 // The return address is in lr. 307 // The return address is in lr.
441 Isolate* isolate = masm->isolate(); 308 Isolate* isolate = masm->isolate();
442 309
443 DCHECK(!AreAliased(x10, x11, LoadWithVectorDescriptor::SlotRegister(), 310 DCHECK(!AreAliased(x10, x11, LoadWithVectorDescriptor::SlotRegister(),
444 LoadWithVectorDescriptor::VectorRegister())); 311 LoadWithVectorDescriptor::VectorRegister()));
445 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11); 312 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11);
446 313
447 __ Push(LoadWithVectorDescriptor::ReceiverRegister(), 314 __ Push(LoadWithVectorDescriptor::ReceiverRegister(),
448 LoadWithVectorDescriptor::NameRegister(), 315 LoadWithVectorDescriptor::NameRegister(),
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 } else { 848 } else {
982 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); 849 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ);
983 // This is JumpIfSmi(smi_reg, branch_imm). 850 // This is JumpIfSmi(smi_reg, branch_imm).
984 patcher.tbz(smi_reg, 0, branch_imm); 851 patcher.tbz(smi_reg, 0, branch_imm);
985 } 852 }
986 } 853 }
987 } 854 }
988 } // namespace v8::internal 855 } // namespace v8::internal
989 856
990 #endif // V8_TARGET_ARCH_ARM64 857 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/ic/arm/ic-arm.cc ('k') | src/ic/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698