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

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

Issue 10985017: Turn get-own-property-descriptor.js test into a regression (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
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/ic.h ('k') | test/mjsunit/get-own-property-descriptor.js » ('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
626 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 743 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
627 StrictModeFlag strict_mode) { 744 StrictModeFlag strict_mode) {
628 // ----------- S t a t e ------------- 745 // ----------- S t a t e -------------
629 // -- rax : value 746 // -- rax : value
630 // -- rcx : key 747 // -- rcx : key
631 // -- rdx : receiver 748 // -- rdx : receiver
632 // -- rsp[0] : return address 749 // -- rsp[0] : return address
633 // ----------------------------------- 750 // -----------------------------------
634 Label slow, slow_with_tagged_index, fast, array, extra, check_extra_double; 751 Label slow, slow_with_tagged_index, fast_object, fast_object_grow;
635 Label fast_object_with_map_check, fast_object_without_map_check; 752 Label fast_double, fast_double_grow;
636 Label fast_double_with_map_check, fast_double_without_map_check; 753 Label array, extra, check_if_double_array;
637 Label transition_smi_elements, finish_object_store, non_double_value;
638 Label transition_double_elements;
639 754
640 // Check that the object isn't a smi. 755 // Check that the object isn't a smi.
641 __ JumpIfSmi(rdx, &slow_with_tagged_index); 756 __ JumpIfSmi(rdx, &slow_with_tagged_index);
642 // Get the map from the receiver. 757 // Get the map from the receiver.
643 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); 758 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset));
644 // Check that the receiver does not require access checks. We need 759 // Check that the receiver does not require access checks. We need
645 // to do this because this generic stub does not perform map checks. 760 // to do this because this generic stub does not perform map checks.
646 __ testb(FieldOperand(r9, Map::kBitFieldOffset), 761 __ testb(FieldOperand(r9, Map::kBitFieldOffset),
647 Immediate(1 << Map::kIsAccessCheckNeeded)); 762 Immediate(1 << Map::kIsAccessCheckNeeded));
648 __ j(not_zero, &slow_with_tagged_index); 763 __ j(not_zero, &slow_with_tagged_index);
(...skipping 10 matching lines...) Expand all
659 // Object case: Check key against length in the elements array. 774 // Object case: Check key against length in the elements array.
660 // rax: value 775 // rax: value
661 // rdx: JSObject 776 // rdx: JSObject
662 // rcx: index 777 // rcx: index
663 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 778 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
664 // Check array bounds. 779 // Check array bounds.
665 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 780 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
666 // rax: value 781 // rax: value
667 // rbx: FixedArray 782 // rbx: FixedArray
668 // rcx: index 783 // rcx: index
669 __ j(above, &fast_object_with_map_check); 784 __ j(above, &fast_object);
670 785
671 // Slow case: call runtime. 786 // Slow case: call runtime.
672 __ bind(&slow); 787 __ bind(&slow);
673 __ Integer32ToSmi(rcx, rcx); 788 __ Integer32ToSmi(rcx, rcx);
674 __ bind(&slow_with_tagged_index); 789 __ bind(&slow_with_tagged_index);
675 GenerateRuntimeSetProperty(masm, strict_mode); 790 GenerateRuntimeSetProperty(masm, strict_mode);
676 // Never returns to here. 791 // Never returns to here.
677 792
678 // Extra capacity case: Check if there is extra capacity to 793 // Extra capacity case: Check if there is extra capacity to
679 // perform the store and update the length. Used for adding one 794 // perform the store and update the length. Used for adding one
680 // element to the array by writing to array[array.length]. 795 // element to the array by writing to array[array.length].
681 __ bind(&extra); 796 __ bind(&extra);
682 // rax: value 797 // rax: value
683 // rdx: receiver (a JSArray) 798 // rdx: receiver (a JSArray)
684 // rbx: receiver's elements array (a FixedArray) 799 // rbx: receiver's elements array (a FixedArray)
685 // rcx: index 800 // rcx: index
686 // flags: smicompare (rdx.length(), rbx) 801 // flags: smicompare (rdx.length(), rbx)
687 __ j(not_equal, &slow); // do not leave holes in the array 802 __ j(not_equal, &slow); // do not leave holes in the array
688 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 803 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
689 __ j(below_equal, &slow); 804 __ j(below_equal, &slow);
690 // Increment index to get new length. 805 // Increment index to get new length.
691 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset)); 806 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
692 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex); 807 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
693 __ j(not_equal, &check_extra_double); 808 __ j(not_equal, &check_if_double_array);
694 __ leal(rdi, Operand(rcx, 1)); 809 __ jmp(&fast_object_grow);
695 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
696 __ jmp(&fast_object_without_map_check);
697 810
698 __ bind(&check_extra_double); 811 __ bind(&check_if_double_array);
699 // rdi: elements array's map 812 // rdi: elements array's map
700 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex); 813 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
701 __ j(not_equal, &slow); 814 __ j(not_equal, &slow);
702 __ leal(rdi, Operand(rcx, 1)); 815 __ jmp(&fast_double_grow);
703 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
704 __ jmp(&fast_double_without_map_check);
705 816
706 // Array case: Get the length and the elements array from the JS 817 // Array case: Get the length and the elements array from the JS
707 // array. Check that the array is in fast mode (and writable); if it 818 // array. Check that the array is in fast mode (and writable); if it
708 // is the length is always a smi. 819 // is the length is always a smi.
709 __ bind(&array); 820 __ bind(&array);
710 // rax: value 821 // rax: value
711 // rdx: receiver (a JSArray) 822 // rdx: receiver (a JSArray)
712 // rcx: index 823 // rcx: index
713 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 824 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
714 825
715 // Check the key against the length in the array, compute the 826 // Check the key against the length in the array, compute the
716 // address to store into and fall through to fast case. 827 // address to store into and fall through to fast case.
717 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 828 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
718 __ j(below_equal, &extra); 829 __ j(below_equal, &extra);
719 830
720 // Fast case: Do the store. 831 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
721 __ bind(&fast_object_with_map_check); 832 &slow, kCheckMap, kDontIncrementLength);
722 // rax: value 833 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
723 // rbx: receiver's elements array (a FixedArray) 834 &slow, kDontCheckMap, kIncrementLength);
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);
806 } 835 }
807 836
808 837
809 // The generated code does not accept smi keys. 838 // The generated code does not accept smi keys.
810 // The generated code falls through if both probes miss. 839 // The generated code falls through if both probes miss.
811 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm, 840 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
812 int argc, 841 int argc,
813 Code::Kind kind, 842 Code::Kind kind,
814 Code::ExtraICState extra_state) { 843 Code::ExtraICState extra_state) {
815 // ----------- S t a t e ------------- 844 // ----------- S t a t e -------------
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) 1806 Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1778 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1807 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1779 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1808 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1780 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1809 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1781 } 1810 }
1782 1811
1783 1812
1784 } } // namespace v8::internal 1813 } } // namespace v8::internal
1785 1814
1786 #endif // V8_TARGET_ARCH_X64 1815 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ic.h ('k') | test/mjsunit/get-own-property-descriptor.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698