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

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

Issue 11028027: Revert trunk to bleeding_edge at r12484 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 2 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.h » ('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 // 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 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), 616 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor),
617 masm->isolate()), 617 masm->isolate()),
618 2, 618 2,
619 1); 619 1);
620 620
621 __ bind(&slow); 621 __ bind(&slow);
622 GenerateMiss(masm, false); 622 GenerateMiss(masm, false);
623 } 623 }
624 624
625 625
626 static void KeyedStoreGenerateGenericHelper(
627 MacroAssembler* masm,
628 Label* fast_object,
629 Label* fast_double,
630 Label* slow,
631 KeyedStoreCheckMap check_map,
632 KeyedStoreIncrementLength increment_length) {
633 Label transition_smi_elements;
634 Label finish_object_store, non_double_value, transition_double_elements;
635 Label fast_double_without_map_check;
636 // Fast case: Do the store, could be either Object or double.
637 __ bind(fast_object);
638 // rax: value
639 // rbx: receiver's elements array (a FixedArray)
640 // rcx: index
641 // rdx: receiver (a JSArray)
642 // r9: map of receiver
643 if (check_map == kCheckMap) {
644 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
645 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
646 __ j(not_equal, fast_double);
647 }
648 // Smi stores don't require further checks.
649 Label non_smi_value;
650 __ JumpIfNotSmi(rax, &non_smi_value);
651 if (increment_length == kIncrementLength) {
652 // Add 1 to receiver->length.
653 __ leal(rdi, Operand(rcx, 1));
654 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
655 }
656 // It's irrelevant whether array is smi-only or not when writing a smi.
657 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
658 rax);
659 __ ret(0);
660
661 __ bind(&non_smi_value);
662 // Writing a non-smi, check whether array allows non-smi elements.
663 // r9: receiver's map
664 __ CheckFastObjectElements(r9, &transition_smi_elements);
665
666 __ bind(&finish_object_store);
667 if (increment_length == kIncrementLength) {
668 // Add 1 to receiver->length.
669 __ leal(rdi, Operand(rcx, 1));
670 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
671 }
672 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
673 rax);
674 __ movq(rdx, rax); // Preserve the value which is returned.
675 __ RecordWriteArray(
676 rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
677 __ ret(0);
678
679 __ bind(fast_double);
680 if (check_map == kCheckMap) {
681 // Check for fast double array case. If this fails, call through to the
682 // runtime.
683 // rdi: elements array's map
684 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
685 __ j(not_equal, slow);
686 }
687 __ bind(&fast_double_without_map_check);
688 __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0,
689 &transition_double_elements);
690 if (increment_length == kIncrementLength) {
691 // Add 1 to receiver->length.
692 __ leal(rdi, Operand(rcx, 1));
693 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
694 }
695 __ ret(0);
696
697 __ bind(&transition_smi_elements);
698 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
699
700 // Transition the array appropriately depending on the value type.
701 __ movq(r9, FieldOperand(rax, HeapObject::kMapOffset));
702 __ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
703 __ j(not_equal, &non_double_value);
704
705 // Value is a double. Transition FAST_SMI_ELEMENTS ->
706 // FAST_DOUBLE_ELEMENTS and complete the store.
707 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
708 FAST_DOUBLE_ELEMENTS,
709 rbx,
710 rdi,
711 slow);
712 ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
713 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
714 __ jmp(&fast_double_without_map_check);
715
716 __ bind(&non_double_value);
717 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
718 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
719 FAST_ELEMENTS,
720 rbx,
721 rdi,
722 slow);
723 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
724 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
725 __ jmp(&finish_object_store);
726
727 __ bind(&transition_double_elements);
728 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
729 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
730 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
731 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
732 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
733 FAST_ELEMENTS,
734 rbx,
735 rdi,
736 slow);
737 ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
738 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
739 __ jmp(&finish_object_store);
740 }
741
742
743 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 626 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
744 StrictModeFlag strict_mode) { 627 StrictModeFlag strict_mode) {
745 // ----------- S t a t e ------------- 628 // ----------- S t a t e -------------
746 // -- rax : value 629 // -- rax : value
747 // -- rcx : key 630 // -- rcx : key
748 // -- rdx : receiver 631 // -- rdx : receiver
749 // -- rsp[0] : return address 632 // -- rsp[0] : return address
750 // ----------------------------------- 633 // -----------------------------------
751 Label slow, slow_with_tagged_index, fast_object, fast_object_grow; 634 Label slow, slow_with_tagged_index, fast, array, extra, check_extra_double;
752 Label fast_double, fast_double_grow; 635 Label fast_object_with_map_check, fast_object_without_map_check;
753 Label array, extra, check_if_double_array; 636 Label fast_double_with_map_check, fast_double_without_map_check;
637 Label transition_smi_elements, finish_object_store, non_double_value;
638 Label transition_double_elements;
754 639
755 // Check that the object isn't a smi. 640 // Check that the object isn't a smi.
756 __ JumpIfSmi(rdx, &slow_with_tagged_index); 641 __ JumpIfSmi(rdx, &slow_with_tagged_index);
757 // Get the map from the receiver. 642 // Get the map from the receiver.
758 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); 643 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset));
759 // Check that the receiver does not require access checks. We need 644 // Check that the receiver does not require access checks. We need
760 // to do this because this generic stub does not perform map checks. 645 // to do this because this generic stub does not perform map checks.
761 __ testb(FieldOperand(r9, Map::kBitFieldOffset), 646 __ testb(FieldOperand(r9, Map::kBitFieldOffset),
762 Immediate(1 << Map::kIsAccessCheckNeeded)); 647 Immediate(1 << Map::kIsAccessCheckNeeded));
763 __ j(not_zero, &slow_with_tagged_index); 648 __ j(not_zero, &slow_with_tagged_index);
(...skipping 10 matching lines...) Expand all
774 // Object case: Check key against length in the elements array. 659 // Object case: Check key against length in the elements array.
775 // rax: value 660 // rax: value
776 // rdx: JSObject 661 // rdx: JSObject
777 // rcx: index 662 // rcx: index
778 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 663 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
779 // Check array bounds. 664 // Check array bounds.
780 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 665 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
781 // rax: value 666 // rax: value
782 // rbx: FixedArray 667 // rbx: FixedArray
783 // rcx: index 668 // rcx: index
784 __ j(above, &fast_object); 669 __ j(above, &fast_object_with_map_check);
785 670
786 // Slow case: call runtime. 671 // Slow case: call runtime.
787 __ bind(&slow); 672 __ bind(&slow);
788 __ Integer32ToSmi(rcx, rcx); 673 __ Integer32ToSmi(rcx, rcx);
789 __ bind(&slow_with_tagged_index); 674 __ bind(&slow_with_tagged_index);
790 GenerateRuntimeSetProperty(masm, strict_mode); 675 GenerateRuntimeSetProperty(masm, strict_mode);
791 // Never returns to here. 676 // Never returns to here.
792 677
793 // Extra capacity case: Check if there is extra capacity to 678 // Extra capacity case: Check if there is extra capacity to
794 // perform the store and update the length. Used for adding one 679 // perform the store and update the length. Used for adding one
795 // element to the array by writing to array[array.length]. 680 // element to the array by writing to array[array.length].
796 __ bind(&extra); 681 __ bind(&extra);
797 // rax: value 682 // rax: value
798 // rdx: receiver (a JSArray) 683 // rdx: receiver (a JSArray)
799 // rbx: receiver's elements array (a FixedArray) 684 // rbx: receiver's elements array (a FixedArray)
800 // rcx: index 685 // rcx: index
801 // flags: smicompare (rdx.length(), rbx) 686 // flags: smicompare (rdx.length(), rbx)
802 __ j(not_equal, &slow); // do not leave holes in the array 687 __ j(not_equal, &slow); // do not leave holes in the array
803 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 688 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
804 __ j(below_equal, &slow); 689 __ j(below_equal, &slow);
805 // Increment index to get new length. 690 // Increment index to get new length.
806 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset)); 691 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
807 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex); 692 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
808 __ j(not_equal, &check_if_double_array); 693 __ j(not_equal, &check_extra_double);
809 __ jmp(&fast_object_grow); 694 __ leal(rdi, Operand(rcx, 1));
695 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
696 __ jmp(&fast_object_without_map_check);
810 697
811 __ bind(&check_if_double_array); 698 __ bind(&check_extra_double);
812 // rdi: elements array's map 699 // rdi: elements array's map
813 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex); 700 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
814 __ j(not_equal, &slow); 701 __ j(not_equal, &slow);
815 __ jmp(&fast_double_grow); 702 __ leal(rdi, Operand(rcx, 1));
703 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
704 __ jmp(&fast_double_without_map_check);
816 705
817 // Array case: Get the length and the elements array from the JS 706 // Array case: Get the length and the elements array from the JS
818 // array. Check that the array is in fast mode (and writable); if it 707 // array. Check that the array is in fast mode (and writable); if it
819 // is the length is always a smi. 708 // is the length is always a smi.
820 __ bind(&array); 709 __ bind(&array);
821 // rax: value 710 // rax: value
822 // rdx: receiver (a JSArray) 711 // rdx: receiver (a JSArray)
823 // rcx: index 712 // rcx: index
824 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 713 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
825 714
826 // Check the key against the length in the array, compute the 715 // Check the key against the length in the array, compute the
827 // address to store into and fall through to fast case. 716 // address to store into and fall through to fast case.
828 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 717 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
829 __ j(below_equal, &extra); 718 __ j(below_equal, &extra);
830 719
831 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, 720 // Fast case: Do the store.
832 &slow, kCheckMap, kDontIncrementLength); 721 __ bind(&fast_object_with_map_check);
833 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, 722 // rax: value
834 &slow, kDontCheckMap, kIncrementLength); 723 // rbx: receiver's elements array (a FixedArray)
724 // rcx: index
725 // rdx: receiver (a JSArray)
726 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
727 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
728 __ j(not_equal, &fast_double_with_map_check);
729 __ bind(&fast_object_without_map_check);
730 // Smi stores don't require further checks.
731 Label non_smi_value;
732 __ JumpIfNotSmi(rax, &non_smi_value);
733 // It's irrelevant whether array is smi-only or not when writing a smi.
734 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
735 rax);
736 __ ret(0);
737
738 __ bind(&non_smi_value);
739 // Writing a non-smi, check whether array allows non-smi elements.
740 // r9: receiver's map
741 __ CheckFastObjectElements(r9, &transition_smi_elements);
742 __ bind(&finish_object_store);
743 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
744 rax);
745 __ movq(rdx, rax); // Preserve the value which is returned.
746 __ RecordWriteArray(
747 rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
748 __ ret(0);
749
750 __ bind(&fast_double_with_map_check);
751 // Check for fast double array case. If this fails, call through to the
752 // runtime.
753 // rdi: elements array's map
754 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
755 __ j(not_equal, &slow);
756 __ bind(&fast_double_without_map_check);
757 // If the value is a number, store it as a double in the FastDoubleElements
758 // array.
759 __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0,
760 &transition_double_elements);
761 __ ret(0);
762
763 __ bind(&transition_smi_elements);
764 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
765
766 // Transition the array appropriately depending on the value type.
767 __ movq(r9, FieldOperand(rax, HeapObject::kMapOffset));
768 __ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
769 __ j(not_equal, &non_double_value);
770
771 // Value is a double. Transition FAST_SMI_ELEMENTS ->
772 // FAST_DOUBLE_ELEMENTS and complete the store.
773 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
774 FAST_DOUBLE_ELEMENTS,
775 rbx,
776 rdi,
777 &slow);
778 ElementsTransitionGenerator::GenerateSmiToDouble(masm, &slow);
779 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
780 __ jmp(&fast_double_without_map_check);
781
782 __ bind(&non_double_value);
783 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
784 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
785 FAST_ELEMENTS,
786 rbx,
787 rdi,
788 &slow);
789 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
790 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
791 __ jmp(&finish_object_store);
792
793 __ bind(&transition_double_elements);
794 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
795 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
796 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
797 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
798 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
799 FAST_ELEMENTS,
800 rbx,
801 rdi,
802 &slow);
803 ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
804 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
805 __ jmp(&finish_object_store);
835 } 806 }
836 807
837 808
838 // The generated code does not accept smi keys. 809 // The generated code does not accept smi keys.
839 // The generated code falls through if both probes miss. 810 // The generated code falls through if both probes miss.
840 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm, 811 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
841 int argc, 812 int argc,
842 Code::Kind kind, 813 Code::Kind kind,
843 Code::ExtraICState extra_state) { 814 Code::ExtraICState extra_state) {
844 // ----------- S t a t e ------------- 815 // ----------- S t a t e -------------
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) 1777 Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1807 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1778 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1808 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1779 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1809 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1780 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1810 } 1781 }
1811 1782
1812 1783
1813 } } // namespace v8::internal 1784 } } // namespace v8::internal
1814 1785
1815 #endif // V8_TARGET_ARCH_X64 1786 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698