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

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: Ports. 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2894 matching lines...) Expand 10 before | Expand all | Expand 10 after
2905 2905
2906 __ Push(r4, r2, r1); 2906 __ Push(r4, r2, r1);
2907 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs, 2907 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs,
2908 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 2908 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
2909 __ Pop(r4, r2, r1); 2909 __ Pop(r4, r2, r1);
2910 2910
2911 __ bind(&done); 2911 __ bind(&done);
2912 } 2912 }
2913 2913
2914 2914
2915 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
2916 // Do not transform the receiver for strict mode functions.
2917 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2918 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset));
2919 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
2920 kSmiTagSize)));
2921 __ b(ne, cont);
2922
2923 // Do not transform the receiver for native (Compilerhints already in r3).
2924 __ tst(r4, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
2925 __ b(ne, cont);
2926 }
2927
2928
2929 static void EmitSlowCase(MacroAssembler* masm,
2930 int argc,
2931 Label* non_function) {
2932 // Check for function proxy.
2933 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
2934 __ b(ne, non_function);
2935 __ push(r1); // put proxy as additional argument
2936 __ mov(r0, Operand(argc + 1, RelocInfo::NONE32));
2937 __ mov(r2, Operand::Zero());
2938 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
2939 {
2940 Handle<Code> adaptor =
2941 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
2942 __ Jump(adaptor, RelocInfo::CODE_TARGET);
2943 }
2944
2945 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
2946 // of the original receiver from the call site).
2947 __ bind(non_function);
2948 __ str(r1, MemOperand(sp, argc * kPointerSize));
2949 __ mov(r0, Operand(argc)); // Set up the number of arguments.
2950 __ mov(r2, Operand::Zero());
2951 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
2952 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
2953 RelocInfo::CODE_TARGET);
2954 }
2955
2956
2957 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
2958 // Wrap the receiver and patch it back onto the stack.
2959 { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
2960 __ Push(r1, r3);
2961 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
2962 __ pop(r1);
2963 }
2964 __ str(r0, MemOperand(sp, argc * kPointerSize));
2965 __ jmp(cont);
2966 }
2967
2968
2915 void CallFunctionStub::Generate(MacroAssembler* masm) { 2969 void CallFunctionStub::Generate(MacroAssembler* masm) {
2916 // r1 : the function to call 2970 // r1 : the function to call
2917 // r2 : feedback vector
2918 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
2919 // vector (Smi)
2920 Label slow, non_function, wrap, cont; 2971 Label slow, non_function, wrap, cont;
2921 2972
2922 if (NeedsChecks()) { 2973 if (NeedsChecks()) {
2923 // Check that the function is really a JavaScript function. 2974 // Check that the function is really a JavaScript function.
2924 // r1: pushed function (to be verified) 2975 // r1: pushed function (to be verified)
2925 __ JumpIfSmi(r1, &non_function); 2976 __ JumpIfSmi(r1, &non_function);
2926 2977
2927 // Goto slow case if we do not have a function. 2978 // Goto slow case if we do not have a function.
2928 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); 2979 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
2929 __ b(ne, &slow); 2980 __ b(ne, &slow);
2930
2931 if (RecordCallTarget()) {
2932 GenerateRecordCallTarget(masm);
2933 // Type information was updated. Because we may call Array, which
2934 // expects either undefined or an AllocationSite in ebx we need
2935 // to set ebx to undefined.
2936 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2937 }
2938 } 2981 }
2939 2982
2940 // Fast-case: Invoke the function now. 2983 // Fast-case: Invoke the function now.
2941 // r1: pushed function 2984 // r1: pushed function
2942 ParameterCount actual(argc_); 2985 int argc = argc_;
2986 ParameterCount actual(argc);
2943 2987
2944 if (CallAsMethod()) { 2988 if (CallAsMethod()) {
2945 if (NeedsChecks()) { 2989 if (NeedsChecks()) {
2946 // Do not transform the receiver for strict mode functions. 2990 EmitContinueIfStrictOrNative(masm, &cont);
2947 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2948 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset));
2949 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
2950 kSmiTagSize)));
2951 __ b(ne, &cont);
2952
2953 // Do not transform the receiver for native (Compilerhints already in r3).
2954 __ tst(r4, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
2955 __ b(ne, &cont);
2956 } 2991 }
2957 2992
2958 // Compute the receiver in sloppy mode. 2993 // Compute the receiver in sloppy mode.
2959 __ ldr(r3, MemOperand(sp, argc_ * kPointerSize)); 2994 __ ldr(r3, MemOperand(sp, argc * kPointerSize));
2960 2995
2961 if (NeedsChecks()) { 2996 if (NeedsChecks()) {
2962 __ JumpIfSmi(r3, &wrap); 2997 __ JumpIfSmi(r3, &wrap);
2963 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE); 2998 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
2964 __ b(lt, &wrap); 2999 __ b(lt, &wrap);
2965 } else { 3000 } else {
2966 __ jmp(&wrap); 3001 __ jmp(&wrap);
2967 } 3002 }
2968 3003
2969 __ bind(&cont); 3004 __ bind(&cont);
2970 } 3005 }
3006
2971 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); 3007 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
2972 3008
2973 if (NeedsChecks()) { 3009 if (NeedsChecks()) {
2974 // Slow-case: Non-function called. 3010 // Slow-case: Non-function called.
2975 __ bind(&slow); 3011 __ bind(&slow);
2976 if (RecordCallTarget()) { 3012 EmitSlowCase(masm, argc, &non_function);
2977 // If there is a call target cache, mark it megamorphic in the
2978 // non-function case. MegamorphicSentinel is an immortal immovable
2979 // object (megamorphic symbol) so no write barrier is needed.
2980 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
2981 masm->isolate()->heap()->megamorphic_symbol());
2982 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
2983 __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
2984 __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize));
2985 }
2986 // Check for function proxy.
2987 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
2988 __ b(ne, &non_function);
2989 __ push(r1); // put proxy as additional argument
2990 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32));
2991 __ mov(r2, Operand::Zero());
2992 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
2993 {
2994 Handle<Code> adaptor =
2995 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
2996 __ Jump(adaptor, RelocInfo::CODE_TARGET);
2997 }
2998
2999 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
3000 // of the original receiver from the call site).
3001 __ bind(&non_function);
3002 __ str(r1, MemOperand(sp, argc_ * kPointerSize));
3003 __ mov(r0, Operand(argc_)); // Set up the number of arguments.
3004 __ mov(r2, Operand::Zero());
3005 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
3006 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3007 RelocInfo::CODE_TARGET);
3008 } 3013 }
3009 3014
3010 if (CallAsMethod()) { 3015 if (CallAsMethod()) {
3011 __ bind(&wrap); 3016 __ bind(&wrap);
3012 // Wrap the receiver and patch it back onto the stack. 3017 EmitWrapCase(masm, argc, &cont);
3013 { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
3014 __ Push(r1, r3);
3015 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
3016 __ pop(r1);
3017 }
3018 __ str(r0, MemOperand(sp, argc_ * kPointerSize));
3019 __ jmp(&cont);
3020 } 3018 }
3021 } 3019 }
3022 3020
3023 3021
3024 void CallConstructStub::Generate(MacroAssembler* masm) { 3022 void CallConstructStub::Generate(MacroAssembler* masm) {
3025 // r0 : number of arguments 3023 // r0 : number of arguments
3026 // r1 : the function to call 3024 // r1 : the function to call
3027 // r2 : feedback vector 3025 // r2 : feedback vector
3028 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback 3026 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
3029 // vector (Smi) 3027 // vector (Smi)
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 __ bind(&non_function_call); 3076 __ bind(&non_function_call);
3079 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 3077 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
3080 __ bind(&do_call); 3078 __ bind(&do_call);
3081 // Set expected number of arguments to zero (not changing r0). 3079 // Set expected number of arguments to zero (not changing r0).
3082 __ mov(r2, Operand::Zero()); 3080 __ mov(r2, Operand::Zero());
3083 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3081 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3084 RelocInfo::CODE_TARGET); 3082 RelocInfo::CODE_TARGET);
3085 } 3083 }
3086 3084
3087 3085
3086 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
3087 __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3088 __ ldr(vector, FieldMemOperand(vector,
3089 JSFunction::kSharedFunctionInfoOffset));
3090 __ ldr(vector, FieldMemOperand(vector,
3091 SharedFunctionInfo::kFeedbackVectorOffset));
3092 }
3093
3094
3095 void CallICStub::Generate(MacroAssembler* masm) {
3096 // r1 - function
3097 // r3 - slot id (Smi)
3098 Label extra_checks_or_miss, slow_start;
3099 Label slow, non_function, wrap, cont;
3100 Label have_js_function;
3101 int argc = state_.arg_count();
3102 ParameterCount actual(argc);
3103
3104 EmitLoadTypeFeedbackVector(masm, r2);
3105
3106 // The checks. First, does r1 match the recorded monomorphic target?
3107 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3108 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
3109 __ cmp(r1, r4);
3110 __ b(ne, &extra_checks_or_miss);
3111
3112 __ bind(&have_js_function);
3113 if (state_.CallAsMethod()) {
3114 EmitContinueIfStrictOrNative(masm, &cont);
3115 // Compute the receiver in sloppy mode.
3116 __ ldr(r3, MemOperand(sp, argc * kPointerSize));
3117
3118 __ JumpIfSmi(r3, &wrap);
3119 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
3120 __ b(lt, &wrap);
3121
3122 __ bind(&cont);
3123 }
3124
3125 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
3126
3127 __ bind(&slow);
3128 EmitSlowCase(masm, argc, &non_function);
3129
3130 if (state_.CallAsMethod()) {
3131 __ bind(&wrap);
3132 EmitWrapCase(masm, argc, &cont);
3133 }
3134
3135 __ bind(&extra_checks_or_miss);
3136 Label miss;
3137
3138 __ CompareRoot(r4, Heap::kMegamorphicSymbolRootIndex);
3139 __ b(eq, &slow_start);
3140 __ CompareRoot(r4, Heap::kUninitializedSymbolRootIndex);
3141 __ b(eq, &miss);
3142
3143 if (!FLAG_trace_ic) {
3144 // We are going megamorphic, and we don't want to visit the runtime.
3145 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3146 __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
3147 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
3148 __ jmp(&slow_start);
3149 }
3150
3151 // We are here because tracing is on or we are going monomorphic.
3152 __ bind(&miss);
3153 GenerateMiss(masm);
3154
3155 // the slow case
3156 __ bind(&slow_start);
3157 // Check that the function is really a JavaScript function.
3158 // r1: pushed function (to be verified)
3159 __ JumpIfSmi(r1, &non_function);
3160
3161 // Goto slow case if we do not have a function.
3162 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
3163 __ b(ne, &slow);
3164 __ jmp(&have_js_function);
3165 }
3166
3167
3168 void CallICStub::GenerateMiss(MacroAssembler* masm) {
3169 // Get the receiver of the function from the stack; 1 ~ return address.
3170 __ ldr(r4, MemOperand(sp, (state_.arg_count() + 1) * kPointerSize));
3171
3172 {
3173 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
3174
3175 // Push the receiver and the function and feedback info.
3176 __ Push(r4, r1, r2, r3);
3177
3178 // Call the entry.
3179 ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
3180 masm->isolate());
3181 __ CallExternalReference(miss, 4);
3182
3183 // Move result to edi and exit the internal frame.
3184 __ mov(r1, r0);
3185 }
3186 }
3187
3188
3088 // StringCharCodeAtGenerator 3189 // StringCharCodeAtGenerator
3089 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 3190 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
3090 Label flat_string; 3191 Label flat_string;
3091 Label ascii_string; 3192 Label ascii_string;
3092 Label got_char_code; 3193 Label got_char_code;
3093 Label sliced_string; 3194 Label sliced_string;
3094 3195
3095 // If the receiver is a smi trigger the non-string case. 3196 // If the receiver is a smi trigger the non-string case.
3096 __ JumpIfSmi(object_, receiver_not_string_); 3197 __ JumpIfSmi(object_, receiver_not_string_);
3097 3198
(...skipping 2092 matching lines...) Expand 10 before | Expand all | Expand 10 after
5190 MemOperand(fp, 6 * kPointerSize), 5291 MemOperand(fp, 6 * kPointerSize),
5191 NULL); 5292 NULL);
5192 } 5293 }
5193 5294
5194 5295
5195 #undef __ 5296 #undef __
5196 5297
5197 } } // namespace v8::internal 5298 } } // namespace v8::internal
5198 5299
5199 #endif // V8_TARGET_ARCH_ARM 5300 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/debug-arm.cc » ('j') | src/ia32/code-stubs-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698