OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 __ j(equal, &slow); | 758 __ j(equal, &slow); |
759 __ CmpInstanceType(edi, JS_FUNCTION_PROXY_TYPE); | 759 __ CmpInstanceType(edi, JS_FUNCTION_PROXY_TYPE); |
760 __ j(equal, &slow); | 760 __ j(equal, &slow); |
761 | 761 |
762 // Object case: Check key against length in the elements array. | 762 // Object case: Check key against length in the elements array. |
763 // eax: value | 763 // eax: value |
764 // edx: JSObject | 764 // edx: JSObject |
765 // ecx: key (a smi) | 765 // ecx: key (a smi) |
766 // edi: receiver map | 766 // edi: receiver map |
767 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); | 767 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); |
768 // Check that the object is in fast mode and writable. | 768 // Check array bounds. Both the key and the length of FixedArray are smis. |
769 __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); | 769 __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); |
770 __ j(below, &fast_object_with_map_check); | 770 __ j(below, &fast_object_with_map_check); |
771 | 771 |
772 // Slow case: call runtime. | 772 // Slow case: call runtime. |
773 __ bind(&slow); | 773 __ bind(&slow); |
774 GenerateRuntimeSetProperty(masm, strict_mode); | 774 GenerateRuntimeSetProperty(masm, strict_mode); |
775 | 775 |
776 // Extra capacity case: Check if there is extra capacity to | 776 // Extra capacity case: Check if there is extra capacity to |
777 // perform the store and update the length. Used for adding one | 777 // perform the store and update the length. Used for adding one |
778 // element to the array by writing to array[array.length]. | 778 // element to the array by writing to array[array.length]. |
779 __ bind(&extra); | 779 __ bind(&extra); |
780 // eax: value | 780 // eax: value |
781 // edx: receiver, a JSArray | 781 // edx: receiver, a JSArray |
782 // ecx: key, a smi. | 782 // ecx: key, a smi. |
783 // ebx: receiver->elements, a FixedArray | 783 // ebx: receiver->elements, a FixedArray |
784 // edi: receiver map | 784 // edi: receiver map |
785 // flags: compare (ecx, edx.length()) | 785 // flags: compare (ecx, edx.length()) |
786 // do not leave holes in the array: | 786 // do not leave holes in the array: |
787 __ j(not_equal, &slow); | 787 __ j(not_equal, &slow); |
788 __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); | 788 __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); |
789 __ j(above_equal, &slow); | 789 __ j(above_equal, &slow); |
790 __ CheckMap(ebx, FACTORY->fixed_array_map(), | 790 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); |
791 &check_if_double_array, DONT_DO_SMI_CHECK); | 791 __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); |
| 792 __ j(not_equal, &check_if_double_array); |
792 // Add 1 to receiver->length, and go to common element store code for Objects. | 793 // Add 1 to receiver->length, and go to common element store code for Objects. |
793 __ add(FieldOperand(edx, JSArray::kLengthOffset), | 794 __ add(FieldOperand(edx, JSArray::kLengthOffset), |
794 Immediate(Smi::FromInt(1))); | 795 Immediate(Smi::FromInt(1))); |
795 __ jmp(&fast_object_without_map_check); | 796 __ jmp(&fast_object_without_map_check); |
796 | 797 |
797 __ bind(&check_if_double_array); | 798 __ bind(&check_if_double_array); |
798 __ CheckMap(ebx, FACTORY->fixed_double_array_map(), &slow, DONT_DO_SMI_CHECK); | 799 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); |
| 800 __ j(not_equal, &slow); |
799 // Add 1 to receiver->length, and go to common element store code for doubles. | 801 // Add 1 to receiver->length, and go to common element store code for doubles. |
800 __ add(FieldOperand(edx, JSArray::kLengthOffset), | 802 __ add(FieldOperand(edx, JSArray::kLengthOffset), |
801 Immediate(Smi::FromInt(1))); | 803 Immediate(Smi::FromInt(1))); |
802 __ jmp(&fast_double_without_map_check); | 804 __ jmp(&fast_double_without_map_check); |
803 | 805 |
804 // Array case: Get the length and the elements array from the JS | 806 // Array case: Get the length and the elements array from the JS |
805 // array. Check that the array is in fast mode (and writable); if it | 807 // array. Check that the array is in fast mode (and writable); if it |
806 // is the length is always a smi. | 808 // is the length is always a smi. |
807 __ bind(&array); | 809 __ bind(&array); |
808 // eax: value | 810 // eax: value |
809 // edx: receiver, a JSArray | 811 // edx: receiver, a JSArray |
810 // ecx: key, a smi. | 812 // ecx: key, a smi. |
811 // edi: receiver map | 813 // edi: receiver map |
812 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); | 814 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); |
813 | 815 |
814 // Check the key against the length in the array and fall through to the | 816 // Check the key against the length in the array and fall through to the |
815 // common store code. | 817 // common store code. |
816 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. | 818 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. |
817 __ j(above_equal, &extra); | 819 __ j(above_equal, &extra); |
818 | 820 |
819 // Fast case: Do the store, could either Object or double. | 821 // Fast case: Do the store, could either Object or double. |
820 __ bind(&fast_object_with_map_check); | 822 __ bind(&fast_object_with_map_check); |
821 // eax: value | 823 // eax: value |
822 // ecx: key (a smi) | 824 // ecx: key (a smi) |
823 // edx: receiver | 825 // edx: receiver |
824 // ebx: FixedArray receiver->elements | 826 // ebx: FixedArray receiver->elements |
825 // edi: receiver map | 827 // edi: receiver map |
826 __ CheckMap(ebx, FACTORY->fixed_array_map(), | 828 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); |
827 &fast_double_with_map_check, DONT_DO_SMI_CHECK); | 829 __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); |
| 830 __ j(not_equal, &fast_double_with_map_check); |
828 __ bind(&fast_object_without_map_check); | 831 __ bind(&fast_object_without_map_check); |
829 // Smi stores don't require further checks. | 832 // Smi stores don't require further checks. |
830 Label non_smi_value; | 833 Label non_smi_value; |
831 __ JumpIfNotSmi(eax, &non_smi_value); | 834 __ JumpIfNotSmi(eax, &non_smi_value); |
832 // It's irrelevant whether array is smi-only or not when writing a smi. | 835 // It's irrelevant whether array is smi-only or not when writing a smi. |
833 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax); | 836 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax); |
834 __ ret(0); | 837 __ ret(0); |
835 | 838 |
836 __ bind(&non_smi_value); | 839 __ bind(&non_smi_value); |
837 if (FLAG_smi_only_arrays) { | 840 if (FLAG_smi_only_arrays) { |
838 // Escape to slow case when writing non-smi into smi-only array. | 841 // Escape to slow case when writing non-smi into smi-only array. |
| 842 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); |
839 __ CheckFastObjectElements(edi, &slow, Label::kNear); | 843 __ CheckFastObjectElements(edi, &slow, Label::kNear); |
840 } | 844 } |
841 | 845 |
842 // Fast elements array, store the value to the elements backing store. | 846 // Fast elements array, store the value to the elements backing store. |
843 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax); | 847 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax); |
844 // Update write barrier for the elements array address. | 848 // Update write barrier for the elements array address. |
845 __ mov(edx, Operand(eax)); // Preserve the value which is returned. | 849 __ mov(edx, Operand(eax)); // Preserve the value which is returned. |
846 __ RecordWriteArray( | 850 __ RecordWriteArray( |
847 ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 851 ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
848 __ ret(0); | 852 __ ret(0); |
849 | 853 |
850 __ bind(&fast_double_with_map_check); | 854 __ bind(&fast_double_with_map_check); |
851 // Check for fast double array case. If this fails, call through to the | 855 // Check for fast double array case. If this fails, call through to the |
852 // runtime. | 856 // runtime. |
853 __ CheckMap(ebx, FACTORY->fixed_double_array_map(), &slow, DONT_DO_SMI_CHECK); | 857 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); |
| 858 __ j(not_equal, &slow); |
854 __ bind(&fast_double_without_map_check); | 859 __ bind(&fast_double_without_map_check); |
855 // If the value is a number, store it as a double in the FastDoubleElements | 860 // If the value is a number, store it as a double in the FastDoubleElements |
856 // array. | 861 // array. |
857 __ StoreNumberToDoubleElements(eax, | 862 __ StoreNumberToDoubleElements(eax, ebx, ecx, edx, xmm0, &slow, false); |
858 ebx, | |
859 ecx, | |
860 edx, | |
861 xmm0, | |
862 &slow, | |
863 false); | |
864 __ ret(0); | 863 __ ret(0); |
865 } | 864 } |
866 | 865 |
867 | 866 |
868 // The generated code does not accept smi keys. | 867 // The generated code does not accept smi keys. |
869 // The generated code falls through if both probes miss. | 868 // The generated code falls through if both probes miss. |
870 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, | 869 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, |
871 int argc, | 870 int argc, |
872 Code::Kind kind, | 871 Code::Kind kind, |
873 Code::ExtraICState extra_ic_state) { | 872 Code::ExtraICState extra_ic_state) { |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1683 Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1682 Condition cc = *jmp_address == Assembler::kJncShortOpcode |
1684 ? not_zero | 1683 ? not_zero |
1685 : zero; | 1684 : zero; |
1686 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1685 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1687 } | 1686 } |
1688 | 1687 |
1689 | 1688 |
1690 } } // namespace v8::internal | 1689 } } // namespace v8::internal |
1691 | 1690 |
1692 #endif // V8_TARGET_ARCH_IA32 | 1691 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |