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/ia32/ic-ia32.cc

Issue 11035053: Rollback trunk to bleeding_edge revision 12525 (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/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-codegen-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 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 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 __ mov(unmapped_location, eax); 740 __ mov(unmapped_location, eax);
741 __ lea(edi, unmapped_location); 741 __ lea(edi, unmapped_location);
742 __ mov(edx, eax); 742 __ mov(edx, eax);
743 __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs); 743 __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs);
744 __ Ret(); 744 __ Ret();
745 __ bind(&slow); 745 __ bind(&slow);
746 GenerateMiss(masm, false); 746 GenerateMiss(masm, false);
747 } 747 }
748 748
749 749
750 static void KeyedStoreGenerateGenericHelper(
751 MacroAssembler* masm,
752 Label* fast_object,
753 Label* fast_double,
754 Label* slow,
755 KeyedStoreCheckMap check_map,
756 KeyedStoreIncrementLength increment_length) {
757 Label transition_smi_elements;
758 Label finish_object_store, non_double_value, transition_double_elements;
759 Label fast_double_without_map_check;
760 // eax: value
761 // ecx: key (a smi)
762 // edx: receiver
763 // ebx: FixedArray receiver->elements
764 // edi: receiver map
765 // Fast case: Do the store, could either Object or double.
766 __ bind(fast_object);
767 if (check_map == kCheckMap) {
768 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
769 __ cmp(edi, masm->isolate()->factory()->fixed_array_map());
770 __ j(not_equal, fast_double);
771 }
772 // Smi stores don't require further checks.
773 Label non_smi_value;
774 __ JumpIfNotSmi(eax, &non_smi_value);
775 if (increment_length == kIncrementLength) {
776 // Add 1 to receiver->length.
777 __ add(FieldOperand(edx, JSArray::kLengthOffset),
778 Immediate(Smi::FromInt(1)));
779 }
780 // It's irrelevant whether array is smi-only or not when writing a smi.
781 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
782 __ ret(0);
783
784 __ bind(&non_smi_value);
785 // Escape to elements kind transition case.
786 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
787 __ CheckFastObjectElements(edi, &transition_smi_elements);
788
789 // Fast elements array, store the value to the elements backing store.
790 __ bind(&finish_object_store);
791 if (increment_length == kIncrementLength) {
792 // Add 1 to receiver->length.
793 __ add(FieldOperand(edx, JSArray::kLengthOffset),
794 Immediate(Smi::FromInt(1)));
795 }
796 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
797 // Update write barrier for the elements array address.
798 __ mov(edx, eax); // Preserve the value which is returned.
799 __ RecordWriteArray(
800 ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
801 __ ret(0);
802
803 __ bind(fast_double);
804 if (check_map == kCheckMap) {
805 // Check for fast double array case. If this fails, call through to the
806 // runtime.
807 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map());
808 __ j(not_equal, slow);
809 // If the value is a number, store it as a double in the FastDoubleElements
810 // array.
811 }
812 __ bind(&fast_double_without_map_check);
813 __ StoreNumberToDoubleElements(eax, ebx, ecx, edi, xmm0,
814 &transition_double_elements, false);
815 if (increment_length == kIncrementLength) {
816 // Add 1 to receiver->length.
817 __ add(FieldOperand(edx, JSArray::kLengthOffset),
818 Immediate(Smi::FromInt(1)));
819 }
820 __ ret(0);
821
822 __ bind(&transition_smi_elements);
823 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
824
825 // Transition the array appropriately depending on the value type.
826 __ CheckMap(eax,
827 masm->isolate()->factory()->heap_number_map(),
828 &non_double_value,
829 DONT_DO_SMI_CHECK);
830
831 // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS
832 // and complete the store.
833 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
834 FAST_DOUBLE_ELEMENTS,
835 ebx,
836 edi,
837 slow);
838 ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
839 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
840 __ jmp(&fast_double_without_map_check);
841
842 __ bind(&non_double_value);
843 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
844 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
845 FAST_ELEMENTS,
846 ebx,
847 edi,
848 slow);
849 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
850 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
851 __ jmp(&finish_object_store);
852
853 __ bind(&transition_double_elements);
854 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
855 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
856 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
857 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
858 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
859 FAST_ELEMENTS,
860 ebx,
861 edi,
862 slow);
863 ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
864 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
865 __ jmp(&finish_object_store);
866 }
867
868
869 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 750 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
870 StrictModeFlag strict_mode) { 751 StrictModeFlag strict_mode) {
871 // ----------- S t a t e ------------- 752 // ----------- S t a t e -------------
872 // -- eax : value 753 // -- eax : value
873 // -- ecx : key 754 // -- ecx : key
874 // -- edx : receiver 755 // -- edx : receiver
875 // -- esp[0] : return address 756 // -- esp[0] : return address
876 // ----------------------------------- 757 // -----------------------------------
877 Label slow, fast_object, fast_object_grow; 758 Label slow, fast_object_with_map_check, fast_object_without_map_check;
878 Label fast_double, fast_double_grow; 759 Label fast_double_with_map_check, fast_double_without_map_check;
879 Label array, extra, check_if_double_array; 760 Label check_if_double_array, array, extra, transition_smi_elements;
761 Label finish_object_store, non_double_value, transition_double_elements;
880 762
881 // Check that the object isn't a smi. 763 // Check that the object isn't a smi.
882 __ JumpIfSmi(edx, &slow); 764 __ JumpIfSmi(edx, &slow);
883 // Get the map from the receiver. 765 // Get the map from the receiver.
884 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); 766 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
885 // Check that the receiver does not require access checks. We need 767 // Check that the receiver does not require access checks. We need
886 // to do this because this generic stub does not perform map checks. 768 // to do this because this generic stub does not perform map checks.
887 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), 769 __ test_b(FieldOperand(edi, Map::kBitFieldOffset),
888 1 << Map::kIsAccessCheckNeeded); 770 1 << Map::kIsAccessCheckNeeded);
889 __ j(not_zero, &slow); 771 __ j(not_zero, &slow);
890 // Check that the key is a smi. 772 // Check that the key is a smi.
891 __ JumpIfNotSmi(ecx, &slow); 773 __ JumpIfNotSmi(ecx, &slow);
892 __ CmpInstanceType(edi, JS_ARRAY_TYPE); 774 __ CmpInstanceType(edi, JS_ARRAY_TYPE);
893 __ j(equal, &array); 775 __ j(equal, &array);
894 // Check that the object is some kind of JSObject. 776 // Check that the object is some kind of JSObject.
895 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); 777 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE);
896 __ j(below, &slow); 778 __ j(below, &slow);
897 779
898 // Object case: Check key against length in the elements array. 780 // Object case: Check key against length in the elements array.
899 // eax: value 781 // eax: value
900 // edx: JSObject 782 // edx: JSObject
901 // ecx: key (a smi) 783 // ecx: key (a smi)
902 // edi: receiver map 784 // edi: receiver map
903 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 785 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
904 // Check array bounds. Both the key and the length of FixedArray are smis. 786 // Check array bounds. Both the key and the length of FixedArray are smis.
905 __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); 787 __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
906 __ j(below, &fast_object); 788 __ j(below, &fast_object_with_map_check);
907 789
908 // Slow case: call runtime. 790 // Slow case: call runtime.
909 __ bind(&slow); 791 __ bind(&slow);
910 GenerateRuntimeSetProperty(masm, strict_mode); 792 GenerateRuntimeSetProperty(masm, strict_mode);
911 793
912 // Extra capacity case: Check if there is extra capacity to 794 // Extra capacity case: Check if there is extra capacity to
913 // perform the store and update the length. Used for adding one 795 // perform the store and update the length. Used for adding one
914 // element to the array by writing to array[array.length]. 796 // element to the array by writing to array[array.length].
915 __ bind(&extra); 797 __ bind(&extra);
916 // eax: value 798 // eax: value
917 // edx: receiver, a JSArray 799 // edx: receiver, a JSArray
918 // ecx: key, a smi. 800 // ecx: key, a smi.
919 // ebx: receiver->elements, a FixedArray 801 // ebx: receiver->elements, a FixedArray
920 // edi: receiver map 802 // edi: receiver map
921 // flags: compare (ecx, edx.length()) 803 // flags: compare (ecx, edx.length())
922 // do not leave holes in the array: 804 // do not leave holes in the array:
923 __ j(not_equal, &slow); 805 __ j(not_equal, &slow);
924 __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); 806 __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
925 __ j(above_equal, &slow); 807 __ j(above_equal, &slow);
926 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); 808 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
927 __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); 809 __ cmp(edi, masm->isolate()->factory()->fixed_array_map());
928 __ j(not_equal, &check_if_double_array); 810 __ j(not_equal, &check_if_double_array);
929 __ jmp(&fast_object_grow); 811 // Add 1 to receiver->length, and go to common element store code for Objects.
812 __ add(FieldOperand(edx, JSArray::kLengthOffset),
813 Immediate(Smi::FromInt(1)));
814 __ jmp(&fast_object_without_map_check);
930 815
931 __ bind(&check_if_double_array); 816 __ bind(&check_if_double_array);
932 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); 817 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map());
933 __ j(not_equal, &slow); 818 __ j(not_equal, &slow);
934 __ jmp(&fast_double_grow); 819 // Add 1 to receiver->length, and go to common element store code for doubles.
820 __ add(FieldOperand(edx, JSArray::kLengthOffset),
821 Immediate(Smi::FromInt(1)));
822 __ jmp(&fast_double_without_map_check);
935 823
936 // Array case: Get the length and the elements array from the JS 824 // Array case: Get the length and the elements array from the JS
937 // array. Check that the array is in fast mode (and writable); if it 825 // array. Check that the array is in fast mode (and writable); if it
938 // is the length is always a smi. 826 // is the length is always a smi.
939 __ bind(&array); 827 __ bind(&array);
940 // eax: value 828 // eax: value
941 // edx: receiver, a JSArray 829 // edx: receiver, a JSArray
942 // ecx: key, a smi. 830 // ecx: key, a smi.
943 // edi: receiver map 831 // edi: receiver map
944 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 832 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
945 833
946 // Check the key against the length in the array and fall through to the 834 // Check the key against the length in the array and fall through to the
947 // common store code. 835 // common store code.
948 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. 836 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
949 __ j(above_equal, &extra); 837 __ j(above_equal, &extra);
950 838
951 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, 839 // Fast case: Do the store, could either Object or double.
952 &slow, kCheckMap, kDontIncrementLength); 840 __ bind(&fast_object_with_map_check);
953 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, 841 // eax: value
954 &slow, kDontCheckMap, kIncrementLength); 842 // ecx: key (a smi)
843 // edx: receiver
844 // ebx: FixedArray receiver->elements
845 // edi: receiver map
846 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
847 __ cmp(edi, masm->isolate()->factory()->fixed_array_map());
848 __ j(not_equal, &fast_double_with_map_check);
849 __ bind(&fast_object_without_map_check);
850 // Smi stores don't require further checks.
851 Label non_smi_value;
852 __ JumpIfNotSmi(eax, &non_smi_value);
853 // It's irrelevant whether array is smi-only or not when writing a smi.
854 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
855 __ ret(0);
856
857 __ bind(&non_smi_value);
858 // Escape to elements kind transition case.
859 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
860 __ CheckFastObjectElements(edi, &transition_smi_elements);
861
862 // Fast elements array, store the value to the elements backing store.
863 __ bind(&finish_object_store);
864 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
865 // Update write barrier for the elements array address.
866 __ mov(edx, eax); // Preserve the value which is returned.
867 __ RecordWriteArray(
868 ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
869 __ ret(0);
870
871 __ bind(&fast_double_with_map_check);
872 // Check for fast double array case. If this fails, call through to the
873 // runtime.
874 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map());
875 __ j(not_equal, &slow);
876 __ bind(&fast_double_without_map_check);
877 // If the value is a number, store it as a double in the FastDoubleElements
878 // array.
879 __ StoreNumberToDoubleElements(eax, ebx, ecx, edx, xmm0,
880 &transition_double_elements, false);
881 __ ret(0);
882
883 __ bind(&transition_smi_elements);
884 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
885
886 // Transition the array appropriately depending on the value type.
887 __ CheckMap(eax,
888 masm->isolate()->factory()->heap_number_map(),
889 &non_double_value,
890 DONT_DO_SMI_CHECK);
891
892 // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS
893 // and complete the store.
894 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
895 FAST_DOUBLE_ELEMENTS,
896 ebx,
897 edi,
898 &slow);
899 ElementsTransitionGenerator::GenerateSmiToDouble(masm, &slow);
900 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
901 __ jmp(&fast_double_without_map_check);
902
903 __ bind(&non_double_value);
904 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
905 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
906 FAST_ELEMENTS,
907 ebx,
908 edi,
909 &slow);
910 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
911 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
912 __ jmp(&finish_object_store);
913
914 __ bind(&transition_double_elements);
915 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
916 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
917 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
918 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
919 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
920 FAST_ELEMENTS,
921 ebx,
922 edi,
923 &slow);
924 ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
925 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
926 __ jmp(&finish_object_store);
955 } 927 }
956 928
957 929
958 // The generated code does not accept smi keys. 930 // The generated code does not accept smi keys.
959 // The generated code falls through if both probes miss. 931 // The generated code falls through if both probes miss.
960 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm, 932 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
961 int argc, 933 int argc,
962 Code::Kind kind, 934 Code::Kind kind,
963 Code::ExtraICState extra_state) { 935 Code::ExtraICState extra_state) {
964 // ----------- S t a t e ------------- 936 // ----------- S t a t e -------------
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) 1765 Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1794 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1766 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1795 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1767 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1796 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1768 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1797 } 1769 }
1798 1770
1799 1771
1800 } } // namespace v8::internal 1772 } } // namespace v8::internal
1801 1773
1802 #endif // V8_TARGET_ARCH_IA32 1774 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698