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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
8 | 8 |
9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
10 #include "code-stubs.h" | 10 #include "code-stubs.h" |
(...skipping 3048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3059 | 3059 |
3060 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { | 3060 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { |
3061 __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 3061 __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
3062 __ ldr(vector, FieldMemOperand(vector, | 3062 __ ldr(vector, FieldMemOperand(vector, |
3063 JSFunction::kSharedFunctionInfoOffset)); | 3063 JSFunction::kSharedFunctionInfoOffset)); |
3064 __ ldr(vector, FieldMemOperand(vector, | 3064 __ ldr(vector, FieldMemOperand(vector, |
3065 SharedFunctionInfo::kFeedbackVectorOffset)); | 3065 SharedFunctionInfo::kFeedbackVectorOffset)); |
3066 } | 3066 } |
3067 | 3067 |
3068 | 3068 |
3069 void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) { | 3069 void CallIC_ArrayStub::Generate(MacroAssembler* masm) { |
3070 // r1 - function | 3070 // r1 - function |
3071 // r2 - feedback vector | |
3072 // r3 - slot id | 3071 // r3 - slot id |
| 3072 Label miss; |
| 3073 int argc = state_.arg_count(); |
| 3074 ParameterCount actual(argc); |
| 3075 |
| 3076 EmitLoadTypeFeedbackVector(masm, r2); |
| 3077 |
3073 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | 3078 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); |
3074 __ cmp(r1, r4); | 3079 __ cmp(r1, r4); |
3075 __ b(ne, miss); | 3080 __ b(ne, &miss); |
3076 | 3081 |
3077 __ mov(r0, Operand(arg_count())); | 3082 __ mov(r0, Operand(arg_count())); |
3078 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 3083 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
3079 __ ldr(r2, FieldMemOperand(r4, FixedArray::kHeaderSize)); | 3084 __ ldr(r2, FieldMemOperand(r4, FixedArray::kHeaderSize)); |
3080 // Verify that r2 contains an AllocationSite | 3085 // Verify that r2 contains an AllocationSite |
3081 __ AssertUndefinedOrAllocationSite(r2, r4); | 3086 __ AssertUndefinedOrAllocationSite(r2, r4); |
3082 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 3087 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
3083 __ TailCallStub(&stub); | 3088 __ TailCallStub(&stub); |
3084 } | |
3085 | |
3086 | |
3087 void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) { | |
3088 // r1 - function | |
3089 // r2 - feedback vector | |
3090 // r3 - slot id | |
3091 Label miss; | |
3092 | |
3093 if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) { | |
3094 Generate_MonomorphicArray(masm, &miss); | |
3095 } else { | |
3096 // So far there is only one customer for our custom feedback scheme. | |
3097 UNREACHABLE(); | |
3098 } | |
3099 | 3089 |
3100 __ bind(&miss); | 3090 __ bind(&miss); |
3101 GenerateMiss(masm); | 3091 GenerateMiss(masm, IC::kCallIC_Customization_Miss); |
3102 | 3092 |
3103 // The slow case, we need this no matter what to complete a call after a miss. | 3093 // The slow case, we need this no matter what to complete a call after a miss. |
3104 CallFunctionNoFeedback(masm, | 3094 CallFunctionNoFeedback(masm, |
3105 arg_count(), | 3095 arg_count(), |
3106 true, | 3096 true, |
3107 CallAsMethod()); | 3097 CallAsMethod()); |
3108 | 3098 |
3109 // Unreachable. | 3099 // Unreachable. |
3110 __ stop("Unexpected code address"); | 3100 __ stop("Unexpected code address"); |
3111 } | 3101 } |
3112 | 3102 |
3113 | 3103 |
3114 void CallICStub::Generate(MacroAssembler* masm) { | 3104 void CallICStub::Generate(MacroAssembler* masm) { |
3115 // r1 - function | 3105 // r1 - function |
3116 // r3 - slot id (Smi) | 3106 // r3 - slot id (Smi) |
3117 Label extra_checks_or_miss, slow_start; | 3107 Label extra_checks_or_miss, slow_start; |
3118 Label slow, non_function, wrap, cont; | 3108 Label slow, non_function, wrap, cont; |
3119 Label have_js_function; | 3109 Label have_js_function; |
3120 int argc = state_.arg_count(); | 3110 int argc = state_.arg_count(); |
3121 ParameterCount actual(argc); | 3111 ParameterCount actual(argc); |
3122 | 3112 |
3123 EmitLoadTypeFeedbackVector(masm, r2); | 3113 EmitLoadTypeFeedbackVector(masm, r2); |
3124 | 3114 |
3125 if (state_.stub_type() != CallIC::DEFAULT) { | |
3126 Generate_CustomFeedbackCall(masm); | |
3127 return; | |
3128 } | |
3129 | |
3130 // The checks. First, does r1 match the recorded monomorphic target? | 3115 // The checks. First, does r1 match the recorded monomorphic target? |
3131 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 3116 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
3132 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); | 3117 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); |
3133 __ cmp(r1, r4); | 3118 __ cmp(r1, r4); |
3134 __ b(ne, &extra_checks_or_miss); | 3119 __ b(ne, &extra_checks_or_miss); |
3135 | 3120 |
3136 __ bind(&have_js_function); | 3121 __ bind(&have_js_function); |
3137 if (state_.CallAsMethod()) { | 3122 if (state_.CallAsMethod()) { |
3138 EmitContinueIfStrictOrNative(masm, &cont); | 3123 EmitContinueIfStrictOrNative(masm, &cont); |
3139 // Compute the receiver in sloppy mode. | 3124 // Compute the receiver in sloppy mode. |
(...skipping 27 matching lines...) Expand all Loading... |
3167 if (!FLAG_trace_ic) { | 3152 if (!FLAG_trace_ic) { |
3168 // We are going megamorphic, and we don't want to visit the runtime. | 3153 // We are going megamorphic, and we don't want to visit the runtime. |
3169 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 3154 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
3170 __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex); | 3155 __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex); |
3171 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize)); | 3156 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize)); |
3172 __ jmp(&slow_start); | 3157 __ jmp(&slow_start); |
3173 } | 3158 } |
3174 | 3159 |
3175 // We are here because tracing is on or we are going monomorphic. | 3160 // We are here because tracing is on or we are going monomorphic. |
3176 __ bind(&miss); | 3161 __ bind(&miss); |
3177 GenerateMiss(masm); | 3162 GenerateMiss(masm, IC::kCallIC_Miss); |
3178 | 3163 |
3179 // the slow case | 3164 // the slow case |
3180 __ bind(&slow_start); | 3165 __ bind(&slow_start); |
3181 // Check that the function is really a JavaScript function. | 3166 // Check that the function is really a JavaScript function. |
3182 // r1: pushed function (to be verified) | 3167 // r1: pushed function (to be verified) |
3183 __ JumpIfSmi(r1, &non_function); | 3168 __ JumpIfSmi(r1, &non_function); |
3184 | 3169 |
3185 // Goto slow case if we do not have a function. | 3170 // Goto slow case if we do not have a function. |
3186 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); | 3171 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); |
3187 __ b(ne, &slow); | 3172 __ b(ne, &slow); |
3188 __ jmp(&have_js_function); | 3173 __ jmp(&have_js_function); |
3189 } | 3174 } |
3190 | 3175 |
3191 | 3176 |
3192 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 3177 void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) { |
3193 // Get the receiver of the function from the stack; 1 ~ return address. | 3178 // Get the receiver of the function from the stack; 1 ~ return address. |
3194 __ ldr(r4, MemOperand(sp, (state_.arg_count() + 1) * kPointerSize)); | 3179 __ ldr(r4, MemOperand(sp, (state_.arg_count() + 1) * kPointerSize)); |
3195 | 3180 |
3196 { | 3181 { |
3197 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 3182 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
3198 | 3183 |
3199 // Push the receiver and the function and feedback info. | 3184 // Push the receiver and the function and feedback info. |
3200 __ Push(r4, r1, r2, r3); | 3185 __ Push(r4, r1, r2, r3); |
3201 | 3186 |
3202 // Call the entry. | 3187 // Call the entry. |
3203 ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss), | 3188 ExternalReference miss = ExternalReference(IC_Utility(id), |
3204 masm->isolate()); | 3189 masm->isolate()); |
3205 __ CallExternalReference(miss, 4); | 3190 __ CallExternalReference(miss, 4); |
3206 | 3191 |
3207 // Move result to edi and exit the internal frame. | 3192 // Move result to edi and exit the internal frame. |
3208 __ mov(r1, r0); | 3193 __ mov(r1, r0); |
3209 } | 3194 } |
3210 } | 3195 } |
3211 | 3196 |
3212 | 3197 |
3213 // StringCharCodeAtGenerator | 3198 // StringCharCodeAtGenerator |
(...skipping 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5299 MemOperand(fp, 6 * kPointerSize), | 5284 MemOperand(fp, 6 * kPointerSize), |
5300 NULL); | 5285 NULL); |
5301 } | 5286 } |
5302 | 5287 |
5303 | 5288 |
5304 #undef __ | 5289 #undef __ |
5305 | 5290 |
5306 } } // namespace v8::internal | 5291 } } // namespace v8::internal |
5307 | 5292 |
5308 #endif // V8_TARGET_ARCH_ARM | 5293 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |