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