Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 305493003: Reland "Customized support for feedback on calls to Array." and follow-up fixes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Bugfix and tests Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.cc ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_MIPS 7 #if V8_TARGET_ARCH_MIPS
8 8
9 #include "bootstrapper.h" 9 #include "bootstrapper.h"
10 #include "code-stubs.h" 10 #include "code-stubs.h"
(...skipping 3076 matching lines...) Expand 10 before | Expand all | Expand 10 after
3087 { FrameScope frame_scope(masm, StackFrame::INTERNAL); 3087 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
3088 __ Push(a1, a3); 3088 __ Push(a1, a3);
3089 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 3089 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
3090 __ pop(a1); 3090 __ pop(a1);
3091 } 3091 }
3092 __ Branch(USE_DELAY_SLOT, cont); 3092 __ Branch(USE_DELAY_SLOT, cont);
3093 __ sw(v0, MemOperand(sp, argc * kPointerSize)); 3093 __ sw(v0, MemOperand(sp, argc * kPointerSize));
3094 } 3094 }
3095 3095
3096 3096
3097 void CallFunctionStub::Generate(MacroAssembler* masm) { 3097 static void CallFunctionNoFeedback(MacroAssembler* masm,
3098 int argc, bool needs_checks,
3099 bool call_as_method) {
3098 // a1 : the function to call 3100 // a1 : the function to call
3099 Label slow, non_function, wrap, cont; 3101 Label slow, non_function, wrap, cont;
3100 3102
3101 if (NeedsChecks()) { 3103 if (needs_checks) {
3102 // Check that the function is really a JavaScript function. 3104 // Check that the function is really a JavaScript function.
3103 // a1: pushed function (to be verified) 3105 // a1: pushed function (to be verified)
3104 __ JumpIfSmi(a1, &non_function); 3106 __ JumpIfSmi(a1, &non_function);
3105 3107
3106 // Goto slow case if we do not have a function. 3108 // Goto slow case if we do not have a function.
3107 __ GetObjectType(a1, t0, t0); 3109 __ GetObjectType(a1, t0, t0);
3108 __ Branch(&slow, ne, t0, Operand(JS_FUNCTION_TYPE)); 3110 __ Branch(&slow, ne, t0, Operand(JS_FUNCTION_TYPE));
3109 } 3111 }
3110 3112
3111 // Fast-case: Invoke the function now. 3113 // Fast-case: Invoke the function now.
3112 // a1: pushed function 3114 // a1: pushed function
3113 int argc = argc_;
3114 ParameterCount actual(argc); 3115 ParameterCount actual(argc);
3115 3116
3116 if (CallAsMethod()) { 3117 if (call_as_method) {
3117 if (NeedsChecks()) { 3118 if (needs_checks) {
3118 EmitContinueIfStrictOrNative(masm, &cont); 3119 EmitContinueIfStrictOrNative(masm, &cont);
3119 } 3120 }
3120 3121
3121 // Compute the receiver in sloppy mode. 3122 // Compute the receiver in sloppy mode.
3122 __ lw(a3, MemOperand(sp, argc * kPointerSize)); 3123 __ lw(a3, MemOperand(sp, argc * kPointerSize));
3123 3124
3124 if (NeedsChecks()) { 3125 if (needs_checks) {
3125 __ JumpIfSmi(a3, &wrap); 3126 __ JumpIfSmi(a3, &wrap);
3126 __ GetObjectType(a3, t0, t0); 3127 __ GetObjectType(a3, t0, t0);
3127 __ Branch(&wrap, lt, t0, Operand(FIRST_SPEC_OBJECT_TYPE)); 3128 __ Branch(&wrap, lt, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
3128 } else { 3129 } else {
3129 __ jmp(&wrap); 3130 __ jmp(&wrap);
3130 } 3131 }
3131 3132
3132 __ bind(&cont); 3133 __ bind(&cont);
3133 } 3134 }
3134 3135
3135 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); 3136 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper());
3136 3137
3137 if (NeedsChecks()) { 3138 if (needs_checks) {
3138 // Slow-case: Non-function called. 3139 // Slow-case: Non-function called.
3139 __ bind(&slow); 3140 __ bind(&slow);
3140 EmitSlowCase(masm, argc, &non_function); 3141 EmitSlowCase(masm, argc, &non_function);
3141 } 3142 }
3142 3143
3143 if (CallAsMethod()) { 3144 if (call_as_method) {
3144 __ bind(&wrap); 3145 __ bind(&wrap);
3145 // Wrap the receiver and patch it back onto the stack. 3146 // Wrap the receiver and patch it back onto the stack.
3146 EmitWrapCase(masm, argc, &cont); 3147 EmitWrapCase(masm, argc, &cont);
3147 } 3148 }
3148 } 3149 }
3149 3150
3150 3151
3152 void CallFunctionStub::Generate(MacroAssembler* masm) {
3153 CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
3154 }
3155
3156
3151 void CallConstructStub::Generate(MacroAssembler* masm) { 3157 void CallConstructStub::Generate(MacroAssembler* masm) {
3152 // a0 : number of arguments 3158 // a0 : number of arguments
3153 // a1 : the function to call 3159 // a1 : the function to call
3154 // a2 : feedback vector 3160 // a2 : feedback vector
3155 // a3 : (only if a2 is not undefined) slot in feedback vector (Smi) 3161 // a3 : (only if a2 is not undefined) slot in feedback vector (Smi)
3156 Label slow, non_function_call; 3162 Label slow, non_function_call;
3157 3163
3158 // Check that the function is not a smi. 3164 // Check that the function is not a smi.
3159 __ JumpIfSmi(a1, &non_function_call); 3165 __ JumpIfSmi(a1, &non_function_call);
3160 // Check that the function is a JSFunction. 3166 // Check that the function is a JSFunction.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 __ bind(&slow); 3206 __ bind(&slow);
3201 __ Branch(&non_function_call, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE)); 3207 __ Branch(&non_function_call, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE));
3202 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 3208 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
3203 __ jmp(&do_call); 3209 __ jmp(&do_call);
3204 3210
3205 __ bind(&non_function_call); 3211 __ bind(&non_function_call);
3206 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 3212 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
3207 __ bind(&do_call); 3213 __ bind(&do_call);
3208 // Set expected number of arguments to zero (not changing r0). 3214 // Set expected number of arguments to zero (not changing r0).
3209 __ li(a2, Operand(0, RelocInfo::NONE32)); 3215 __ li(a2, Operand(0, RelocInfo::NONE32));
3210 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3216 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3211 RelocInfo::CODE_TARGET); 3217 RelocInfo::CODE_TARGET);
3212 } 3218 }
3213 3219
3214 3220
3215 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { 3221 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
3216 __ lw(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3222 __ lw(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3217 __ lw(vector, FieldMemOperand(vector, 3223 __ lw(vector, FieldMemOperand(vector,
3218 JSFunction::kSharedFunctionInfoOffset)); 3224 JSFunction::kSharedFunctionInfoOffset));
3219 __ lw(vector, FieldMemOperand(vector, 3225 __ lw(vector, FieldMemOperand(vector,
3220 SharedFunctionInfo::kFeedbackVectorOffset)); 3226 SharedFunctionInfo::kFeedbackVectorOffset));
3221 } 3227 }
3222 3228
3223 3229
3230 void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
3231 // a1 - function
3232 // a2 - feedback vector
3233 // a3 - slot id
3234 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, at);
3235 __ Branch(miss, ne, a1, Operand(at));
3236
3237 __ li(a0, Operand(arg_count()));
3238 __ sll(at, a3, kPointerSizeLog2 - kSmiTagSize);
3239 __ Addu(at, a2, Operand(at));
3240 __ lw(a2, FieldMemOperand(at, FixedArray::kHeaderSize));
3241 // Verify that a2 contains an AllocationSite
3242 __ AssertUndefinedOrAllocationSite(a2, at);
3243 ArrayConstructorStub stub(masm->isolate(), arg_count());
3244 __ TailCallStub(&stub);
3245 }
3246
3247
3248 void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
3249 // a1 - function
3250 // a2 - feedback vector
3251 // a3 - slot id
3252 Label miss;
3253
3254 if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
3255 Generate_MonomorphicArray(masm, &miss);
3256 } else {
3257 // So far there is only one customer for our custom feedback scheme.
3258 UNREACHABLE();
3259 }
3260
3261 __ bind(&miss);
3262 GenerateMiss(masm);
3263
3264 // The slow case, we need this no matter what to complete a call after a miss.
3265 CallFunctionNoFeedback(masm,
3266 arg_count(),
3267 true,
3268 CallAsMethod());
3269
3270 // Unreachable.
3271 __ stop("Unexpected code address");
3272 }
3273
3274
3224 void CallICStub::Generate(MacroAssembler* masm) { 3275 void CallICStub::Generate(MacroAssembler* masm) {
3225 // r1 - function 3276 // r1 - function
3226 // r3 - slot id (Smi) 3277 // r3 - slot id (Smi)
3227 Label extra_checks_or_miss, slow_start; 3278 Label extra_checks_or_miss, slow_start;
3228 Label slow, non_function, wrap, cont; 3279 Label slow, non_function, wrap, cont;
3229 Label have_js_function; 3280 Label have_js_function;
3230 int argc = state_.arg_count(); 3281 int argc = state_.arg_count();
3231 ParameterCount actual(argc); 3282 ParameterCount actual(argc);
3232 3283
3233 EmitLoadTypeFeedbackVector(masm, a2); 3284 EmitLoadTypeFeedbackVector(masm, a2);
3234 3285
3286 if (state_.stub_type() != CallIC::DEFAULT) {
3287 Generate_CustomFeedbackCall(masm);
3288 return;
3289 }
3290
3235 // The checks. First, does r1 match the recorded monomorphic target? 3291 // The checks. First, does r1 match the recorded monomorphic target?
3236 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); 3292 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
3237 __ Addu(t0, a2, Operand(t0)); 3293 __ Addu(t0, a2, Operand(t0));
3238 __ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize)); 3294 __ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize));
3239 __ Branch(&extra_checks_or_miss, ne, a1, Operand(t0)); 3295 __ Branch(&extra_checks_or_miss, ne, a1, Operand(t0));
3240 3296
3241 __ bind(&have_js_function); 3297 __ bind(&have_js_function);
3242 if (state_.CallAsMethod()) { 3298 if (state_.CallAsMethod()) {
3243 EmitContinueIfStrictOrNative(masm, &cont); 3299 EmitContinueIfStrictOrNative(masm, &cont);
3244 // Compute the receiver in sloppy mode. 3300 // Compute the receiver in sloppy mode.
(...skipping 2200 matching lines...) Expand 10 before | Expand all | Expand 10 after
5445 MemOperand(fp, 6 * kPointerSize), 5501 MemOperand(fp, 6 * kPointerSize),
5446 NULL); 5502 NULL);
5447 } 5503 }
5448 5504
5449 5505
5450 #undef __ 5506 #undef __
5451 5507
5452 } } // namespace v8::internal 5508 } } // namespace v8::internal
5453 5509
5454 #endif // V8_TARGET_ARCH_MIPS 5510 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ic.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698