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

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

Issue 1407373007: Remove CallFunctionStub, always call through the Call builtin (also from CallIC) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/code-factory.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/handler-compiler.h" 10 #include "src/ic/handler-compiler.h"
(...skipping 2729 matching lines...) Expand 10 before | Expand all | Expand 10 after
2740 __ B(&done); 2740 __ B(&done);
2741 2741
2742 __ Bind(&not_array_function); 2742 __ Bind(&not_array_function);
2743 CreateWeakCellStub weak_cell_stub(masm->isolate()); 2743 CreateWeakCellStub weak_cell_stub(masm->isolate());
2744 CallStubInRecordCallTarget(masm, &weak_cell_stub, argc, function, 2744 CallStubInRecordCallTarget(masm, &weak_cell_stub, argc, function,
2745 feedback_vector, index, orig_construct, is_super); 2745 feedback_vector, index, orig_construct, is_super);
2746 __ Bind(&done); 2746 __ Bind(&done);
2747 } 2747 }
2748 2748
2749 2749
2750 static void LoadCompilerHints(MacroAssembler* masm) {
2751 // ----------- S t a t e -------------
2752 // -- x1 : the function to call
2753 // -----------------------------------
2754 // Do not transform the receiver for strict mode functions.
2755 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
2756 __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset));
2757 }
2758
2759
2760 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
2761 // ----------- S t a t e -------------
2762 // -- a1 : the function to call
2763 // -- x3 : the shared function info
2764 // -- w4 : the compiler info hints from the shared function info
2765 // -----------------------------------
2766 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont);
2767
2768 // Do not transform the receiver for native (Compilerhints already in x3).
2769 __ Tbnz(w4, SharedFunctionInfo::kNative, cont);
2770 }
2771
2772
2773 static void EmitSlowCase(MacroAssembler* masm, int argc) {
2774 __ Mov(x0, argc);
2775 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2776 }
2777
2778
2779 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
2780 // Wrap the receiver and patch it back onto the stack.
2781 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
2782 __ Push(x1);
2783 __ Mov(x0, x3);
2784 ToObjectStub stub(masm->isolate());
2785 __ CallStub(&stub);
2786 __ Pop(x1);
2787 }
2788 __ Poke(x0, argc * kPointerSize);
2789 __ B(cont);
2790 }
2791
2792
2793 static void EmitClassConstructorCallCheck(MacroAssembler* masm) {
2794 // ----------- S t a t e -------------
2795 // -- x1 : the function to call
2796 // -- x3 : the shared function info
2797 // -- w4 : the shared function's compiler hints
2798 // -----------------------------------
2799 // ClassConstructor Check: ES6 section 9.2.1 [[Call]]
2800 Label non_class_constructor;
2801 __ TestAndBranchIfAllClear(
2802 w4, (1 << SharedFunctionInfo::kIsDefaultConstructor) |
2803 (1 << SharedFunctionInfo::kIsSubclassConstructor) |
2804 (1 << SharedFunctionInfo::kIsBaseConstructor),
2805 &non_class_constructor);
2806 // If we call a classConstructor Function throw a TypeError
2807 // indirectly via the CallFunction builtin.
2808 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
2809 __ bind(&non_class_constructor);
2810 }
2811
2812
2813 static void CallFunctionNoFeedback(MacroAssembler* masm,
2814 int argc, bool needs_checks,
2815 bool call_as_method) {
2816 // x1 function the function to call
2817 Register function = x1;
2818 Register type = x4;
2819 Label slow, wrap, cont;
2820
2821 // TODO(jbramley): This function has a lot of unnamed registers. Name them,
2822 // and tidy things up a bit.
2823
2824 if (needs_checks) {
2825 // Check that the function is really a JavaScript function.
2826 __ JumpIfSmi(function, &slow);
2827
2828 // Goto slow case if we do not have a function.
2829 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow);
2830 }
2831
2832 LoadCompilerHints(masm);
2833 EmitClassConstructorCallCheck(masm);
2834
2835 // Fast-case: Invoke the function now.
2836 // x1 function pushed function
2837 ParameterCount actual(argc);
2838
2839 if (call_as_method) {
2840 if (needs_checks) {
2841 EmitContinueIfStrictOrNative(masm, &cont);
2842 }
2843
2844 // Compute the receiver in sloppy mode.
2845 __ Peek(x3, argc * kPointerSize);
2846
2847 if (needs_checks) {
2848 __ JumpIfSmi(x3, &wrap);
2849 __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt);
2850 } else {
2851 __ B(&wrap);
2852 }
2853
2854 __ Bind(&cont);
2855 }
2856
2857 __ InvokeFunction(function,
2858 actual,
2859 JUMP_FUNCTION,
2860 NullCallWrapper());
2861 if (needs_checks) {
2862 // Slow-case: Non-function called.
2863 __ Bind(&slow);
2864 EmitSlowCase(masm, argc);
2865 }
2866
2867 if (call_as_method) {
2868 __ Bind(&wrap);
2869 EmitWrapCase(masm, argc, &cont);
2870 }
2871 }
2872
2873
2874 void CallFunctionStub::Generate(MacroAssembler* masm) {
2875 ASM_LOCATION("CallFunctionStub::Generate");
2876 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod());
2877 }
2878
2879
2880 void CallConstructStub::Generate(MacroAssembler* masm) { 2750 void CallConstructStub::Generate(MacroAssembler* masm) {
2881 ASM_LOCATION("CallConstructStub::Generate"); 2751 ASM_LOCATION("CallConstructStub::Generate");
2882 // x0 : number of arguments 2752 // x0 : number of arguments
2883 // x1 : the function to call 2753 // x1 : the function to call
2884 // x2 : feedback vector 2754 // x2 : feedback vector
2885 // x3 : slot in feedback vector (Smi, for RecordCallTarget) 2755 // x3 : slot in feedback vector (Smi, for RecordCallTarget)
2886 // x4 : original constructor (for IsSuperConstructorCall) 2756 // x4 : original constructor (for IsSuperConstructorCall)
2887 Register function = x1; 2757 Register function = x1;
2888 2758
2889 Label non_function; 2759 Label non_function;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2969 void CallICStub::Generate(MacroAssembler* masm) { 2839 void CallICStub::Generate(MacroAssembler* masm) {
2970 ASM_LOCATION("CallICStub"); 2840 ASM_LOCATION("CallICStub");
2971 2841
2972 // x1 - function 2842 // x1 - function
2973 // x3 - slot id (Smi) 2843 // x3 - slot id (Smi)
2974 // x2 - vector 2844 // x2 - vector
2975 const int with_types_offset = 2845 const int with_types_offset =
2976 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); 2846 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
2977 const int generic_offset = 2847 const int generic_offset =
2978 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); 2848 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
2979 Label extra_checks_or_miss, slow_start; 2849 Label extra_checks_or_miss, call;
2980 Label slow, wrap, cont;
2981 Label have_js_function;
2982 int argc = arg_count(); 2850 int argc = arg_count();
2983 ParameterCount actual(argc); 2851 ParameterCount actual(argc);
2984 2852
2985 Register function = x1; 2853 Register function = x1;
2986 Register feedback_vector = x2; 2854 Register feedback_vector = x2;
2987 Register index = x3; 2855 Register index = x3;
2988 Register type = x4; 2856 Register type = x4;
2989 2857
2990 // The checks. First, does x1 match the recorded monomorphic target? 2858 // The checks. First, does x1 match the recorded monomorphic target?
2991 __ Add(x4, feedback_vector, 2859 __ Add(x4, feedback_vector,
(...skipping 24 matching lines...) Expand all
3016 2884
3017 // Increment the call count for monomorphic function calls. 2885 // Increment the call count for monomorphic function calls.
3018 __ Add(feedback_vector, feedback_vector, 2886 __ Add(feedback_vector, feedback_vector,
3019 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 2887 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
3020 __ Add(feedback_vector, feedback_vector, 2888 __ Add(feedback_vector, feedback_vector,
3021 Operand(FixedArray::kHeaderSize + kPointerSize)); 2889 Operand(FixedArray::kHeaderSize + kPointerSize));
3022 __ Ldr(index, FieldMemOperand(feedback_vector, 0)); 2890 __ Ldr(index, FieldMemOperand(feedback_vector, 0));
3023 __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); 2891 __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement)));
3024 __ Str(index, FieldMemOperand(feedback_vector, 0)); 2892 __ Str(index, FieldMemOperand(feedback_vector, 0));
3025 2893
3026 __ bind(&have_js_function); 2894 __ bind(&call);
3027 2895 __ Mov(x0, argc);
3028 LoadCompilerHints(masm); 2896 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3029 EmitClassConstructorCallCheck(masm);
3030
3031 if (CallAsMethod()) {
3032 EmitContinueIfStrictOrNative(masm, &cont);
3033
3034 // Compute the receiver in sloppy mode.
3035 __ Peek(x3, argc * kPointerSize);
3036
3037 __ JumpIfSmi(x3, &wrap);
3038 __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt);
3039
3040 __ Bind(&cont);
3041 }
3042
3043 __ InvokeFunction(function,
3044 actual,
3045 JUMP_FUNCTION,
3046 NullCallWrapper());
3047
3048 __ bind(&slow);
3049 EmitSlowCase(masm, argc);
3050
3051 if (CallAsMethod()) {
3052 __ bind(&wrap);
3053 EmitWrapCase(masm, argc, &cont);
3054 }
3055 2897
3056 __ bind(&extra_checks_or_miss); 2898 __ bind(&extra_checks_or_miss);
3057 Label uninitialized, miss, not_allocation_site; 2899 Label uninitialized, miss, not_allocation_site;
3058 2900
3059 __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &slow_start); 2901 __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &call);
3060 2902
3061 __ Ldr(x5, FieldMemOperand(x4, HeapObject::kMapOffset)); 2903 __ Ldr(x5, FieldMemOperand(x4, HeapObject::kMapOffset));
3062 __ JumpIfNotRoot(x5, Heap::kAllocationSiteMapRootIndex, &not_allocation_site); 2904 __ JumpIfNotRoot(x5, Heap::kAllocationSiteMapRootIndex, &not_allocation_site);
3063 2905
3064 HandleArrayCase(masm, &miss); 2906 HandleArrayCase(masm, &miss);
3065 2907
3066 __ bind(&not_allocation_site); 2908 __ bind(&not_allocation_site);
3067 2909
3068 // The following cases attempt to handle MISS cases without going to the 2910 // The following cases attempt to handle MISS cases without going to the
3069 // runtime. 2911 // runtime.
(...skipping 11 matching lines...) Expand all
3081 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 2923 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
3082 __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex); 2924 __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex);
3083 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); 2925 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize));
3084 // We have to update statistics for runtime profiling. 2926 // We have to update statistics for runtime profiling.
3085 __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset)); 2927 __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset));
3086 __ Subs(x4, x4, Operand(Smi::FromInt(1))); 2928 __ Subs(x4, x4, Operand(Smi::FromInt(1)));
3087 __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset)); 2929 __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset));
3088 __ Ldr(x4, FieldMemOperand(feedback_vector, generic_offset)); 2930 __ Ldr(x4, FieldMemOperand(feedback_vector, generic_offset));
3089 __ Adds(x4, x4, Operand(Smi::FromInt(1))); 2931 __ Adds(x4, x4, Operand(Smi::FromInt(1)));
3090 __ Str(x4, FieldMemOperand(feedback_vector, generic_offset)); 2932 __ Str(x4, FieldMemOperand(feedback_vector, generic_offset));
3091 __ B(&slow_start); 2933 __ B(&call);
3092 2934
3093 __ bind(&uninitialized); 2935 __ bind(&uninitialized);
3094 2936
3095 // We are going monomorphic, provided we actually have a JSFunction. 2937 // We are going monomorphic, provided we actually have a JSFunction.
3096 __ JumpIfSmi(function, &miss); 2938 __ JumpIfSmi(function, &miss);
3097 2939
3098 // Goto miss case if we do not have a function. 2940 // Goto miss case if we do not have a function.
3099 __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss); 2941 __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss);
3100 2942
3101 // Make sure the function is not the Array() function, which requires special 2943 // Make sure the function is not the Array() function, which requires special
(...skipping 18 matching lines...) Expand all
3120 // x3 - slot 2962 // x3 - slot
3121 // x1 - function 2963 // x1 - function
3122 { 2964 {
3123 FrameScope scope(masm, StackFrame::INTERNAL); 2965 FrameScope scope(masm, StackFrame::INTERNAL);
3124 CreateWeakCellStub create_stub(masm->isolate()); 2966 CreateWeakCellStub create_stub(masm->isolate());
3125 __ Push(function); 2967 __ Push(function);
3126 __ CallStub(&create_stub); 2968 __ CallStub(&create_stub);
3127 __ Pop(function); 2969 __ Pop(function);
3128 } 2970 }
3129 2971
3130 __ B(&have_js_function); 2972 __ B(&call);
3131 2973
3132 // We are here because tracing is on or we encountered a MISS case we can't 2974 // We are here because tracing is on or we encountered a MISS case we can't
3133 // handle here. 2975 // handle here.
3134 __ bind(&miss); 2976 __ bind(&miss);
3135 GenerateMiss(masm); 2977 GenerateMiss(masm);
3136 2978
3137 // the slow case 2979 __ B(&call);
3138 __ bind(&slow_start);
3139
3140 // Check that the function is really a JavaScript function.
3141 __ JumpIfSmi(function, &slow);
3142
3143 // Goto slow case if we do not have a function.
3144 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow);
3145 __ B(&have_js_function);
3146 } 2980 }
3147 2981
3148 2982
3149 void CallICStub::GenerateMiss(MacroAssembler* masm) { 2983 void CallICStub::GenerateMiss(MacroAssembler* masm) {
3150 ASM_LOCATION("CallICStub[Miss]"); 2984 ASM_LOCATION("CallICStub[Miss]");
3151 2985
3152 FrameScope scope(masm, StackFrame::INTERNAL); 2986 FrameScope scope(masm, StackFrame::INTERNAL);
3153 2987
3154 // Push the receiver and the function and feedback info. 2988 // Push the receiver and the function and feedback info.
3155 __ Push(x1, x2, x3); 2989 __ Push(x1, x2, x3);
(...skipping 2887 matching lines...) Expand 10 before | Expand all | Expand 10 after
6043 MemOperand(fp, 6 * kPointerSize), NULL); 5877 MemOperand(fp, 6 * kPointerSize), NULL);
6044 } 5878 }
6045 5879
6046 5880
6047 #undef __ 5881 #undef __
6048 5882
6049 } // namespace internal 5883 } // namespace internal
6050 } // namespace v8 5884 } // namespace v8
6051 5885
6052 #endif // V8_TARGET_ARCH_ARM64 5886 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698