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