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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 2811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2822 arg_count(), | 2822 arg_count(), |
2823 true, | 2823 true, |
2824 CallAsMethod()); | 2824 CallAsMethod()); |
2825 | 2825 |
2826 // Unreachable. | 2826 // Unreachable. |
2827 __ stop("Unexpected code address"); | 2827 __ stop("Unexpected code address"); |
2828 } | 2828 } |
2829 | 2829 |
2830 | 2830 |
2831 void CallICStub::Generate(MacroAssembler* masm) { | 2831 void CallICStub::Generate(MacroAssembler* masm) { |
2832 // r1 - function | 2832 // a1 - function |
2833 // r3 - slot id (Smi) | 2833 // a3 - slot id (Smi) |
| 2834 const int with_types_offset = |
| 2835 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 2836 const int generic_offset = |
| 2837 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
2834 Label extra_checks_or_miss, slow_start; | 2838 Label extra_checks_or_miss, slow_start; |
2835 Label slow, non_function, wrap, cont; | 2839 Label slow, non_function, wrap, cont; |
2836 Label have_js_function; | 2840 Label have_js_function; |
2837 int argc = arg_count(); | 2841 int argc = arg_count(); |
2838 ParameterCount actual(argc); | 2842 ParameterCount actual(argc); |
2839 | 2843 |
2840 EmitLoadTypeFeedbackVector(masm, a2); | 2844 EmitLoadTypeFeedbackVector(masm, a2); |
2841 | 2845 |
2842 // The checks. First, does r1 match the recorded monomorphic target? | 2846 // The checks. First, does r1 match the recorded monomorphic target? |
2843 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); | 2847 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
(...skipping 18 matching lines...) Expand all Loading... |
2862 | 2866 |
2863 __ bind(&slow); | 2867 __ bind(&slow); |
2864 EmitSlowCase(masm, argc, &non_function); | 2868 EmitSlowCase(masm, argc, &non_function); |
2865 | 2869 |
2866 if (CallAsMethod()) { | 2870 if (CallAsMethod()) { |
2867 __ bind(&wrap); | 2871 __ bind(&wrap); |
2868 EmitWrapCase(masm, argc, &cont); | 2872 EmitWrapCase(masm, argc, &cont); |
2869 } | 2873 } |
2870 | 2874 |
2871 __ bind(&extra_checks_or_miss); | 2875 __ bind(&extra_checks_or_miss); |
2872 Label miss; | 2876 Label uninitialized, miss; |
2873 | 2877 |
2874 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 2878 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
2875 __ Branch(&slow_start, eq, t0, Operand(at)); | 2879 __ Branch(&slow_start, eq, t0, Operand(at)); |
2876 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); | |
2877 __ Branch(&miss, eq, t0, Operand(at)); | |
2878 | 2880 |
2879 if (!FLAG_trace_ic) { | 2881 // The following cases attempt to handle MISS cases without going to the |
2880 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 2882 // runtime. |
2881 // to handle it here. More complex cases are dealt with in the runtime. | 2883 if (FLAG_trace_ic) { |
2882 __ AssertNotSmi(t0); | 2884 __ Branch(&miss); |
2883 __ GetObjectType(t0, t1, t1); | |
2884 __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE)); | |
2885 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); | |
2886 __ Addu(t0, a2, Operand(t0)); | |
2887 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | |
2888 __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); | |
2889 // We have to update statistics for runtime profiling. | |
2890 const int with_types_offset = | |
2891 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | |
2892 __ lw(t0, FieldMemOperand(a2, with_types_offset)); | |
2893 __ Subu(t0, t0, Operand(Smi::FromInt(1))); | |
2894 __ sw(t0, FieldMemOperand(a2, with_types_offset)); | |
2895 const int generic_offset = | |
2896 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | |
2897 __ lw(t0, FieldMemOperand(a2, generic_offset)); | |
2898 __ Addu(t0, t0, Operand(Smi::FromInt(1))); | |
2899 __ sw(t0, FieldMemOperand(a2, generic_offset)); | |
2900 __ Branch(&slow_start); | |
2901 } | 2885 } |
2902 | 2886 |
2903 // We are here because tracing is on or we are going monomorphic. | 2887 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); |
| 2888 __ Branch(&uninitialized, eq, t0, Operand(at)); |
| 2889 |
| 2890 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
| 2891 // to handle it here. More complex cases are dealt with in the runtime. |
| 2892 __ AssertNotSmi(t0); |
| 2893 __ GetObjectType(t0, t1, t1); |
| 2894 __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE)); |
| 2895 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
| 2896 __ Addu(t0, a2, Operand(t0)); |
| 2897 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
| 2898 __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); |
| 2899 // We have to update statistics for runtime profiling. |
| 2900 __ lw(t0, FieldMemOperand(a2, with_types_offset)); |
| 2901 __ Subu(t0, t0, Operand(Smi::FromInt(1))); |
| 2902 __ sw(t0, FieldMemOperand(a2, with_types_offset)); |
| 2903 __ lw(t0, FieldMemOperand(a2, generic_offset)); |
| 2904 __ Addu(t0, t0, Operand(Smi::FromInt(1))); |
| 2905 __ Branch(USE_DELAY_SLOT, &slow_start); |
| 2906 __ sw(t0, FieldMemOperand(a2, generic_offset)); // In delay slot. |
| 2907 |
| 2908 __ bind(&uninitialized); |
| 2909 |
| 2910 // We are going monomorphic, provided we actually have a JSFunction. |
| 2911 __ JumpIfSmi(a1, &miss); |
| 2912 |
| 2913 // Goto miss case if we do not have a function. |
| 2914 __ GetObjectType(a1, t0, t0); |
| 2915 __ Branch(&miss, ne, t0, Operand(JS_FUNCTION_TYPE)); |
| 2916 |
| 2917 // Make sure the function is not the Array() function, which requires special |
| 2918 // behavior on MISS. |
| 2919 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t0); |
| 2920 __ Branch(&miss, eq, a1, Operand(t0)); |
| 2921 |
| 2922 // Update stats. |
| 2923 __ lw(t0, FieldMemOperand(a2, with_types_offset)); |
| 2924 __ Addu(t0, t0, Operand(Smi::FromInt(1))); |
| 2925 __ sw(t0, FieldMemOperand(a2, with_types_offset)); |
| 2926 |
| 2927 // Store the function. |
| 2928 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
| 2929 __ Addu(t0, a2, Operand(t0)); |
| 2930 __ Addu(t0, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 2931 __ sw(a1, MemOperand(t0, 0)); |
| 2932 |
| 2933 // Update the write barrier. |
| 2934 __ mov(t1, a1); |
| 2935 __ RecordWrite(a2, t0, t1, kRAHasNotBeenSaved, kDontSaveFPRegs, |
| 2936 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| 2937 __ Branch(&have_js_function); |
| 2938 |
| 2939 // We are here because tracing is on or we encountered a MISS case we can't |
| 2940 // handle here. |
2904 __ bind(&miss); | 2941 __ bind(&miss); |
2905 GenerateMiss(masm); | 2942 GenerateMiss(masm); |
2906 | 2943 |
2907 // the slow case | 2944 // the slow case |
2908 __ bind(&slow_start); | 2945 __ bind(&slow_start); |
2909 // Check that the function is really a JavaScript function. | 2946 // Check that the function is really a JavaScript function. |
2910 // r1: pushed function (to be verified) | 2947 // r1: pushed function (to be verified) |
2911 __ JumpIfSmi(a1, &non_function); | 2948 __ JumpIfSmi(a1, &non_function); |
2912 | 2949 |
2913 // Goto slow case if we do not have a function. | 2950 // Goto slow case if we do not have a function. |
(...skipping 2042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4956 MemOperand(fp, 6 * kPointerSize), | 4993 MemOperand(fp, 6 * kPointerSize), |
4957 NULL); | 4994 NULL); |
4958 } | 4995 } |
4959 | 4996 |
4960 | 4997 |
4961 #undef __ | 4998 #undef __ |
4962 | 4999 |
4963 } } // namespace v8::internal | 5000 } } // namespace v8::internal |
4964 | 5001 |
4965 #endif // V8_TARGET_ARCH_MIPS | 5002 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |