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

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

Issue 381633002: Use a register spec for StoreIC and KeyedStoreIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Code comments. Created 6 years, 5 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
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.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 #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-inl.h" 10 #include "src/ic-inl.h"
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 static void KeyedStoreGenerateGenericHelper( 560 static void KeyedStoreGenerateGenericHelper(
561 MacroAssembler* masm, 561 MacroAssembler* masm,
562 Label* fast_object, 562 Label* fast_object,
563 Label* fast_double, 563 Label* fast_double,
564 Label* slow, 564 Label* slow,
565 KeyedStoreCheckMap check_map, 565 KeyedStoreCheckMap check_map,
566 KeyedStoreIncrementLength increment_length) { 566 KeyedStoreIncrementLength increment_length) {
567 Label transition_smi_elements; 567 Label transition_smi_elements;
568 Label finish_object_store, non_double_value, transition_double_elements; 568 Label finish_object_store, non_double_value, transition_double_elements;
569 Label fast_double_without_map_check; 569 Label fast_double_without_map_check;
570 Register receiver = KeyedStoreIC::ReceiverRegister();
571 Register key = KeyedStoreIC::NameRegister();
572 Register value = KeyedStoreIC::ValueRegister();
573 ASSERT(receiver.is(rdx));
574 ASSERT(key.is(rcx));
575 ASSERT(value.is(rax));
570 // Fast case: Do the store, could be either Object or double. 576 // Fast case: Do the store, could be either Object or double.
571 __ bind(fast_object); 577 __ bind(fast_object);
572 // rax: value
573 // rbx: receiver's elements array (a FixedArray) 578 // rbx: receiver's elements array (a FixedArray)
574 // rcx: index 579 // receiver is a JSArray.
575 // rdx: receiver (a JSArray)
576 // r9: map of receiver 580 // r9: map of receiver
577 if (check_map == kCheckMap) { 581 if (check_map == kCheckMap) {
578 __ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset)); 582 __ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
579 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex); 583 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
580 __ j(not_equal, fast_double); 584 __ j(not_equal, fast_double);
581 } 585 }
582 586
583 // HOLECHECK: guards "A[i] = V" 587 // HOLECHECK: guards "A[i] = V"
584 // We have to go to the runtime if the current value is the hole because 588 // We have to go to the runtime if the current value is the hole because
585 // there may be a callback on the element 589 // there may be a callback on the element
586 Label holecheck_passed1; 590 Label holecheck_passed1;
587 __ movp(kScratchRegister, FieldOperand(rbx, 591 __ movp(kScratchRegister, FieldOperand(rbx,
588 rcx, 592 key,
589 times_pointer_size, 593 times_pointer_size,
590 FixedArray::kHeaderSize)); 594 FixedArray::kHeaderSize));
591 __ CompareRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 595 __ CompareRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
592 __ j(not_equal, &holecheck_passed1); 596 __ j(not_equal, &holecheck_passed1);
593 __ JumpIfDictionaryInPrototypeChain(rdx, rdi, kScratchRegister, slow); 597 __ JumpIfDictionaryInPrototypeChain(receiver, rdi, kScratchRegister, slow);
594 598
595 __ bind(&holecheck_passed1); 599 __ bind(&holecheck_passed1);
596 600
597 // Smi stores don't require further checks. 601 // Smi stores don't require further checks.
598 Label non_smi_value; 602 Label non_smi_value;
599 __ JumpIfNotSmi(rax, &non_smi_value); 603 __ JumpIfNotSmi(value, &non_smi_value);
600 if (increment_length == kIncrementLength) { 604 if (increment_length == kIncrementLength) {
601 // Add 1 to receiver->length. 605 // Add 1 to receiver->length.
602 __ leal(rdi, Operand(rcx, 1)); 606 __ leal(rdi, Operand(key, 1));
603 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi); 607 __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
604 } 608 }
605 // It's irrelevant whether array is smi-only or not when writing a smi. 609 // It's irrelevant whether array is smi-only or not when writing a smi.
606 __ movp(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize), 610 __ movp(FieldOperand(rbx, key, times_pointer_size, FixedArray::kHeaderSize),
607 rax); 611 value);
608 __ ret(0); 612 __ ret(0);
609 613
610 __ bind(&non_smi_value); 614 __ bind(&non_smi_value);
611 // Writing a non-smi, check whether array allows non-smi elements. 615 // Writing a non-smi, check whether array allows non-smi elements.
612 // r9: receiver's map 616 // r9: receiver's map
613 __ CheckFastObjectElements(r9, &transition_smi_elements); 617 __ CheckFastObjectElements(r9, &transition_smi_elements);
614 618
615 __ bind(&finish_object_store); 619 __ bind(&finish_object_store);
616 if (increment_length == kIncrementLength) { 620 if (increment_length == kIncrementLength) {
617 // Add 1 to receiver->length. 621 // Add 1 to receiver->length.
618 __ leal(rdi, Operand(rcx, 1)); 622 __ leal(rdi, Operand(key, 1));
619 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi); 623 __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
620 } 624 }
621 __ movp(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize), 625 __ movp(FieldOperand(rbx, key, times_pointer_size, FixedArray::kHeaderSize),
622 rax); 626 value);
623 __ movp(rdx, rax); // Preserve the value which is returned. 627 __ movp(rdx, value); // Preserve the value which is returned.
624 __ RecordWriteArray( 628 __ RecordWriteArray(
625 rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 629 rbx, rdx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
626 __ ret(0); 630 __ ret(0);
627 631
628 __ bind(fast_double); 632 __ bind(fast_double);
629 if (check_map == kCheckMap) { 633 if (check_map == kCheckMap) {
630 // Check for fast double array case. If this fails, call through to the 634 // Check for fast double array case. If this fails, call through to the
631 // runtime. 635 // runtime.
632 // rdi: elements array's map 636 // rdi: elements array's map
633 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex); 637 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
634 __ j(not_equal, slow); 638 __ j(not_equal, slow);
635 } 639 }
636 640
637 // HOLECHECK: guards "A[i] double hole?" 641 // HOLECHECK: guards "A[i] double hole?"
638 // We have to see if the double version of the hole is present. If so 642 // We have to see if the double version of the hole is present. If so
639 // go to the runtime. 643 // go to the runtime.
640 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); 644 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
641 __ cmpl(FieldOperand(rbx, rcx, times_8, offset), Immediate(kHoleNanUpper32)); 645 __ cmpl(FieldOperand(rbx, key, times_8, offset), Immediate(kHoleNanUpper32));
642 __ j(not_equal, &fast_double_without_map_check); 646 __ j(not_equal, &fast_double_without_map_check);
643 __ JumpIfDictionaryInPrototypeChain(rdx, rdi, kScratchRegister, slow); 647 __ JumpIfDictionaryInPrototypeChain(receiver, rdi, kScratchRegister, slow);
644 648
645 __ bind(&fast_double_without_map_check); 649 __ bind(&fast_double_without_map_check);
646 __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0, 650 __ StoreNumberToDoubleElements(value, rbx, key, xmm0,
647 &transition_double_elements); 651 &transition_double_elements);
648 if (increment_length == kIncrementLength) { 652 if (increment_length == kIncrementLength) {
649 // Add 1 to receiver->length. 653 // Add 1 to receiver->length.
650 __ leal(rdi, Operand(rcx, 1)); 654 __ leal(rdi, Operand(key, 1));
651 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi); 655 __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
652 } 656 }
653 __ ret(0); 657 __ ret(0);
654 658
655 __ bind(&transition_smi_elements); 659 __ bind(&transition_smi_elements);
656 __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); 660 __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset));
657 661
658 // Transition the array appropriately depending on the value type. 662 // Transition the array appropriately depending on the value type.
659 __ movp(r9, FieldOperand(rax, HeapObject::kMapOffset)); 663 __ movp(r9, FieldOperand(value, HeapObject::kMapOffset));
660 __ CompareRoot(r9, Heap::kHeapNumberMapRootIndex); 664 __ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
661 __ j(not_equal, &non_double_value); 665 __ j(not_equal, &non_double_value);
662 666
663 // Value is a double. Transition FAST_SMI_ELEMENTS -> 667 // Value is a double. Transition FAST_SMI_ELEMENTS ->
664 // FAST_DOUBLE_ELEMENTS and complete the store. 668 // FAST_DOUBLE_ELEMENTS and complete the store.
665 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 669 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
666 FAST_DOUBLE_ELEMENTS, 670 FAST_DOUBLE_ELEMENTS,
667 rbx, 671 rbx,
668 rdi, 672 rdi,
669 slow); 673 slow);
670 AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, 674 AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS,
671 FAST_DOUBLE_ELEMENTS); 675 FAST_DOUBLE_ELEMENTS);
672 ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow); 676 ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow);
673 __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 677 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
674 __ jmp(&fast_double_without_map_check); 678 __ jmp(&fast_double_without_map_check);
675 679
676 __ bind(&non_double_value); 680 __ bind(&non_double_value);
677 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS 681 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
678 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 682 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
679 FAST_ELEMENTS, 683 FAST_ELEMENTS,
680 rbx, 684 rbx,
681 rdi, 685 rdi,
682 slow); 686 slow);
683 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); 687 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
684 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode, 688 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode,
685 slow); 689 slow);
686 __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 690 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
687 __ jmp(&finish_object_store); 691 __ jmp(&finish_object_store);
688 692
689 __ bind(&transition_double_elements); 693 __ bind(&transition_double_elements);
690 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a 694 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
691 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and 695 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
692 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS 696 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
693 __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); 697 __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset));
694 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, 698 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
695 FAST_ELEMENTS, 699 FAST_ELEMENTS,
696 rbx, 700 rbx,
697 rdi, 701 rdi,
698 slow); 702 slow);
699 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); 703 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
700 ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow); 704 ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow);
701 __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 705 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
702 __ jmp(&finish_object_store); 706 __ jmp(&finish_object_store);
703 } 707 }
704 708
705 709
706 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 710 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
707 StrictMode strict_mode) { 711 StrictMode strict_mode) {
708 // ----------- S t a t e ------------- 712 // Return address is on the stack.
709 // -- rax : value
710 // -- rcx : key
711 // -- rdx : receiver
712 // -- rsp[0] : return address
713 // -----------------------------------
714 Label slow, slow_with_tagged_index, fast_object, fast_object_grow; 713 Label slow, slow_with_tagged_index, fast_object, fast_object_grow;
715 Label fast_double, fast_double_grow; 714 Label fast_double, fast_double_grow;
716 Label array, extra, check_if_double_array; 715 Label array, extra, check_if_double_array;
716 Register receiver = ReceiverRegister();
717 Register key = NameRegister();
718 ASSERT(receiver.is(rdx));
719 ASSERT(key.is(rcx));
717 720
718 // Check that the object isn't a smi. 721 // Check that the object isn't a smi.
719 __ JumpIfSmi(rdx, &slow_with_tagged_index); 722 __ JumpIfSmi(receiver, &slow_with_tagged_index);
720 // Get the map from the receiver. 723 // Get the map from the receiver.
721 __ movp(r9, FieldOperand(rdx, HeapObject::kMapOffset)); 724 __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset));
722 // Check that the receiver does not require access checks and is not observed. 725 // Check that the receiver does not require access checks and is not observed.
723 // The generic stub does not perform map checks or handle observed objects. 726 // The generic stub does not perform map checks or handle observed objects.
724 __ testb(FieldOperand(r9, Map::kBitFieldOffset), 727 __ testb(FieldOperand(r9, Map::kBitFieldOffset),
725 Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved)); 728 Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved));
726 __ j(not_zero, &slow_with_tagged_index); 729 __ j(not_zero, &slow_with_tagged_index);
727 // Check that the key is a smi. 730 // Check that the key is a smi.
728 __ JumpIfNotSmi(rcx, &slow_with_tagged_index); 731 __ JumpIfNotSmi(key, &slow_with_tagged_index);
729 __ SmiToInteger32(rcx, rcx); 732 __ SmiToInteger32(key, key);
730 733
731 __ CmpInstanceType(r9, JS_ARRAY_TYPE); 734 __ CmpInstanceType(r9, JS_ARRAY_TYPE);
732 __ j(equal, &array); 735 __ j(equal, &array);
733 // Check that the object is some kind of JSObject. 736 // Check that the object is some kind of JSObject.
734 __ CmpInstanceType(r9, FIRST_JS_OBJECT_TYPE); 737 __ CmpInstanceType(r9, FIRST_JS_OBJECT_TYPE);
735 __ j(below, &slow); 738 __ j(below, &slow);
736 739
737 // Object case: Check key against length in the elements array. 740 // Object case: Check key against length in the elements array.
738 // rax: value 741 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
739 // rdx: JSObject
740 // rcx: index
741 __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
742 // Check array bounds. 742 // Check array bounds.
743 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 743 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key);
744 // rax: value
745 // rbx: FixedArray 744 // rbx: FixedArray
746 // rcx: index
747 __ j(above, &fast_object); 745 __ j(above, &fast_object);
748 746
749 // Slow case: call runtime. 747 // Slow case: call runtime.
750 __ bind(&slow); 748 __ bind(&slow);
751 __ Integer32ToSmi(rcx, rcx); 749 __ Integer32ToSmi(key, key);
752 __ bind(&slow_with_tagged_index); 750 __ bind(&slow_with_tagged_index);
753 GenerateRuntimeSetProperty(masm, strict_mode); 751 GenerateRuntimeSetProperty(masm, strict_mode);
754 // Never returns to here. 752 // Never returns to here.
755 753
756 // Extra capacity case: Check if there is extra capacity to 754 // Extra capacity case: Check if there is extra capacity to
757 // perform the store and update the length. Used for adding one 755 // perform the store and update the length. Used for adding one
758 // element to the array by writing to array[array.length]. 756 // element to the array by writing to array[array.length].
759 __ bind(&extra); 757 __ bind(&extra);
760 // rax: value 758 // receiver is a JSArray.
761 // rdx: receiver (a JSArray)
762 // rbx: receiver's elements array (a FixedArray) 759 // rbx: receiver's elements array (a FixedArray)
763 // rcx: index 760 // flags: smicompare (receiver.length(), rbx)
764 // flags: smicompare (rdx.length(), rbx)
765 __ j(not_equal, &slow); // do not leave holes in the array 761 __ j(not_equal, &slow); // do not leave holes in the array
766 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 762 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key);
767 __ j(below_equal, &slow); 763 __ j(below_equal, &slow);
768 // Increment index to get new length. 764 // Increment index to get new length.
769 __ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset)); 765 __ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
770 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex); 766 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
771 __ j(not_equal, &check_if_double_array); 767 __ j(not_equal, &check_if_double_array);
772 __ jmp(&fast_object_grow); 768 __ jmp(&fast_object_grow);
773 769
774 __ bind(&check_if_double_array); 770 __ bind(&check_if_double_array);
775 // rdi: elements array's map 771 // rdi: elements array's map
776 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex); 772 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
777 __ j(not_equal, &slow); 773 __ j(not_equal, &slow);
778 __ jmp(&fast_double_grow); 774 __ jmp(&fast_double_grow);
779 775
780 // Array case: Get the length and the elements array from the JS 776 // Array case: Get the length and the elements array from the JS
781 // array. Check that the array is in fast mode (and writable); if it 777 // array. Check that the array is in fast mode (and writable); if it
782 // is the length is always a smi. 778 // is the length is always a smi.
783 __ bind(&array); 779 __ bind(&array);
784 // rax: value 780 // receiver is a JSArray.
785 // rdx: receiver (a JSArray) 781 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
786 // rcx: index
787 __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
788 782
789 // Check the key against the length in the array, compute the 783 // Check the key against the length in the array, compute the
790 // address to store into and fall through to fast case. 784 // address to store into and fall through to fast case.
791 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 785 __ SmiCompareInteger32(FieldOperand(receiver, JSArray::kLengthOffset), key);
792 __ j(below_equal, &extra); 786 __ j(below_equal, &extra);
793 787
794 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, 788 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
795 &slow, kCheckMap, kDontIncrementLength); 789 &slow, kCheckMap, kDontIncrementLength);
796 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, 790 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
797 &slow, kDontCheckMap, kIncrementLength); 791 &slow, kDontCheckMap, kIncrementLength);
798 } 792 }
799 793
800 794
801 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm, 795 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); 893 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
900 __ j(equal, &slow); 894 __ j(equal, &slow);
901 __ movp(rax, unmapped_location); 895 __ movp(rax, unmapped_location);
902 __ Ret(); 896 __ Ret();
903 __ bind(&slow); 897 __ bind(&slow);
904 GenerateMiss(masm); 898 GenerateMiss(masm);
905 } 899 }
906 900
907 901
908 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { 902 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
909 // ----------- S t a t e ------------- 903 // The return address is on the stack.
910 // -- rax : value
911 // -- rcx : key
912 // -- rdx : receiver
913 // -- rsp[0] : return address
914 // -----------------------------------
915 Label slow, notin; 904 Label slow, notin;
905 Register receiver = ReceiverRegister();
906 Register name = NameRegister();
907 Register value = ValueRegister();
908 ASSERT(receiver.is(rdx));
909 ASSERT(name.is(rcx));
910 ASSERT(value.is(rax));
911
916 Operand mapped_location = GenerateMappedArgumentsLookup( 912 Operand mapped_location = GenerateMappedArgumentsLookup(
917 masm, rdx, rcx, rbx, rdi, r8, &notin, &slow); 913 masm, receiver, name, rbx, rdi, r8, &notin, &slow);
918 __ movp(mapped_location, rax); 914 __ movp(mapped_location, value);
919 __ leap(r9, mapped_location); 915 __ leap(r9, mapped_location);
920 __ movp(r8, rax); 916 __ movp(r8, value);
921 __ RecordWrite(rbx, 917 __ RecordWrite(rbx,
922 r9, 918 r9,
923 r8, 919 r8,
924 kDontSaveFPRegs, 920 kDontSaveFPRegs,
925 EMIT_REMEMBERED_SET, 921 EMIT_REMEMBERED_SET,
926 INLINE_SMI_CHECK); 922 INLINE_SMI_CHECK);
927 __ Ret(); 923 __ Ret();
928 __ bind(&notin); 924 __ bind(&notin);
929 // The unmapped lookup expects that the parameter map is in rbx. 925 // The unmapped lookup expects that the parameter map is in rbx.
930 Operand unmapped_location = 926 Operand unmapped_location =
931 GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rdi, &slow); 927 GenerateUnmappedArgumentsLookup(masm, name, rbx, rdi, &slow);
932 __ movp(unmapped_location, rax); 928 __ movp(unmapped_location, value);
933 __ leap(r9, unmapped_location); 929 __ leap(r9, unmapped_location);
934 __ movp(r8, rax); 930 __ movp(r8, value);
935 __ RecordWrite(rbx, 931 __ RecordWrite(rbx,
936 r9, 932 r9,
937 r8, 933 r8,
938 kDontSaveFPRegs, 934 kDontSaveFPRegs,
939 EMIT_REMEMBERED_SET, 935 EMIT_REMEMBERED_SET,
940 INLINE_SMI_CHECK); 936 INLINE_SMI_CHECK);
941 __ Ret(); 937 __ Ret();
942 __ bind(&slow); 938 __ bind(&slow);
943 GenerateMiss(masm); 939 GenerateMiss(masm);
944 } 940 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); 1038 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
1043 __ TailCallExternalReference(ref, 2, 1); 1039 __ TailCallExternalReference(ref, 2, 1);
1044 } 1040 }
1045 1041
1046 1042
1047 // IC register specifications 1043 // IC register specifications
1048 const Register LoadIC::ReceiverRegister() { return rdx; } 1044 const Register LoadIC::ReceiverRegister() { return rdx; }
1049 const Register LoadIC::NameRegister() { return rcx; } 1045 const Register LoadIC::NameRegister() { return rcx; }
1050 1046
1051 1047
1048 const Register StoreIC::ReceiverRegister() { return rdx; }
1049 const Register StoreIC::NameRegister() { return rcx; }
1050 const Register StoreIC::ValueRegister() { return rax; }
1051
1052
1053 const Register KeyedStoreIC::ReceiverRegister() {
1054 return StoreIC::ReceiverRegister();
1055 }
1056
1057
1058 const Register KeyedStoreIC::NameRegister() {
1059 return StoreIC::NameRegister();
1060 }
1061
1062
1063 const Register KeyedStoreIC::ValueRegister() {
1064 return StoreIC::ValueRegister();
1065 }
1066
1067
1052 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 1068 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
1053 // The return address is on the stack. 1069 // The return address is on the stack.
1054 1070
1055 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); 1071 __ PopReturnAddressTo(KeyedLoadIC_TempRegister());
1056 __ Push(ReceiverRegister()); // receiver 1072 __ Push(ReceiverRegister()); // receiver
1057 __ Push(NameRegister()); // name 1073 __ Push(NameRegister()); // name
1058 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); 1074 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister());
1059 1075
1060 // Perform tail call to the entry. 1076 // Perform tail call to the entry.
1061 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 1077 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
1062 } 1078 }
1063 1079
1064 1080
1065 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 1081 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
1066 // ----------- S t a t e ------------- 1082 // The return address is on the stack.
1067 // -- rax : value
1068 // -- rcx : name
1069 // -- rdx : receiver
1070 // -- rsp[0] : return address
1071 // -----------------------------------
1072 1083
1073 // Get the receiver from the stack and probe the stub cache. 1084 // Get the receiver from the stack and probe the stub cache.
1074 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); 1085 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
1075 masm->isolate()->stub_cache()->GenerateProbe( 1086 masm->isolate()->stub_cache()->GenerateProbe(
1076 masm, flags, rdx, rcx, rbx, no_reg); 1087 masm, flags, ReceiverRegister(), NameRegister(), rbx, no_reg);
1077 1088
1078 // Cache miss: Jump to runtime. 1089 // Cache miss: Jump to runtime.
1079 GenerateMiss(masm); 1090 GenerateMiss(masm);
1080 } 1091 }
1081 1092
1082 1093
1083 void StoreIC::GenerateMiss(MacroAssembler* masm) { 1094 static void StoreIC_PushArgs(MacroAssembler* masm) {
1084 // ----------- S t a t e ------------- 1095 Register receiver = StoreIC::ReceiverRegister();
1085 // -- rax : value 1096 Register name = StoreIC::NameRegister();
1086 // -- rcx : name 1097 Register value = StoreIC::ValueRegister();
1087 // -- rdx : receiver 1098
1088 // -- rsp[0] : return address 1099 ASSERT(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value));
1089 // -----------------------------------
1090 1100
1091 __ PopReturnAddressTo(rbx); 1101 __ PopReturnAddressTo(rbx);
1092 __ Push(rdx); // receiver 1102 __ Push(receiver);
1093 __ Push(rcx); // name 1103 __ Push(name);
1094 __ Push(rax); // value 1104 __ Push(value);
1095 __ PushReturnAddressFrom(rbx); 1105 __ PushReturnAddressFrom(rbx);
1106 }
1107
1108
1109 void StoreIC::GenerateMiss(MacroAssembler* masm) {
1110 // Return address is on the stack.
1111 StoreIC_PushArgs(masm);
1096 1112
1097 // Perform tail call to the entry. 1113 // Perform tail call to the entry.
1098 ExternalReference ref = 1114 ExternalReference ref =
1099 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); 1115 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate());
1100 __ TailCallExternalReference(ref, 3, 1); 1116 __ TailCallExternalReference(ref, 3, 1);
1101 } 1117 }
1102 1118
1103 1119
1104 void StoreIC::GenerateNormal(MacroAssembler* masm) { 1120 void StoreIC::GenerateNormal(MacroAssembler* masm) {
1105 // ----------- S t a t e ------------- 1121 // Return address is on the stack.
1106 // -- rax : value 1122 Register receiver = ReceiverRegister();
1107 // -- rcx : name 1123 Register name = NameRegister();
1108 // -- rdx : receiver 1124 Register value = ValueRegister();
1109 // -- rsp[0] : return address
1110 // -----------------------------------
1111 1125
1112 Label miss; 1126 Label miss;
1113 1127
1114 GenerateNameDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss); 1128 GenerateNameDictionaryReceiverCheck(masm, receiver, rbx, rdi, &miss);
1115 1129
1116 GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9); 1130 GenerateDictionaryStore(masm, &miss, rbx, name, value, r8, r9);
1117 Counters* counters = masm->isolate()->counters(); 1131 Counters* counters = masm->isolate()->counters();
1118 __ IncrementCounter(counters->store_normal_hit(), 1); 1132 __ IncrementCounter(counters->store_normal_hit(), 1);
1119 __ ret(0); 1133 __ ret(0);
1120 1134
1121 __ bind(&miss); 1135 __ bind(&miss);
1122 __ IncrementCounter(counters->store_normal_miss(), 1); 1136 __ IncrementCounter(counters->store_normal_miss(), 1);
1123 GenerateMiss(masm); 1137 GenerateMiss(masm);
1124 } 1138 }
1125 1139
1126 1140
1127 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, 1141 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
1128 StrictMode strict_mode) { 1142 StrictMode strict_mode) {
1129 // ----------- S t a t e ------------- 1143 // Return address is on the stack.
1130 // -- rax : value 1144 ASSERT(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) &&
1131 // -- rcx : name 1145 !rbx.is(ValueRegister()));
1132 // -- rdx : receiver 1146
1133 // -- rsp[0] : return address
1134 // -----------------------------------
1135 __ PopReturnAddressTo(rbx); 1147 __ PopReturnAddressTo(rbx);
1136 __ Push(rdx); 1148 __ Push(ReceiverRegister());
1137 __ Push(rcx); 1149 __ Push(NameRegister());
1138 __ Push(rax); 1150 __ Push(ValueRegister());
1139 __ Push(Smi::FromInt(strict_mode)); 1151 __ Push(Smi::FromInt(strict_mode));
1140 __ PushReturnAddressFrom(rbx); 1152 __ PushReturnAddressFrom(rbx);
1141 1153
1142 // Do tail-call to runtime routine. 1154 // Do tail-call to runtime routine.
1143 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); 1155 __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
1144 } 1156 }
1145 1157
1146 1158
1147 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, 1159 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
1148 StrictMode strict_mode) { 1160 StrictMode strict_mode) {
1149 // ----------- S t a t e ------------- 1161 // Return address is on the stack.
1150 // -- rax : value 1162 ASSERT(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) &&
1151 // -- rcx : key 1163 !rbx.is(ValueRegister()));
1152 // -- rdx : receiver
1153 // -- rsp[0] : return address
1154 // -----------------------------------
1155 1164
1156 __ PopReturnAddressTo(rbx); 1165 __ PopReturnAddressTo(rbx);
1157 __ Push(rdx); // receiver 1166 __ Push(ReceiverRegister());
1158 __ Push(rcx); // key 1167 __ Push(NameRegister());
1159 __ Push(rax); // value 1168 __ Push(ValueRegister());
1160 __ Push(Smi::FromInt(strict_mode)); // Strict mode. 1169 __ Push(Smi::FromInt(strict_mode)); // Strict mode.
1161 __ PushReturnAddressFrom(rbx); 1170 __ PushReturnAddressFrom(rbx);
1162 1171
1163 // Do tail-call to runtime routine. 1172 // Do tail-call to runtime routine.
1164 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); 1173 __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
1165 } 1174 }
1166 1175
1167 1176
1168 void StoreIC::GenerateSlow(MacroAssembler* masm) { 1177 void StoreIC::GenerateSlow(MacroAssembler* masm) {
1169 // ----------- S t a t e ------------- 1178 // Return address is on the stack.
1170 // -- rax : value 1179 StoreIC_PushArgs(masm);
1171 // -- rcx : key
1172 // -- rdx : receiver
1173 // -- rsp[0] : return address
1174 // -----------------------------------
1175
1176 __ PopReturnAddressTo(rbx);
1177 __ Push(rdx); // receiver
1178 __ Push(rcx); // key
1179 __ Push(rax); // value
1180 __ PushReturnAddressFrom(rbx);
1181 1180
1182 // Do tail-call to runtime routine. 1181 // Do tail-call to runtime routine.
1183 ExternalReference ref(IC_Utility(kStoreIC_Slow), masm->isolate()); 1182 ExternalReference ref(IC_Utility(kStoreIC_Slow), masm->isolate());
1184 __ TailCallExternalReference(ref, 3, 1); 1183 __ TailCallExternalReference(ref, 3, 1);
1185 } 1184 }
1186 1185
1187 1186
1188 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { 1187 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
1189 // ----------- S t a t e ------------- 1188 // Return address is on the stack.
1190 // -- rax : value 1189 StoreIC_PushArgs(masm);
1191 // -- rcx : key
1192 // -- rdx : receiver
1193 // -- rsp[0] : return address
1194 // -----------------------------------
1195
1196 __ PopReturnAddressTo(rbx);
1197 __ Push(rdx); // receiver
1198 __ Push(rcx); // key
1199 __ Push(rax); // value
1200 __ PushReturnAddressFrom(rbx);
1201 1190
1202 // Do tail-call to runtime routine. 1191 // Do tail-call to runtime routine.
1203 ExternalReference ref(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); 1192 ExternalReference ref(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
1204 __ TailCallExternalReference(ref, 3, 1); 1193 __ TailCallExternalReference(ref, 3, 1);
1205 } 1194 }
1206 1195
1207 1196
1208 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 1197 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1209 // ----------- S t a t e ------------- 1198 // Return address is on the stack.
1210 // -- rax : value 1199 StoreIC_PushArgs(masm);
1211 // -- rcx : key
1212 // -- rdx : receiver
1213 // -- rsp[0] : return address
1214 // -----------------------------------
1215
1216 __ PopReturnAddressTo(rbx);
1217 __ Push(rdx); // receiver
1218 __ Push(rcx); // key
1219 __ Push(rax); // value
1220 __ PushReturnAddressFrom(rbx);
1221 1200
1222 // Do tail-call to runtime routine. 1201 // Do tail-call to runtime routine.
1223 ExternalReference ref = 1202 ExternalReference ref =
1224 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); 1203 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
1225 __ TailCallExternalReference(ref, 3, 1); 1204 __ TailCallExternalReference(ref, 3, 1);
1226 } 1205 }
1227 1206
1228 1207
1229 #undef __ 1208 #undef __
1230 1209
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) 1272 Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1294 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1273 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1295 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1274 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1296 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1275 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1297 } 1276 }
1298 1277
1299 1278
1300 } } // namespace v8::internal 1279 } } // namespace v8::internal
1301 1280
1302 #endif // V8_TARGET_ARCH_X64 1281 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698