OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
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 2998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3009 | 3009 |
3010 __ Unreachable(); | 3010 __ Unreachable(); |
3011 } | 3011 } |
3012 | 3012 |
3013 | 3013 |
3014 void CallICStub::Generate(MacroAssembler* masm) { | 3014 void CallICStub::Generate(MacroAssembler* masm) { |
3015 ASM_LOCATION("CallICStub"); | 3015 ASM_LOCATION("CallICStub"); |
3016 | 3016 |
3017 // x1 - function | 3017 // x1 - function |
3018 // x3 - slot id (Smi) | 3018 // x3 - slot id (Smi) |
| 3019 const int with_types_offset = |
| 3020 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 3021 const int generic_offset = |
| 3022 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
3019 Label extra_checks_or_miss, slow_start; | 3023 Label extra_checks_or_miss, slow_start; |
3020 Label slow, non_function, wrap, cont; | 3024 Label slow, non_function, wrap, cont; |
3021 Label have_js_function; | 3025 Label have_js_function; |
3022 int argc = arg_count(); | 3026 int argc = arg_count(); |
3023 ParameterCount actual(argc); | 3027 ParameterCount actual(argc); |
3024 | 3028 |
3025 Register function = x1; | 3029 Register function = x1; |
3026 Register feedback_vector = x2; | 3030 Register feedback_vector = x2; |
3027 Register index = x3; | 3031 Register index = x3; |
3028 Register type = x4; | 3032 Register type = x4; |
(...skipping 28 matching lines...) Expand all Loading... |
3057 | 3061 |
3058 __ bind(&slow); | 3062 __ bind(&slow); |
3059 EmitSlowCase(masm, argc, function, type, &non_function); | 3063 EmitSlowCase(masm, argc, function, type, &non_function); |
3060 | 3064 |
3061 if (CallAsMethod()) { | 3065 if (CallAsMethod()) { |
3062 __ bind(&wrap); | 3066 __ bind(&wrap); |
3063 EmitWrapCase(masm, argc, &cont); | 3067 EmitWrapCase(masm, argc, &cont); |
3064 } | 3068 } |
3065 | 3069 |
3066 __ bind(&extra_checks_or_miss); | 3070 __ bind(&extra_checks_or_miss); |
3067 Label miss; | 3071 Label uninitialized, miss; |
3068 | 3072 |
3069 __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &slow_start); | 3073 __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &slow_start); |
| 3074 |
| 3075 // The following cases attempt to handle MISS cases without going to the |
| 3076 // runtime. |
| 3077 if (FLAG_trace_ic) { |
| 3078 __ jmp(&miss); |
| 3079 } |
| 3080 |
3070 __ JumpIfRoot(x4, Heap::kuninitialized_symbolRootIndex, &miss); | 3081 __ JumpIfRoot(x4, Heap::kuninitialized_symbolRootIndex, &miss); |
3071 | 3082 |
3072 if (!FLAG_trace_ic) { | 3083 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
3073 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 3084 // to handle it here. More complex cases are dealt with in the runtime. |
3074 // to handle it here. More complex cases are dealt with in the runtime. | 3085 __ AssertNotSmi(x4); |
3075 __ AssertNotSmi(x4); | 3086 __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss); |
3076 __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss); | 3087 __ Add(x4, feedback_vector, |
3077 __ Add(x4, feedback_vector, | 3088 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
3078 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 3089 __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex); |
3079 __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex); | 3090 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
3080 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); | 3091 // We have to update statistics for runtime profiling. |
3081 // We have to update statistics for runtime profiling. | 3092 __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
3082 const int with_types_offset = | 3093 __ Subs(x4, x4, Operand(Smi::FromInt(1))); |
3083 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 3094 __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
3084 __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset)); | 3095 __ Ldr(x4, FieldMemOperand(feedback_vector, generic_offset)); |
3085 __ Subs(x4, x4, Operand(Smi::FromInt(1))); | 3096 __ Adds(x4, x4, Operand(Smi::FromInt(1))); |
3086 __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset)); | 3097 __ Str(x4, FieldMemOperand(feedback_vector, generic_offset)); |
3087 const int generic_offset = | 3098 __ B(&slow_start); |
3088 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | |
3089 __ Ldr(x4, FieldMemOperand(feedback_vector, generic_offset)); | |
3090 __ Adds(x4, x4, Operand(Smi::FromInt(1))); | |
3091 __ Str(x4, FieldMemOperand(feedback_vector, generic_offset)); | |
3092 __ B(&slow_start); | |
3093 } | |
3094 | 3099 |
3095 // We are here because tracing is on or we are going monomorphic. | 3100 __ bind(&uninitialized); |
| 3101 |
| 3102 // We are going monomorphic, provided we actually have a JSFunction. |
| 3103 __ JumpIfSmi(function, &miss); |
| 3104 |
| 3105 // Goto miss case if we do not have a function. |
| 3106 __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss); |
| 3107 |
| 3108 // Make sure the function is not the Array() function, which requires special |
| 3109 // behavior on MISS. |
| 3110 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, x5); |
| 3111 __ Cmp(function, x5); |
| 3112 __ B(eq, &miss); |
| 3113 |
| 3114 // Update stats. |
| 3115 __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
| 3116 __ Adds(x4, x4, Operand(Smi::FromInt(1))); |
| 3117 __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
| 3118 |
| 3119 // Store the function. |
| 3120 __ Add(x4, feedback_vector, |
| 3121 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 3122 __ Str(function, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
| 3123 |
| 3124 __ Add(x4, feedback_vector, |
| 3125 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 3126 __ Add(x4, x4, FixedArray::kHeaderSize - kHeapObjectTag); |
| 3127 __ Str(function, MemOperand(x4, 0)); |
| 3128 |
| 3129 // Update the write barrier. |
| 3130 __ Mov(x5, function); |
| 3131 __ RecordWrite(feedback_vector, x4, x5, kLRHasNotBeenSaved, kDontSaveFPRegs, |
| 3132 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| 3133 __ B(&have_js_function); |
| 3134 |
| 3135 // We are here because tracing is on or we encountered a MISS case we can't |
| 3136 // handle here. |
3096 __ bind(&miss); | 3137 __ bind(&miss); |
3097 GenerateMiss(masm); | 3138 GenerateMiss(masm); |
3098 | 3139 |
3099 // the slow case | 3140 // the slow case |
3100 __ bind(&slow_start); | 3141 __ bind(&slow_start); |
3101 | 3142 |
3102 // Check that the function is really a JavaScript function. | 3143 // Check that the function is really a JavaScript function. |
3103 __ JumpIfSmi(function, &non_function); | 3144 __ JumpIfSmi(function, &non_function); |
3104 | 3145 |
3105 // Goto slow case if we do not have a function. | 3146 // Goto slow case if we do not have a function. |
(...skipping 1995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5101 MemOperand(fp, 6 * kPointerSize), | 5142 MemOperand(fp, 6 * kPointerSize), |
5102 NULL); | 5143 NULL); |
5103 } | 5144 } |
5104 | 5145 |
5105 | 5146 |
5106 #undef __ | 5147 #undef __ |
5107 | 5148 |
5108 } } // namespace v8::internal | 5149 } } // namespace v8::internal |
5109 | 5150 |
5110 #endif // V8_TARGET_ARCH_ARM64 | 5151 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |