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

Side by Side Diff: src/arm/code-stubs-arm.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, 6 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 | « no previous file | src/arm64/code-stubs-arm64.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_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 2916 matching lines...) Expand 10 before | Expand all | Expand 10 after
2927 { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); 2927 { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
2928 __ Push(r1, r3); 2928 __ Push(r1, r3);
2929 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 2929 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
2930 __ pop(r1); 2930 __ pop(r1);
2931 } 2931 }
2932 __ str(r0, MemOperand(sp, argc * kPointerSize)); 2932 __ str(r0, MemOperand(sp, argc * kPointerSize));
2933 __ jmp(cont); 2933 __ jmp(cont);
2934 } 2934 }
2935 2935
2936 2936
2937 void CallFunctionStub::Generate(MacroAssembler* masm) { 2937 static void CallFunctionNoFeedback(MacroAssembler* masm,
2938 int argc, bool needs_checks,
2939 bool call_as_method) {
2938 // r1 : the function to call 2940 // r1 : the function to call
2939 Label slow, non_function, wrap, cont; 2941 Label slow, non_function, wrap, cont;
2940 2942
2941 if (NeedsChecks()) { 2943 if (needs_checks) {
2942 // Check that the function is really a JavaScript function. 2944 // Check that the function is really a JavaScript function.
2943 // r1: pushed function (to be verified) 2945 // r1: pushed function (to be verified)
2944 __ JumpIfSmi(r1, &non_function); 2946 __ JumpIfSmi(r1, &non_function);
2945 2947
2946 // Goto slow case if we do not have a function. 2948 // Goto slow case if we do not have a function.
2947 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); 2949 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
2948 __ b(ne, &slow); 2950 __ b(ne, &slow);
2949 } 2951 }
2950 2952
2951 // Fast-case: Invoke the function now. 2953 // Fast-case: Invoke the function now.
2952 // r1: pushed function 2954 // r1: pushed function
2953 int argc = argc_;
2954 ParameterCount actual(argc); 2955 ParameterCount actual(argc);
2955 2956
2956 if (CallAsMethod()) { 2957 if (call_as_method) {
2957 if (NeedsChecks()) { 2958 if (needs_checks) {
2958 EmitContinueIfStrictOrNative(masm, &cont); 2959 EmitContinueIfStrictOrNative(masm, &cont);
2959 } 2960 }
2960 2961
2961 // Compute the receiver in sloppy mode. 2962 // Compute the receiver in sloppy mode.
2962 __ ldr(r3, MemOperand(sp, argc * kPointerSize)); 2963 __ ldr(r3, MemOperand(sp, argc * kPointerSize));
2963 2964
2964 if (NeedsChecks()) { 2965 if (needs_checks) {
2965 __ JumpIfSmi(r3, &wrap); 2966 __ JumpIfSmi(r3, &wrap);
2966 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE); 2967 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
2967 __ b(lt, &wrap); 2968 __ b(lt, &wrap);
2968 } else { 2969 } else {
2969 __ jmp(&wrap); 2970 __ jmp(&wrap);
2970 } 2971 }
2971 2972
2972 __ bind(&cont); 2973 __ bind(&cont);
2973 } 2974 }
2974 2975
2975 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); 2976 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
2976 2977
2977 if (NeedsChecks()) { 2978 if (needs_checks) {
2978 // Slow-case: Non-function called. 2979 // Slow-case: Non-function called.
2979 __ bind(&slow); 2980 __ bind(&slow);
2980 EmitSlowCase(masm, argc, &non_function); 2981 EmitSlowCase(masm, argc, &non_function);
2981 } 2982 }
2982 2983
2983 if (CallAsMethod()) { 2984 if (call_as_method) {
2984 __ bind(&wrap); 2985 __ bind(&wrap);
2985 EmitWrapCase(masm, argc, &cont); 2986 EmitWrapCase(masm, argc, &cont);
2986 } 2987 }
2987 } 2988 }
2988 2989
2989 2990
2991 void CallFunctionStub::Generate(MacroAssembler* masm) {
2992 CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
2993 }
2994
2995
2990 void CallConstructStub::Generate(MacroAssembler* masm) { 2996 void CallConstructStub::Generate(MacroAssembler* masm) {
2991 // r0 : number of arguments 2997 // r0 : number of arguments
2992 // r1 : the function to call 2998 // r1 : the function to call
2993 // r2 : feedback vector 2999 // r2 : feedback vector
2994 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback 3000 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
2995 // vector (Smi) 3001 // vector (Smi)
2996 Label slow, non_function_call; 3002 Label slow, non_function_call;
2997 3003
2998 // Check that the function is not a smi. 3004 // Check that the function is not a smi.
2999 __ JumpIfSmi(r1, &non_function_call); 3005 __ JumpIfSmi(r1, &non_function_call);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE)); 3045 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
3040 __ b(ne, &non_function_call); 3046 __ b(ne, &non_function_call);
3041 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 3047 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
3042 __ jmp(&do_call); 3048 __ jmp(&do_call);
3043 3049
3044 __ bind(&non_function_call); 3050 __ bind(&non_function_call);
3045 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 3051 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
3046 __ bind(&do_call); 3052 __ bind(&do_call);
3047 // Set expected number of arguments to zero (not changing r0). 3053 // Set expected number of arguments to zero (not changing r0).
3048 __ mov(r2, Operand::Zero()); 3054 __ mov(r2, Operand::Zero());
3049 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3055 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3050 RelocInfo::CODE_TARGET); 3056 RelocInfo::CODE_TARGET);
3051 } 3057 }
3052 3058
3053 3059
3054 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { 3060 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
3055 __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3061 __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3056 __ ldr(vector, FieldMemOperand(vector, 3062 __ ldr(vector, FieldMemOperand(vector,
3057 JSFunction::kSharedFunctionInfoOffset)); 3063 JSFunction::kSharedFunctionInfoOffset));
3058 __ ldr(vector, FieldMemOperand(vector, 3064 __ ldr(vector, FieldMemOperand(vector,
3059 SharedFunctionInfo::kFeedbackVectorOffset)); 3065 SharedFunctionInfo::kFeedbackVectorOffset));
3060 } 3066 }
3061 3067
3062 3068
3069 void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
3070 // r1 - function
3071 // r2 - feedback vector
3072 // r3 - slot id
3073 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4);
3074 __ cmp(r1, r4);
3075 __ b(ne, miss);
3076
3077 __ mov(r0, Operand(arg_count()));
3078 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3079 __ ldr(r2, FieldMemOperand(r4, FixedArray::kHeaderSize));
3080 // Verify that r2 contains an AllocationSite
3081 __ AssertUndefinedOrAllocationSite(r2, r4);
3082 ArrayConstructorStub stub(masm->isolate(), arg_count());
3083 __ 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
3100 __ bind(&miss);
3101 GenerateMiss(masm);
3102
3103 // The slow case, we need this no matter what to complete a call after a miss.
3104 CallFunctionNoFeedback(masm,
3105 arg_count(),
3106 true,
3107 CallAsMethod());
3108
3109 // Unreachable.
3110 __ stop("Unexpected code address");
3111 }
3112
3113
3063 void CallICStub::Generate(MacroAssembler* masm) { 3114 void CallICStub::Generate(MacroAssembler* masm) {
3064 // r1 - function 3115 // r1 - function
3065 // r3 - slot id (Smi) 3116 // r3 - slot id (Smi)
3066 Label extra_checks_or_miss, slow_start; 3117 Label extra_checks_or_miss, slow_start;
3067 Label slow, non_function, wrap, cont; 3118 Label slow, non_function, wrap, cont;
3068 Label have_js_function; 3119 Label have_js_function;
3069 int argc = state_.arg_count(); 3120 int argc = state_.arg_count();
3070 ParameterCount actual(argc); 3121 ParameterCount actual(argc);
3071 3122
3072 EmitLoadTypeFeedbackVector(masm, r2); 3123 EmitLoadTypeFeedbackVector(masm, r2);
3073 3124
3125 if (state_.stub_type() != CallIC::DEFAULT) {
3126 Generate_CustomFeedbackCall(masm);
3127 return;
3128 }
3129
3074 // The checks. First, does r1 match the recorded monomorphic target? 3130 // The checks. First, does r1 match the recorded monomorphic target?
3075 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); 3131 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3076 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); 3132 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
3077 __ cmp(r1, r4); 3133 __ cmp(r1, r4);
3078 __ b(ne, &extra_checks_or_miss); 3134 __ b(ne, &extra_checks_or_miss);
3079 3135
3080 __ bind(&have_js_function); 3136 __ bind(&have_js_function);
3081 if (state_.CallAsMethod()) { 3137 if (state_.CallAsMethod()) {
3082 EmitContinueIfStrictOrNative(masm, &cont); 3138 EmitContinueIfStrictOrNative(masm, &cont);
3083 // Compute the receiver in sloppy mode. 3139 // Compute the receiver in sloppy mode.
(...skipping 2159 matching lines...) Expand 10 before | Expand all | Expand 10 after
5243 MemOperand(fp, 6 * kPointerSize), 5299 MemOperand(fp, 6 * kPointerSize),
5244 NULL); 5300 NULL);
5245 } 5301 }
5246 5302
5247 5303
5248 #undef __ 5304 #undef __
5249 5305
5250 } } // namespace v8::internal 5306 } } // namespace v8::internal
5251 5307
5252 #endif // V8_TARGET_ARCH_ARM 5308 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/code-stubs-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698