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