| OLD | NEW |
| 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 Loading... |
| 2740 __ B(&done); | 2740 __ B(&done); |
| 2741 | 2741 |
| 2742 __ Bind(¬_array_function); | 2742 __ Bind(¬_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) { | 2750 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
| 2761 // ----------- S t a t e ------------- | 2751 // Do not transform the receiver for strict mode functions. |
| 2762 // -- a1 : the function to call | 2752 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 2763 // -- x3 : the shared function info | 2753 __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset)); |
| 2764 // -- w4 : the compiler info hints from the shared function info | |
| 2765 // ----------------------------------- | |
| 2766 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont); | 2754 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont); |
| 2767 | 2755 |
| 2768 // Do not transform the receiver for native (Compilerhints already in x3). | 2756 // Do not transform the receiver for native (Compilerhints already in x3). |
| 2769 __ Tbnz(w4, SharedFunctionInfo::kNative, cont); | 2757 __ Tbnz(w4, SharedFunctionInfo::kNative, cont); |
| 2770 } | 2758 } |
| 2771 | 2759 |
| 2772 | 2760 |
| 2773 static void EmitSlowCase(MacroAssembler* masm, int argc) { | 2761 static void EmitSlowCase(MacroAssembler* masm, int argc) { |
| 2774 __ Mov(x0, argc); | 2762 __ Mov(x0, argc); |
| 2775 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2763 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 2776 } | 2764 } |
| 2777 | 2765 |
| 2778 | 2766 |
| 2779 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { | 2767 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { |
| 2780 // Wrap the receiver and patch it back onto the stack. | 2768 // Wrap the receiver and patch it back onto the stack. |
| 2781 { FrameScope frame_scope(masm, StackFrame::INTERNAL); | 2769 { FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 2782 __ Push(x1); | 2770 __ Push(x1); |
| 2783 __ Mov(x0, x3); | 2771 __ Mov(x0, x3); |
| 2784 ToObjectStub stub(masm->isolate()); | 2772 ToObjectStub stub(masm->isolate()); |
| 2785 __ CallStub(&stub); | 2773 __ CallStub(&stub); |
| 2786 __ Pop(x1); | 2774 __ Pop(x1); |
| 2787 } | 2775 } |
| 2788 __ Poke(x0, argc * kPointerSize); | 2776 __ Poke(x0, argc * kPointerSize); |
| 2789 __ B(cont); | 2777 __ B(cont); |
| 2790 } | 2778 } |
| 2791 | 2779 |
| 2792 | 2780 |
| 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, | 2781 static void CallFunctionNoFeedback(MacroAssembler* masm, |
| 2814 int argc, bool needs_checks, | 2782 int argc, bool needs_checks, |
| 2815 bool call_as_method) { | 2783 bool call_as_method) { |
| 2816 // x1 function the function to call | 2784 // x1 function the function to call |
| 2817 Register function = x1; | 2785 Register function = x1; |
| 2818 Register type = x4; | 2786 Register type = x4; |
| 2819 Label slow, wrap, cont; | 2787 Label slow, wrap, cont; |
| 2820 | 2788 |
| 2821 // TODO(jbramley): This function has a lot of unnamed registers. Name them, | 2789 // TODO(jbramley): This function has a lot of unnamed registers. Name them, |
| 2822 // and tidy things up a bit. | 2790 // and tidy things up a bit. |
| 2823 | 2791 |
| 2824 if (needs_checks) { | 2792 if (needs_checks) { |
| 2825 // Check that the function is really a JavaScript function. | 2793 // Check that the function is really a JavaScript function. |
| 2826 __ JumpIfSmi(function, &slow); | 2794 __ JumpIfSmi(function, &slow); |
| 2827 | 2795 |
| 2828 // Goto slow case if we do not have a function. | 2796 // Goto slow case if we do not have a function. |
| 2829 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); | 2797 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); |
| 2830 } | 2798 } |
| 2831 | 2799 |
| 2832 LoadCompilerHints(masm); | |
| 2833 EmitClassConstructorCallCheck(masm); | |
| 2834 | |
| 2835 // Fast-case: Invoke the function now. | 2800 // Fast-case: Invoke the function now. |
| 2836 // x1 function pushed function | 2801 // x1 function pushed function |
| 2837 ParameterCount actual(argc); | 2802 ParameterCount actual(argc); |
| 2838 | 2803 |
| 2839 if (call_as_method) { | 2804 if (call_as_method) { |
| 2840 if (needs_checks) { | 2805 if (needs_checks) { |
| 2841 EmitContinueIfStrictOrNative(masm, &cont); | 2806 EmitContinueIfStrictOrNative(masm, &cont); |
| 2842 } | 2807 } |
| 2843 | 2808 |
| 2844 // Compute the receiver in sloppy mode. | 2809 // Compute the receiver in sloppy mode. |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3017 // Increment the call count for monomorphic function calls. | 2982 // Increment the call count for monomorphic function calls. |
| 3018 __ Add(feedback_vector, feedback_vector, | 2983 __ Add(feedback_vector, feedback_vector, |
| 3019 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 2984 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 3020 __ Add(feedback_vector, feedback_vector, | 2985 __ Add(feedback_vector, feedback_vector, |
| 3021 Operand(FixedArray::kHeaderSize + kPointerSize)); | 2986 Operand(FixedArray::kHeaderSize + kPointerSize)); |
| 3022 __ Ldr(index, FieldMemOperand(feedback_vector, 0)); | 2987 __ Ldr(index, FieldMemOperand(feedback_vector, 0)); |
| 3023 __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2988 __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
| 3024 __ Str(index, FieldMemOperand(feedback_vector, 0)); | 2989 __ Str(index, FieldMemOperand(feedback_vector, 0)); |
| 3025 | 2990 |
| 3026 __ bind(&have_js_function); | 2991 __ bind(&have_js_function); |
| 3027 | |
| 3028 LoadCompilerHints(masm); | |
| 3029 EmitClassConstructorCallCheck(masm); | |
| 3030 | |
| 3031 if (CallAsMethod()) { | 2992 if (CallAsMethod()) { |
| 3032 EmitContinueIfStrictOrNative(masm, &cont); | 2993 EmitContinueIfStrictOrNative(masm, &cont); |
| 3033 | 2994 |
| 3034 // Compute the receiver in sloppy mode. | 2995 // Compute the receiver in sloppy mode. |
| 3035 __ Peek(x3, argc * kPointerSize); | 2996 __ Peek(x3, argc * kPointerSize); |
| 3036 | 2997 |
| 3037 __ JumpIfSmi(x3, &wrap); | 2998 __ JumpIfSmi(x3, &wrap); |
| 3038 __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt); | 2999 __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt); |
| 3039 | 3000 |
| 3040 __ Bind(&cont); | 3001 __ Bind(&cont); |
| (...skipping 3002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6043 MemOperand(fp, 6 * kPointerSize), NULL); | 6004 MemOperand(fp, 6 * kPointerSize), NULL); |
| 6044 } | 6005 } |
| 6045 | 6006 |
| 6046 | 6007 |
| 6047 #undef __ | 6008 #undef __ |
| 6048 | 6009 |
| 6049 } // namespace internal | 6010 } // namespace internal |
| 6050 } // namespace v8 | 6011 } // namespace v8 |
| 6051 | 6012 |
| 6052 #endif // V8_TARGET_ARCH_ARM64 | 6013 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |