| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 2730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2741 __ Ldr(sliced_string_offset, | 2741 __ Ldr(sliced_string_offset, |
| 2742 UntagSmiFieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2742 UntagSmiFieldMemOperand(subject, SlicedString::kOffsetOffset)); |
| 2743 __ Ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2743 __ Ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
| 2744 __ B(&check_underlying); // Go to (4). | 2744 __ B(&check_underlying); // Go to (4). |
| 2745 #endif | 2745 #endif |
| 2746 } | 2746 } |
| 2747 | 2747 |
| 2748 | 2748 |
| 2749 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, | 2749 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, |
| 2750 Register argc, Register function, | 2750 Register argc, Register function, |
| 2751 Register feedback_vector, | 2751 Register feedback_vector, Register index, |
| 2752 Register index) { | 2752 Register orig_construct) { |
| 2753 FrameScope scope(masm, StackFrame::INTERNAL); | 2753 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2754 | 2754 |
| 2755 // Number-of-arguments register must be smi-tagged to call out. | 2755 // Number-of-arguments register must be smi-tagged to call out. |
| 2756 __ SmiTag(argc); | 2756 __ SmiTag(argc); |
| 2757 __ Push(argc, function, feedback_vector, index); | 2757 __ Push(argc, function, feedback_vector, index, orig_construct); |
| 2758 | 2758 |
| 2759 DCHECK(feedback_vector.Is(x2) && index.Is(x3)); | 2759 DCHECK(feedback_vector.Is(x2) && index.Is(x3)); |
| 2760 __ CallStub(stub); | 2760 __ CallStub(stub); |
| 2761 | 2761 |
| 2762 __ Pop(index, feedback_vector, function, argc); | 2762 __ Pop(orig_construct, index, feedback_vector, function, argc); |
| 2763 __ SmiUntag(argc); | 2763 __ SmiUntag(argc); |
| 2764 } | 2764 } |
| 2765 | 2765 |
| 2766 | 2766 |
| 2767 static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc, | 2767 static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc, |
| 2768 Register function, | 2768 Register function, |
| 2769 Register feedback_vector, Register index, | 2769 Register feedback_vector, Register index, |
| 2770 Register scratch1, Register scratch2, | 2770 Register orig_construct, Register scratch1, |
| 2771 Register scratch3) { | 2771 Register scratch2, Register scratch3) { |
| 2772 ASM_LOCATION("GenerateRecordCallTarget"); | 2772 ASM_LOCATION("GenerateRecordCallTarget"); |
| 2773 DCHECK(!AreAliased(scratch1, scratch2, scratch3, argc, function, | 2773 DCHECK(!AreAliased(scratch1, scratch2, scratch3, argc, function, |
| 2774 feedback_vector, index)); | 2774 feedback_vector, index, orig_construct)); |
| 2775 // Cache the called function in a feedback vector slot. Cache states are | 2775 // Cache the called function in a feedback vector slot. Cache states are |
| 2776 // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic. | 2776 // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic. |
| 2777 // argc : number of arguments to the construct function | 2777 // argc : number of arguments to the construct function |
| 2778 // function : the function to call | 2778 // function : the function to call |
| 2779 // feedback_vector : the feedback vector | 2779 // feedback_vector : the feedback vector |
| 2780 // index : slot in feedback vector (smi) | 2780 // index : slot in feedback vector (smi) |
| 2781 // orig_construct : original constructor |
| 2781 Label initialize, done, miss, megamorphic, not_array_function; | 2782 Label initialize, done, miss, megamorphic, not_array_function; |
| 2782 | 2783 |
| 2783 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2784 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
| 2784 masm->isolate()->heap()->megamorphic_symbol()); | 2785 masm->isolate()->heap()->megamorphic_symbol()); |
| 2785 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2786 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
| 2786 masm->isolate()->heap()->uninitialized_symbol()); | 2787 masm->isolate()->heap()->uninitialized_symbol()); |
| 2787 | 2788 |
| 2788 // Load the cache state. | 2789 // Load the cache state. |
| 2789 Register feedback = scratch1; | 2790 Register feedback = scratch1; |
| 2790 Register feedback_map = scratch2; | 2791 Register feedback_map = scratch2; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2849 // Make sure the function is the Array() function | 2850 // Make sure the function is the Array() function |
| 2850 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch1); | 2851 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch1); |
| 2851 __ Cmp(function, scratch1); | 2852 __ Cmp(function, scratch1); |
| 2852 __ B(ne, ¬_array_function); | 2853 __ B(ne, ¬_array_function); |
| 2853 | 2854 |
| 2854 // The target function is the Array constructor, | 2855 // The target function is the Array constructor, |
| 2855 // Create an AllocationSite if we don't already have it, store it in the | 2856 // Create an AllocationSite if we don't already have it, store it in the |
| 2856 // slot. | 2857 // slot. |
| 2857 CreateAllocationSiteStub create_stub(masm->isolate()); | 2858 CreateAllocationSiteStub create_stub(masm->isolate()); |
| 2858 CallStubInRecordCallTarget(masm, &create_stub, argc, function, | 2859 CallStubInRecordCallTarget(masm, &create_stub, argc, function, |
| 2859 feedback_vector, index); | 2860 feedback_vector, index, orig_construct); |
| 2860 __ B(&done); | 2861 __ B(&done); |
| 2861 | 2862 |
| 2862 __ Bind(¬_array_function); | 2863 __ Bind(¬_array_function); |
| 2863 } | 2864 } |
| 2864 | 2865 |
| 2865 CreateWeakCellStub create_stub(masm->isolate()); | 2866 CreateWeakCellStub create_stub(masm->isolate()); |
| 2866 CallStubInRecordCallTarget(masm, &create_stub, argc, function, | 2867 CallStubInRecordCallTarget(masm, &create_stub, argc, function, |
| 2867 feedback_vector, index); | 2868 feedback_vector, index, orig_construct); |
| 2868 __ Bind(&done); | 2869 __ Bind(&done); |
| 2869 } | 2870 } |
| 2870 | 2871 |
| 2871 | 2872 |
| 2872 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2873 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
| 2873 // Do not transform the receiver for strict mode functions. | 2874 // Do not transform the receiver for strict mode functions. |
| 2874 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); | 2875 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 2875 __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset)); | 2876 __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset)); |
| 2876 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont); | 2877 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont); |
| 2877 | 2878 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2997 Label slow, non_function_call; | 2998 Label slow, non_function_call; |
| 2998 | 2999 |
| 2999 // Check that the function is not a smi. | 3000 // Check that the function is not a smi. |
| 3000 __ JumpIfSmi(function, &non_function_call); | 3001 __ JumpIfSmi(function, &non_function_call); |
| 3001 // Check that the function is a JSFunction. | 3002 // Check that the function is a JSFunction. |
| 3002 Register object_type = x10; | 3003 Register object_type = x10; |
| 3003 __ JumpIfNotObjectType(function, object_type, object_type, JS_FUNCTION_TYPE, | 3004 __ JumpIfNotObjectType(function, object_type, object_type, JS_FUNCTION_TYPE, |
| 3004 &slow); | 3005 &slow); |
| 3005 | 3006 |
| 3006 if (RecordCallTarget()) { | 3007 if (RecordCallTarget()) { |
| 3007 if (IsSuperConstructorCall()) { | 3008 GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11, x12); |
| 3008 __ Push(x4); | |
| 3009 } | |
| 3010 // TODO(mstarzinger): Consider tweaking target recording to avoid push/pop. | |
| 3011 GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11); | |
| 3012 if (IsSuperConstructorCall()) { | |
| 3013 __ Pop(x4); | |
| 3014 } | |
| 3015 | 3009 |
| 3016 __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); | 3010 __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); |
| 3017 if (FLAG_pretenuring_call_new) { | 3011 if (FLAG_pretenuring_call_new) { |
| 3018 // Put the AllocationSite from the feedback vector into x2. | 3012 // Put the AllocationSite from the feedback vector into x2. |
| 3019 // By adding kPointerSize we encode that we know the AllocationSite | 3013 // By adding kPointerSize we encode that we know the AllocationSite |
| 3020 // entry is at the feedback vector slot given by x3 + 1. | 3014 // entry is at the feedback vector slot given by x3 + 1. |
| 3021 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize + kPointerSize)); | 3015 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize + kPointerSize)); |
| 3022 } else { | 3016 } else { |
| 3023 Label feedback_register_initialized; | 3017 Label feedback_register_initialized; |
| 3024 // Put the AllocationSite from the feedback vector into x2, or undefined. | 3018 // Put the AllocationSite from the feedback vector into x2, or undefined. |
| (...skipping 2814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5839 MemOperand(fp, 6 * kPointerSize), NULL); | 5833 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5840 } | 5834 } |
| 5841 | 5835 |
| 5842 | 5836 |
| 5843 #undef __ | 5837 #undef __ |
| 5844 | 5838 |
| 5845 } // namespace internal | 5839 } // namespace internal |
| 5846 } // namespace v8 | 5840 } // namespace v8 |
| 5847 | 5841 |
| 5848 #endif // V8_TARGET_ARCH_ARM64 | 5842 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |