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

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

Issue 247373002: CallICStub with a "never patch" approach until customization. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE + code size multiplier. 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/arm/builtins-arm.cc ('k') | src/arm/debug-arm.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 2838 matching lines...) Expand 10 before | Expand all | Expand 10 after
2849 2849
2850 __ Push(r4, r2, r1); 2850 __ Push(r4, r2, r1);
2851 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs, 2851 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs,
2852 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 2852 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
2853 __ Pop(r4, r2, r1); 2853 __ Pop(r4, r2, r1);
2854 2854
2855 __ bind(&done); 2855 __ bind(&done);
2856 } 2856 }
2857 2857
2858 2858
2859 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
2860 // Do not transform the receiver for strict mode functions.
2861 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2862 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset));
2863 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
2864 kSmiTagSize)));
2865 __ b(ne, cont);
2866
2867 // Do not transform the receiver for native (Compilerhints already in r3).
2868 __ tst(r4, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
2869 __ b(ne, cont);
2870 }
2871
2872
2873 static void EmitSlowCase(MacroAssembler* masm,
2874 int argc,
2875 Label* non_function) {
2876 // Check for function proxy.
2877 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
2878 __ b(ne, non_function);
2879 __ push(r1); // put proxy as additional argument
2880 __ mov(r0, Operand(argc + 1, RelocInfo::NONE32));
2881 __ mov(r2, Operand::Zero());
2882 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
2883 {
2884 Handle<Code> adaptor =
2885 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
2886 __ Jump(adaptor, RelocInfo::CODE_TARGET);
2887 }
2888
2889 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
2890 // of the original receiver from the call site).
2891 __ bind(non_function);
2892 __ str(r1, MemOperand(sp, argc * kPointerSize));
2893 __ mov(r0, Operand(argc)); // Set up the number of arguments.
2894 __ mov(r2, Operand::Zero());
2895 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
2896 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
2897 RelocInfo::CODE_TARGET);
2898 }
2899
2900
2901 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
2902 // Wrap the receiver and patch it back onto the stack.
2903 { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
2904 __ Push(r1, r3);
2905 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
2906 __ pop(r1);
2907 }
2908 __ str(r0, MemOperand(sp, argc * kPointerSize));
2909 __ jmp(cont);
2910 }
2911
2912
2859 void CallFunctionStub::Generate(MacroAssembler* masm) { 2913 void CallFunctionStub::Generate(MacroAssembler* masm) {
2860 // r1 : the function to call 2914 // r1 : the function to call
2861 // r2 : feedback vector
2862 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
2863 // vector (Smi)
2864 Label slow, non_function, wrap, cont; 2915 Label slow, non_function, wrap, cont;
2865 2916
2866 if (NeedsChecks()) { 2917 if (NeedsChecks()) {
2867 // Check that the function is really a JavaScript function. 2918 // Check that the function is really a JavaScript function.
2868 // r1: pushed function (to be verified) 2919 // r1: pushed function (to be verified)
2869 __ JumpIfSmi(r1, &non_function); 2920 __ JumpIfSmi(r1, &non_function);
2870 2921
2871 // Goto slow case if we do not have a function. 2922 // Goto slow case if we do not have a function.
2872 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); 2923 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
2873 __ b(ne, &slow); 2924 __ b(ne, &slow);
2874
2875 if (RecordCallTarget()) {
2876 GenerateRecordCallTarget(masm);
2877 // Type information was updated. Because we may call Array, which
2878 // expects either undefined or an AllocationSite in ebx we need
2879 // to set ebx to undefined.
2880 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2881 }
2882 } 2925 }
2883 2926
2884 // Fast-case: Invoke the function now. 2927 // Fast-case: Invoke the function now.
2885 // r1: pushed function 2928 // r1: pushed function
2886 ParameterCount actual(argc_); 2929 int argc = argc_;
2930 ParameterCount actual(argc);
2887 2931
2888 if (CallAsMethod()) { 2932 if (CallAsMethod()) {
2889 if (NeedsChecks()) { 2933 if (NeedsChecks()) {
2890 // Do not transform the receiver for strict mode functions. 2934 EmitContinueIfStrictOrNative(masm, &cont);
2891 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2892 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset));
2893 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
2894 kSmiTagSize)));
2895 __ b(ne, &cont);
2896
2897 // Do not transform the receiver for native (Compilerhints already in r3).
2898 __ tst(r4, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
2899 __ b(ne, &cont);
2900 } 2935 }
2901 2936
2902 // Compute the receiver in sloppy mode. 2937 // Compute the receiver in sloppy mode.
2903 __ ldr(r3, MemOperand(sp, argc_ * kPointerSize)); 2938 __ ldr(r3, MemOperand(sp, argc * kPointerSize));
2904 2939
2905 if (NeedsChecks()) { 2940 if (NeedsChecks()) {
2906 __ JumpIfSmi(r3, &wrap); 2941 __ JumpIfSmi(r3, &wrap);
2907 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE); 2942 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
2908 __ b(lt, &wrap); 2943 __ b(lt, &wrap);
2909 } else { 2944 } else {
2910 __ jmp(&wrap); 2945 __ jmp(&wrap);
2911 } 2946 }
2912 2947
2913 __ bind(&cont); 2948 __ bind(&cont);
2914 } 2949 }
2950
2915 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); 2951 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
2916 2952
2917 if (NeedsChecks()) { 2953 if (NeedsChecks()) {
2918 // Slow-case: Non-function called. 2954 // Slow-case: Non-function called.
2919 __ bind(&slow); 2955 __ bind(&slow);
2920 if (RecordCallTarget()) { 2956 EmitSlowCase(masm, argc, &non_function);
2921 // If there is a call target cache, mark it megamorphic in the
2922 // non-function case. MegamorphicSentinel is an immortal immovable
2923 // object (megamorphic symbol) so no write barrier is needed.
2924 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(isolate()),
2925 isolate()->heap()->megamorphic_symbol());
2926 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
2927 __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
2928 __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize));
2929 }
2930 // Check for function proxy.
2931 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
2932 __ b(ne, &non_function);
2933 __ push(r1); // put proxy as additional argument
2934 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32));
2935 __ mov(r2, Operand::Zero());
2936 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
2937 {
2938 Handle<Code> adaptor =
2939 isolate()->builtins()->ArgumentsAdaptorTrampoline();
2940 __ Jump(adaptor, RelocInfo::CODE_TARGET);
2941 }
2942
2943 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
2944 // of the original receiver from the call site).
2945 __ bind(&non_function);
2946 __ str(r1, MemOperand(sp, argc_ * kPointerSize));
2947 __ mov(r0, Operand(argc_)); // Set up the number of arguments.
2948 __ mov(r2, Operand::Zero());
2949 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
2950 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
2951 RelocInfo::CODE_TARGET);
2952 } 2957 }
2953 2958
2954 if (CallAsMethod()) { 2959 if (CallAsMethod()) {
2955 __ bind(&wrap); 2960 __ bind(&wrap);
2956 // Wrap the receiver and patch it back onto the stack. 2961 EmitWrapCase(masm, argc, &cont);
2957 { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
2958 __ Push(r1, r3);
2959 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
2960 __ pop(r1);
2961 }
2962 __ str(r0, MemOperand(sp, argc_ * kPointerSize));
2963 __ jmp(&cont);
2964 } 2962 }
2965 } 2963 }
2966 2964
2967 2965
2968 void CallConstructStub::Generate(MacroAssembler* masm) { 2966 void CallConstructStub::Generate(MacroAssembler* masm) {
2969 // r0 : number of arguments 2967 // r0 : number of arguments
2970 // r1 : the function to call 2968 // r1 : the function to call
2971 // r2 : feedback vector 2969 // r2 : feedback vector
2972 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback 2970 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
2973 // vector (Smi) 2971 // vector (Smi)
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3022 __ bind(&non_function_call); 3020 __ bind(&non_function_call);
3023 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 3021 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
3024 __ bind(&do_call); 3022 __ bind(&do_call);
3025 // Set expected number of arguments to zero (not changing r0). 3023 // Set expected number of arguments to zero (not changing r0).
3026 __ mov(r2, Operand::Zero()); 3024 __ mov(r2, Operand::Zero());
3027 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3025 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3028 RelocInfo::CODE_TARGET); 3026 RelocInfo::CODE_TARGET);
3029 } 3027 }
3030 3028
3031 3029
3030 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
3031 __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3032 __ ldr(vector, FieldMemOperand(vector,
3033 JSFunction::kSharedFunctionInfoOffset));
3034 __ ldr(vector, FieldMemOperand(vector,
3035 SharedFunctionInfo::kFeedbackVectorOffset));
3036 }
3037
3038
3039 void CallICStub::Generate(MacroAssembler* masm) {
3040 // r1 - function
3041 // r3 - slot id (Smi)
3042 Label extra_checks_or_miss, slow_start;
3043 Label slow, non_function, wrap, cont;
3044 Label have_js_function;
3045 int argc = state_.arg_count();
3046 ParameterCount actual(argc);
3047
3048 EmitLoadTypeFeedbackVector(masm, r2);
3049
3050 // The checks. First, does r1 match the recorded monomorphic target?
3051 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3052 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
3053 __ cmp(r1, r4);
3054 __ b(ne, &extra_checks_or_miss);
3055
3056 __ bind(&have_js_function);
3057 if (state_.CallAsMethod()) {
3058 EmitContinueIfStrictOrNative(masm, &cont);
3059 // Compute the receiver in sloppy mode.
3060 __ ldr(r3, MemOperand(sp, argc * kPointerSize));
3061
3062 __ JumpIfSmi(r3, &wrap);
3063 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
3064 __ b(lt, &wrap);
3065
3066 __ bind(&cont);
3067 }
3068
3069 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
3070
3071 __ bind(&slow);
3072 EmitSlowCase(masm, argc, &non_function);
3073
3074 if (state_.CallAsMethod()) {
3075 __ bind(&wrap);
3076 EmitWrapCase(masm, argc, &cont);
3077 }
3078
3079 __ bind(&extra_checks_or_miss);
3080 Label miss;
3081
3082 __ CompareRoot(r4, Heap::kMegamorphicSymbolRootIndex);
3083 __ b(eq, &slow_start);
3084 __ CompareRoot(r4, Heap::kUninitializedSymbolRootIndex);
3085 __ b(eq, &miss);
3086
3087 if (!FLAG_trace_ic) {
3088 // We are going megamorphic, and we don't want to visit the runtime.
3089 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3090 __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
3091 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
3092 __ jmp(&slow_start);
3093 }
3094
3095 // We are here because tracing is on or we are going monomorphic.
3096 __ bind(&miss);
3097 GenerateMiss(masm);
3098
3099 // the slow case
3100 __ bind(&slow_start);
3101 // Check that the function is really a JavaScript function.
3102 // r1: pushed function (to be verified)
3103 __ JumpIfSmi(r1, &non_function);
3104
3105 // Goto slow case if we do not have a function.
3106 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
3107 __ b(ne, &slow);
3108 __ jmp(&have_js_function);
3109 }
3110
3111
3112 void CallICStub::GenerateMiss(MacroAssembler* masm) {
3113 // Get the receiver of the function from the stack; 1 ~ return address.
3114 __ ldr(r4, MemOperand(sp, (state_.arg_count() + 1) * kPointerSize));
3115
3116 {
3117 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
3118
3119 // Push the receiver and the function and feedback info.
3120 __ Push(r4, r1, r2, r3);
3121
3122 // Call the entry.
3123 ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
3124 masm->isolate());
3125 __ CallExternalReference(miss, 4);
3126
3127 // Move result to edi and exit the internal frame.
3128 __ mov(r1, r0);
3129 }
3130 }
3131
3132
3032 // StringCharCodeAtGenerator 3133 // StringCharCodeAtGenerator
3033 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 3134 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
3034 Label flat_string; 3135 Label flat_string;
3035 Label ascii_string; 3136 Label ascii_string;
3036 Label got_char_code; 3137 Label got_char_code;
3037 Label sliced_string; 3138 Label sliced_string;
3038 3139
3039 // If the receiver is a smi trigger the non-string case. 3140 // If the receiver is a smi trigger the non-string case.
3040 __ JumpIfSmi(object_, receiver_not_string_); 3141 __ JumpIfSmi(object_, receiver_not_string_);
3041 3142
(...skipping 2081 matching lines...) Expand 10 before | Expand all | Expand 10 after
5123 MemOperand(fp, 6 * kPointerSize), 5224 MemOperand(fp, 6 * kPointerSize),
5124 NULL); 5225 NULL);
5125 } 5226 }
5126 5227
5127 5228
5128 #undef __ 5229 #undef __
5129 5230
5130 } } // namespace v8::internal 5231 } } // namespace v8::internal
5131 5232
5132 #endif // V8_TARGET_ARCH_ARM 5233 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/debug-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698