| 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 |