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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2885 CallAsMethod()); | 2885 CallAsMethod()); |
2886 | 2886 |
2887 // Unreachable. | 2887 // Unreachable. |
2888 __ stop("Unexpected code address"); | 2888 __ stop("Unexpected code address"); |
2889 } | 2889 } |
2890 | 2890 |
2891 | 2891 |
2892 void CallICStub::Generate(MacroAssembler* masm) { | 2892 void CallICStub::Generate(MacroAssembler* masm) { |
2893 // a1 - function | 2893 // a1 - function |
2894 // a3 - slot id (Smi) | 2894 // a3 - slot id (Smi) |
| 2895 const int with_types_offset = |
| 2896 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 2897 const int generic_offset = |
| 2898 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
2895 Label extra_checks_or_miss, slow_start; | 2899 Label extra_checks_or_miss, slow_start; |
2896 Label slow, non_function, wrap, cont; | 2900 Label slow, non_function, wrap, cont; |
2897 Label have_js_function; | 2901 Label have_js_function; |
2898 int argc = arg_count(); | 2902 int argc = arg_count(); |
2899 ParameterCount actual(argc); | 2903 ParameterCount actual(argc); |
2900 | 2904 |
2901 EmitLoadTypeFeedbackVector(masm, a2); | 2905 EmitLoadTypeFeedbackVector(masm, a2); |
2902 | 2906 |
2903 // The checks. First, does r1 match the recorded monomorphic target? | 2907 // The checks. First, does r1 match the recorded monomorphic target? |
2904 __ dsrl(a4, a3, 32 - kPointerSizeLog2); | 2908 __ dsrl(a4, a3, 32 - kPointerSizeLog2); |
(...skipping 18 matching lines...) Expand all Loading... |
2923 | 2927 |
2924 __ bind(&slow); | 2928 __ bind(&slow); |
2925 EmitSlowCase(masm, argc, &non_function); | 2929 EmitSlowCase(masm, argc, &non_function); |
2926 | 2930 |
2927 if (CallAsMethod()) { | 2931 if (CallAsMethod()) { |
2928 __ bind(&wrap); | 2932 __ bind(&wrap); |
2929 EmitWrapCase(masm, argc, &cont); | 2933 EmitWrapCase(masm, argc, &cont); |
2930 } | 2934 } |
2931 | 2935 |
2932 __ bind(&extra_checks_or_miss); | 2936 __ bind(&extra_checks_or_miss); |
2933 Label miss; | 2937 Label uninitialized, miss; |
2934 | 2938 |
2935 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 2939 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
2936 __ Branch(&slow_start, eq, a4, Operand(at)); | 2940 __ Branch(&slow_start, eq, a4, Operand(at)); |
2937 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); | |
2938 __ Branch(&miss, eq, a4, Operand(at)); | |
2939 | 2941 |
2940 if (!FLAG_trace_ic) { | 2942 // The following cases attempt to handle MISS cases without going to the |
2941 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 2943 // runtime. |
2942 // to handle it here. More complex cases are dealt with in the runtime. | 2944 if (FLAG_trace_ic) { |
2943 __ AssertNotSmi(a4); | 2945 __ Branch(&miss); |
2944 __ GetObjectType(a4, a5, a5); | |
2945 __ Branch(&miss, ne, a5, Operand(JS_FUNCTION_TYPE)); | |
2946 __ dsrl(a4, a3, 32 - kPointerSizeLog2); | |
2947 __ Daddu(a4, a2, Operand(a4)); | |
2948 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | |
2949 __ sd(at, FieldMemOperand(a4, FixedArray::kHeaderSize)); | |
2950 // We have to update statistics for runtime profiling. | |
2951 const int with_types_offset = | |
2952 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | |
2953 __ ld(a4, FieldMemOperand(a2, with_types_offset)); | |
2954 __ Dsubu(a4, a4, Operand(Smi::FromInt(1))); | |
2955 __ sd(a4, FieldMemOperand(a2, with_types_offset)); | |
2956 const int generic_offset = | |
2957 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | |
2958 __ ld(a4, FieldMemOperand(a2, generic_offset)); | |
2959 __ Daddu(a4, a4, Operand(Smi::FromInt(1))); | |
2960 __ Branch(USE_DELAY_SLOT, &slow_start); | |
2961 __ sd(a4, FieldMemOperand(a2, generic_offset)); // In delay slot. | |
2962 } | 2946 } |
2963 | 2947 |
2964 // We are here because tracing is on or we are going monomorphic. | 2948 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); |
| 2949 __ Branch(&uninitialized, eq, a4, Operand(at)); |
| 2950 |
| 2951 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
| 2952 // to handle it here. More complex cases are dealt with in the runtime. |
| 2953 __ AssertNotSmi(a4); |
| 2954 __ GetObjectType(a4, a5, a5); |
| 2955 __ Branch(&miss, ne, a5, Operand(JS_FUNCTION_TYPE)); |
| 2956 __ dsrl(a4, a3, 32 - kPointerSizeLog2); |
| 2957 __ Daddu(a4, a2, Operand(a4)); |
| 2958 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
| 2959 __ sd(at, FieldMemOperand(a4, FixedArray::kHeaderSize)); |
| 2960 // We have to update statistics for runtime profiling. |
| 2961 __ ld(a4, FieldMemOperand(a2, with_types_offset)); |
| 2962 __ Dsubu(a4, a4, Operand(Smi::FromInt(1))); |
| 2963 __ sd(a4, FieldMemOperand(a2, with_types_offset)); |
| 2964 __ ld(a4, FieldMemOperand(a2, generic_offset)); |
| 2965 __ Daddu(a4, a4, Operand(Smi::FromInt(1))); |
| 2966 __ Branch(USE_DELAY_SLOT, &slow_start); |
| 2967 __ sd(a4, FieldMemOperand(a2, generic_offset)); // In delay slot. |
| 2968 |
| 2969 __ bind(&uninitialized); |
| 2970 |
| 2971 // We are going monomorphic, provided we actually have a JSFunction. |
| 2972 __ JumpIfSmi(a1, &miss); |
| 2973 |
| 2974 // Goto miss case if we do not have a function. |
| 2975 __ GetObjectType(a1, a4, a4); |
| 2976 __ Branch(&miss, ne, a4, Operand(JS_FUNCTION_TYPE)); |
| 2977 |
| 2978 // Make sure the function is not the Array() function, which requires special |
| 2979 // behavior on MISS. |
| 2980 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); |
| 2981 __ Branch(&miss, eq, a1, Operand(a4)); |
| 2982 |
| 2983 // Update stats. |
| 2984 __ ld(a4, FieldMemOperand(a2, with_types_offset)); |
| 2985 __ Daddu(a4, a4, Operand(Smi::FromInt(1))); |
| 2986 __ sd(a4, FieldMemOperand(a2, with_types_offset)); |
| 2987 |
| 2988 // Store the function. |
| 2989 __ dsrl(a4, a3, 32 - kPointerSizeLog2); |
| 2990 __ Daddu(a4, a2, Operand(a4)); |
| 2991 __ Daddu(a4, a4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 2992 __ sd(a1, MemOperand(a4, 0)); |
| 2993 |
| 2994 // Update the write barrier. |
| 2995 __ mov(a5, a1); |
| 2996 __ RecordWrite(a2, a4, a5, kRAHasNotBeenSaved, kDontSaveFPRegs, |
| 2997 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| 2998 __ Branch(&have_js_function); |
| 2999 |
| 3000 // We are here because tracing is on or we encountered a MISS case we can't |
| 3001 // handle here. |
2965 __ bind(&miss); | 3002 __ bind(&miss); |
2966 GenerateMiss(masm); | 3003 GenerateMiss(masm); |
2967 | 3004 |
2968 // the slow case | 3005 // the slow case |
2969 __ bind(&slow_start); | 3006 __ bind(&slow_start); |
2970 // Check that the function is really a JavaScript function. | 3007 // Check that the function is really a JavaScript function. |
2971 // r1: pushed function (to be verified) | 3008 // r1: pushed function (to be verified) |
2972 __ JumpIfSmi(a1, &non_function); | 3009 __ JumpIfSmi(a1, &non_function); |
2973 | 3010 |
2974 // Goto slow case if we do not have a function. | 3011 // Goto slow case if we do not have a function. |
(...skipping 2007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4982 MemOperand(fp, 6 * kPointerSize), | 5019 MemOperand(fp, 6 * kPointerSize), |
4983 NULL); | 5020 NULL); |
4984 } | 5021 } |
4985 | 5022 |
4986 | 5023 |
4987 #undef __ | 5024 #undef __ |
4988 | 5025 |
4989 } } // namespace v8::internal | 5026 } } // namespace v8::internal |
4990 | 5027 |
4991 #endif // V8_TARGET_ARCH_MIPS64 | 5028 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |