OLD | NEW |
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 | 5 |
6 #include "src/v8.h" | 6 #include "src/v8.h" |
7 | 7 |
8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
9 | 9 |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, | 759 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, |
760 receiver_map, t0, slow); | 760 receiver_map, t0, slow); |
761 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); | 761 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); |
762 ElementsTransitionGenerator::GenerateDoubleToObject( | 762 ElementsTransitionGenerator::GenerateDoubleToObject( |
763 masm, receiver, key, value, receiver_map, mode, slow); | 763 masm, receiver, key, value, receiver_map, mode, slow); |
764 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 764 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
765 __ jmp(&finish_object_store); | 765 __ jmp(&finish_object_store); |
766 } | 766 } |
767 | 767 |
768 | 768 |
769 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 769 void KeyedStoreIC::GenerateGeneric( |
770 StrictMode strict_mode) { | 770 MacroAssembler* masm, StrictMode strict_mode, |
| 771 KeyedStoreStubCacheRequirement handler_requirement) { |
771 // ---------- S t a t e -------------- | 772 // ---------- S t a t e -------------- |
772 // -- a0 : value | 773 // -- a0 : value |
773 // -- a1 : key | 774 // -- a1 : key |
774 // -- a2 : receiver | 775 // -- a2 : receiver |
775 // -- ra : return address | 776 // -- ra : return address |
776 // ----------------------------------- | 777 // ----------------------------------- |
777 Label slow, fast_object, fast_object_grow; | 778 Label slow, fast_object, fast_object_grow; |
778 Label fast_double, fast_double_grow; | 779 Label fast_double, fast_double_grow; |
779 Label array, extra, check_if_double_array; | 780 Label array, extra, check_if_double_array, maybe_name_key, miss; |
780 | 781 |
781 // Register usage. | 782 // Register usage. |
782 Register value = StoreDescriptor::ValueRegister(); | 783 Register value = StoreDescriptor::ValueRegister(); |
783 Register key = StoreDescriptor::NameRegister(); | 784 Register key = StoreDescriptor::NameRegister(); |
784 Register receiver = StoreDescriptor::ReceiverRegister(); | 785 Register receiver = StoreDescriptor::ReceiverRegister(); |
785 DCHECK(value.is(a0)); | 786 DCHECK(value.is(a0)); |
786 Register receiver_map = a3; | 787 Register receiver_map = a3; |
787 Register elements_map = t2; | 788 Register elements_map = t2; |
788 Register elements = t3; // Elements array of the receiver. | 789 Register elements = t3; // Elements array of the receiver. |
789 // t0 and t1 are used as general scratch registers. | 790 // t0 and t1 are used as general scratch registers. |
790 | 791 |
791 // Check that the key is a smi. | 792 // Check that the key is a smi. |
792 __ JumpIfNotSmi(key, &slow); | 793 __ JumpIfNotSmi(key, &maybe_name_key); |
793 // Check that the object isn't a smi. | 794 // Check that the object isn't a smi. |
794 __ JumpIfSmi(receiver, &slow); | 795 __ JumpIfSmi(receiver, &slow); |
795 // Get the map of the object. | 796 // Get the map of the object. |
796 __ lw(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 797 __ lw(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
797 // Check that the receiver does not require access checks and is not observed. | 798 // Check that the receiver does not require access checks and is not observed. |
798 // The generic stub does not perform map checks or handle observed objects. | 799 // The generic stub does not perform map checks or handle observed objects. |
799 __ lbu(t0, FieldMemOperand(receiver_map, Map::kBitFieldOffset)); | 800 __ lbu(t0, FieldMemOperand(receiver_map, Map::kBitFieldOffset)); |
800 __ And(t0, t0, | 801 __ And(t0, t0, |
801 Operand(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved)); | 802 Operand(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved)); |
802 __ Branch(&slow, ne, t0, Operand(zero_reg)); | 803 __ Branch(&slow, ne, t0, Operand(zero_reg)); |
803 // Check if the object is a JS array or not. | 804 // Check if the object is a JS array or not. |
804 __ lbu(t0, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset)); | 805 __ lbu(t0, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset)); |
805 __ Branch(&array, eq, t0, Operand(JS_ARRAY_TYPE)); | 806 __ Branch(&array, eq, t0, Operand(JS_ARRAY_TYPE)); |
806 // Check that the object is some kind of JSObject. | 807 // Check that the object is some kind of JSObject. |
807 __ Branch(&slow, lt, t0, Operand(FIRST_JS_OBJECT_TYPE)); | 808 __ Branch(&slow, lt, t0, Operand(FIRST_JS_OBJECT_TYPE)); |
808 | 809 |
809 // Object case: Check key against length in the elements array. | 810 // Object case: Check key against length in the elements array. |
810 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 811 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
811 // Check array bounds. Both the key and the length of FixedArray are smis. | 812 // Check array bounds. Both the key and the length of FixedArray are smis. |
812 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 813 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
813 __ Branch(&fast_object, lo, key, Operand(t0)); | 814 __ Branch(&fast_object, lo, key, Operand(t0)); |
814 | 815 |
815 // Slow case, handle jump to runtime. | 816 // Slow case, handle jump to runtime. |
816 __ bind(&slow); | 817 __ bind(&slow); |
817 // Entry registers are intact. | 818 // Entry registers are intact. |
818 // a0: value. | 819 // a0: value. |
819 // a1: key. | 820 // a1: key. |
820 // a2: receiver. | 821 // a2: receiver. |
821 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); | 822 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); |
| 823 // Never returns to here. |
| 824 |
| 825 __ bind(&maybe_name_key); |
| 826 __ lw(t0, FieldMemOperand(key, HeapObject::kMapOffset)); |
| 827 __ lb(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); |
| 828 __ JumpIfNotUniqueNameInstanceType(t0, &slow); |
| 829 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 830 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 831 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, |
| 832 key, a3, t0, t1, t2); |
| 833 // Cache miss. |
| 834 if (handler_requirement == kCallRuntimeOnMissingHandler) { |
| 835 __ Branch(&slow); |
| 836 } else { |
| 837 DCHECK(handler_requirement == kMissOnMissingHandler); |
| 838 __ Branch(&miss); |
| 839 } |
822 | 840 |
823 // Extra capacity case: Check if there is extra capacity to | 841 // Extra capacity case: Check if there is extra capacity to |
824 // perform the store and update the length. Used for adding one | 842 // perform the store and update the length. Used for adding one |
825 // element to the array by writing to array[array.length]. | 843 // element to the array by writing to array[array.length]. |
826 __ bind(&extra); | 844 __ bind(&extra); |
827 // Condition code from comparing key and array length is still available. | 845 // Condition code from comparing key and array length is still available. |
828 // Only support writing to array[array.length]. | 846 // Only support writing to array[array.length]. |
829 __ Branch(&slow, ne, key, Operand(t0)); | 847 __ Branch(&slow, ne, key, Operand(t0)); |
830 // Check for room in the elements backing store. | 848 // Check for room in the elements backing store. |
831 // Both the key and the length of FixedArray are smis. | 849 // Both the key and the length of FixedArray are smis. |
(...skipping 19 matching lines...) Expand all Loading... |
851 __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 869 __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
852 __ Branch(&extra, hs, key, Operand(t0)); | 870 __ Branch(&extra, hs, key, Operand(t0)); |
853 | 871 |
854 KeyedStoreGenerateGenericHelper( | 872 KeyedStoreGenerateGenericHelper( |
855 masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength, | 873 masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength, |
856 value, key, receiver, receiver_map, elements_map, elements); | 874 value, key, receiver, receiver_map, elements_map, elements); |
857 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 875 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
858 &slow, kDontCheckMap, kIncrementLength, value, | 876 &slow, kDontCheckMap, kIncrementLength, value, |
859 key, receiver, receiver_map, elements_map, | 877 key, receiver, receiver_map, elements_map, |
860 elements); | 878 elements); |
| 879 |
| 880 __ bind(&miss); |
| 881 GenerateMiss(masm); |
861 } | 882 } |
862 | 883 |
863 | 884 |
864 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { | 885 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { |
865 // Push receiver, key and value for runtime call. | 886 // Push receiver, key and value for runtime call. |
866 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), | 887 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), |
867 StoreDescriptor::ValueRegister()); | 888 StoreDescriptor::ValueRegister()); |
868 | 889 |
869 ExternalReference ref = | 890 ExternalReference ref = |
870 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); | 891 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 patcher.ChangeBranchCondition(ne); | 1036 patcher.ChangeBranchCondition(ne); |
1016 } else { | 1037 } else { |
1017 DCHECK(Assembler::IsBne(branch_instr)); | 1038 DCHECK(Assembler::IsBne(branch_instr)); |
1018 patcher.ChangeBranchCondition(eq); | 1039 patcher.ChangeBranchCondition(eq); |
1019 } | 1040 } |
1020 } | 1041 } |
1021 } | 1042 } |
1022 } // namespace v8::internal | 1043 } // namespace v8::internal |
1023 | 1044 |
1024 #endif // V8_TARGET_ARCH_MIPS | 1045 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |