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

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

Issue 1546323002: [ic] Fixed receiver_map register trashing in KeyedStoreIC megamorphic. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 12 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/arm/macro-assembler-arm.cc ('k') | src/ic/mips/ic-mips.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 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 #if V8_TARGET_ARCH_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/ic/ic.h" 8 #include "src/ic/ic.h"
9 #include "src/ic/ic-compiler.h" 9 #include "src/ic/ic-compiler.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, 480 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
481 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length, 481 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
482 Register value, Register key, Register receiver, Register receiver_map, 482 Register value, Register key, Register receiver, Register receiver_map,
483 Register elements_map, Register elements) { 483 Register elements_map, Register elements) {
484 Label transition_smi_elements; 484 Label transition_smi_elements;
485 Label finish_object_store, non_double_value, transition_double_elements; 485 Label finish_object_store, non_double_value, transition_double_elements;
486 Label fast_double_without_map_check; 486 Label fast_double_without_map_check;
487 487
488 // Fast case: Do the store, could be either Object or double. 488 // Fast case: Do the store, could be either Object or double.
489 __ bind(fast_object); 489 __ bind(fast_object);
490 Register scratch_value = r4; 490 Register scratch = r4;
491 Register address = r5; 491 Register address = r5;
492 DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
493 scratch, address));
494
492 if (check_map == kCheckMap) { 495 if (check_map == kCheckMap) {
493 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); 496 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
494 __ cmp(elements_map, 497 __ cmp(elements_map,
495 Operand(masm->isolate()->factory()->fixed_array_map())); 498 Operand(masm->isolate()->factory()->fixed_array_map()));
496 __ b(ne, fast_double); 499 __ b(ne, fast_double);
497 } 500 }
498 501
499 // HOLECHECK: guards "A[i] = V" 502 // HOLECHECK: guards "A[i] = V"
500 // We have to go to the runtime if the current value is the hole because 503 // We have to go to the runtime if the current value is the hole because
501 // there may be a callback on the element 504 // there may be a callback on the element
502 Label holecheck_passed1; 505 Label holecheck_passed1;
503 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 506 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
504 __ ldr(scratch_value, 507 __ ldr(scratch, MemOperand::PointerAddressFromSmiKey(address, key, PreIndex));
505 MemOperand::PointerAddressFromSmiKey(address, key, PreIndex)); 508 __ cmp(scratch, Operand(masm->isolate()->factory()->the_hole_value()));
506 __ cmp(scratch_value, Operand(masm->isolate()->factory()->the_hole_value()));
507 __ b(ne, &holecheck_passed1); 509 __ b(ne, &holecheck_passed1);
508 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value, 510 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
509 slow);
510 511
511 __ bind(&holecheck_passed1); 512 __ bind(&holecheck_passed1);
512 513
513 // Smi stores don't require further checks. 514 // Smi stores don't require further checks.
514 Label non_smi_value; 515 Label non_smi_value;
515 __ JumpIfNotSmi(value, &non_smi_value); 516 __ JumpIfNotSmi(value, &non_smi_value);
516 517
517 if (increment_length == kIncrementLength) { 518 if (increment_length == kIncrementLength) {
518 // Add 1 to receiver->length. 519 // Add 1 to receiver->length.
519 __ add(scratch_value, key, Operand(Smi::FromInt(1))); 520 __ add(scratch, key, Operand(Smi::FromInt(1)));
520 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); 521 __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
521 } 522 }
522 // It's irrelevant whether array is smi-only or not when writing a smi. 523 // It's irrelevant whether array is smi-only or not when writing a smi.
523 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 524 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
524 __ str(value, MemOperand::PointerAddressFromSmiKey(address, key)); 525 __ str(value, MemOperand::PointerAddressFromSmiKey(address, key));
525 __ Ret(); 526 __ Ret();
526 527
527 __ bind(&non_smi_value); 528 __ bind(&non_smi_value);
528 // Escape to elements kind transition case. 529 // Escape to elements kind transition case.
529 __ CheckFastObjectElements(receiver_map, scratch_value, 530 __ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
530 &transition_smi_elements);
531 531
532 // Fast elements array, store the value to the elements backing store. 532 // Fast elements array, store the value to the elements backing store.
533 __ bind(&finish_object_store); 533 __ bind(&finish_object_store);
534 if (increment_length == kIncrementLength) { 534 if (increment_length == kIncrementLength) {
535 // Add 1 to receiver->length. 535 // Add 1 to receiver->length.
536 __ add(scratch_value, key, Operand(Smi::FromInt(1))); 536 __ add(scratch, key, Operand(Smi::FromInt(1)));
537 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); 537 __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
538 } 538 }
539 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 539 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
540 __ add(address, address, Operand::PointerOffsetFromSmiKey(key)); 540 __ add(address, address, Operand::PointerOffsetFromSmiKey(key));
541 __ str(value, MemOperand(address)); 541 __ str(value, MemOperand(address));
542 // Update write barrier for the elements array address. 542 // Update write barrier for the elements array address.
543 __ mov(scratch_value, value); // Preserve the value which is returned. 543 __ mov(scratch, value); // Preserve the value which is returned.
544 __ RecordWrite(elements, address, scratch_value, kLRHasNotBeenSaved, 544 __ RecordWrite(elements, address, scratch, kLRHasNotBeenSaved,
545 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 545 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
546 __ Ret(); 546 __ Ret();
547 547
548 __ bind(fast_double); 548 __ bind(fast_double);
549 if (check_map == kCheckMap) { 549 if (check_map == kCheckMap) {
550 // Check for fast double array case. If this fails, call through to the 550 // Check for fast double array case. If this fails, call through to the
551 // runtime. 551 // runtime.
552 __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex); 552 __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex);
553 __ b(ne, slow); 553 __ b(ne, slow);
554 } 554 }
555 555
556 // HOLECHECK: guards "A[i] double hole?" 556 // HOLECHECK: guards "A[i] double hole?"
557 // We have to see if the double version of the hole is present. If so 557 // We have to see if the double version of the hole is present. If so
558 // go to the runtime. 558 // go to the runtime.
559 __ add(address, elements, 559 __ add(address, elements,
560 Operand((FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32)) - 560 Operand((FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32)) -
561 kHeapObjectTag)); 561 kHeapObjectTag));
562 __ ldr(scratch_value, 562 __ ldr(scratch, MemOperand(address, key, LSL, kPointerSizeLog2, PreIndex));
563 MemOperand(address, key, LSL, kPointerSizeLog2, PreIndex)); 563 __ cmp(scratch, Operand(kHoleNanUpper32));
564 __ cmp(scratch_value, Operand(kHoleNanUpper32));
565 __ b(ne, &fast_double_without_map_check); 564 __ b(ne, &fast_double_without_map_check);
566 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value, 565 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
567 slow);
568 566
569 __ bind(&fast_double_without_map_check); 567 __ bind(&fast_double_without_map_check);
570 __ StoreNumberToDoubleElements(value, key, elements, r3, d0, 568 __ StoreNumberToDoubleElements(value, key, elements, scratch, d0,
571 &transition_double_elements); 569 &transition_double_elements);
572 if (increment_length == kIncrementLength) { 570 if (increment_length == kIncrementLength) {
573 // Add 1 to receiver->length. 571 // Add 1 to receiver->length.
574 __ add(scratch_value, key, Operand(Smi::FromInt(1))); 572 __ add(scratch, key, Operand(Smi::FromInt(1)));
575 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); 573 __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
576 } 574 }
577 __ Ret(); 575 __ Ret();
578 576
579 __ bind(&transition_smi_elements); 577 __ bind(&transition_smi_elements);
580 // Transition the array appropriately depending on the value type. 578 // Transition the array appropriately depending on the value type.
581 __ ldr(r4, FieldMemOperand(value, HeapObject::kMapOffset)); 579 __ ldr(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
582 __ CompareRoot(r4, Heap::kHeapNumberMapRootIndex); 580 __ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
583 __ b(ne, &non_double_value); 581 __ b(ne, &non_double_value);
584 582
585 // Value is a double. Transition FAST_SMI_ELEMENTS -> 583 // Value is a double. Transition FAST_SMI_ELEMENTS ->
586 // FAST_DOUBLE_ELEMENTS and complete the store. 584 // FAST_DOUBLE_ELEMENTS and complete the store.
587 __ LoadTransitionedArrayMapConditional( 585 __ LoadTransitionedArrayMapConditional(
588 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, r4, slow); 586 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
589 AllocationSiteMode mode = 587 AllocationSiteMode mode =
590 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS); 588 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
591 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value, 589 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
592 receiver_map, mode, slow); 590 receiver_map, mode, slow);
593 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 591 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
594 __ jmp(&fast_double_without_map_check); 592 __ jmp(&fast_double_without_map_check);
595 593
596 __ bind(&non_double_value); 594 __ bind(&non_double_value);
597 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS 595 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
598 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS, 596 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
599 receiver_map, r4, slow); 597 receiver_map, scratch, slow);
600 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); 598 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
601 ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 599 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
602 masm, receiver, key, value, receiver_map, mode, slow); 600 masm, receiver, key, value, receiver_map, mode, slow);
603 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 601 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
604 __ jmp(&finish_object_store); 602 __ jmp(&finish_object_store);
605 603
606 __ bind(&transition_double_elements); 604 __ bind(&transition_double_elements);
607 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a 605 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
608 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and 606 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
609 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS 607 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
610 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, 608 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
611 receiver_map, r4, slow); 609 receiver_map, scratch, slow);
612 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); 610 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
613 ElementsTransitionGenerator::GenerateDoubleToObject( 611 ElementsTransitionGenerator::GenerateDoubleToObject(
614 masm, receiver, key, value, receiver_map, mode, slow); 612 masm, receiver, key, value, receiver_map, mode, slow);
615 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 613 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
616 __ jmp(&finish_object_store); 614 __ jmp(&finish_object_store);
617 } 615 }
618 616
619 617
620 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm, 618 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
621 LanguageMode language_mode) { 619 LanguageMode language_mode) {
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 patcher.EmitCondition(ne); 898 patcher.EmitCondition(ne);
901 } else { 899 } else {
902 DCHECK(Assembler::GetCondition(branch_instr) == ne); 900 DCHECK(Assembler::GetCondition(branch_instr) == ne);
903 patcher.EmitCondition(eq); 901 patcher.EmitCondition(eq);
904 } 902 }
905 } 903 }
906 } // namespace internal 904 } // namespace internal
907 } // namespace v8 905 } // namespace v8
908 906
909 #endif // V8_TARGET_ARCH_ARM 907 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/ic/mips/ic-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698