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 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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, Register index, | 2751 Register feedback_vector, Register index, |
2752 Register orig_construct) { | 2752 Register orig_construct, bool is_super) { |
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, orig_construct); | 2757 if (is_super) { |
2758 __ Push(argc, function, feedback_vector, index, orig_construct); | |
jbramley
2015/07/22 07:51:36
Why not pass orig_construct=NoReg for the !is_supe
Michael Starzinger
2015/07/22 08:07:41
The way the 8-register push is implemented, it ass
| |
2759 } else { | |
2760 __ Push(argc, function, feedback_vector, index); | |
2761 } | |
2758 | 2762 |
2759 DCHECK(feedback_vector.Is(x2) && index.Is(x3)); | 2763 DCHECK(feedback_vector.Is(x2) && index.Is(x3)); |
2760 __ CallStub(stub); | 2764 __ CallStub(stub); |
2761 | 2765 |
2762 __ Pop(orig_construct, index, feedback_vector, function, argc); | 2766 if (is_super) { |
2767 __ Pop(orig_construct, index, feedback_vector, function, argc); | |
2768 } else { | |
2769 __ Pop(index, feedback_vector, function, argc); | |
2770 } | |
2763 __ SmiUntag(argc); | 2771 __ SmiUntag(argc); |
2764 } | 2772 } |
2765 | 2773 |
2766 | 2774 |
2767 static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc, | 2775 static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc, |
2768 Register function, | 2776 Register function, |
2769 Register feedback_vector, Register index, | 2777 Register feedback_vector, Register index, |
2770 Register orig_construct, Register scratch1, | 2778 Register orig_construct, Register scratch1, |
2771 Register scratch2, Register scratch3) { | 2779 Register scratch2, Register scratch3, |
2780 bool is_super) { | |
2772 ASM_LOCATION("GenerateRecordCallTarget"); | 2781 ASM_LOCATION("GenerateRecordCallTarget"); |
2773 DCHECK(!AreAliased(scratch1, scratch2, scratch3, argc, function, | 2782 DCHECK(!AreAliased(scratch1, scratch2, scratch3, argc, function, |
2774 feedback_vector, index, orig_construct)); | 2783 feedback_vector, index, orig_construct)); |
2775 // Cache the called function in a feedback vector slot. Cache states are | 2784 // Cache the called function in a feedback vector slot. Cache states are |
2776 // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic. | 2785 // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic. |
2777 // argc : number of arguments to the construct function | 2786 // argc : number of arguments to the construct function |
2778 // function : the function to call | 2787 // function : the function to call |
2779 // feedback_vector : the feedback vector | 2788 // feedback_vector : the feedback vector |
2780 // index : slot in feedback vector (smi) | 2789 // index : slot in feedback vector (smi) |
2781 // orig_construct : original constructor | 2790 // orig_construct : original constructor (for IsSuperConstructorCall) |
2782 Label initialize, done, miss, megamorphic, not_array_function; | 2791 Label initialize, done, miss, megamorphic, not_array_function; |
2783 | 2792 |
2784 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2793 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
2785 masm->isolate()->heap()->megamorphic_symbol()); | 2794 masm->isolate()->heap()->megamorphic_symbol()); |
2786 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2795 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
2787 masm->isolate()->heap()->uninitialized_symbol()); | 2796 masm->isolate()->heap()->uninitialized_symbol()); |
2788 | 2797 |
2789 // Load the cache state. | 2798 // Load the cache state. |
2790 Register feedback = scratch1; | 2799 Register feedback = scratch1; |
2791 Register feedback_map = scratch2; | 2800 Register feedback_map = scratch2; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2850 // Make sure the function is the Array() function | 2859 // Make sure the function is the Array() function |
2851 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch1); | 2860 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch1); |
2852 __ Cmp(function, scratch1); | 2861 __ Cmp(function, scratch1); |
2853 __ B(ne, ¬_array_function); | 2862 __ B(ne, ¬_array_function); |
2854 | 2863 |
2855 // The target function is the Array constructor, | 2864 // The target function is the Array constructor, |
2856 // Create an AllocationSite if we don't already have it, store it in the | 2865 // Create an AllocationSite if we don't already have it, store it in the |
2857 // slot. | 2866 // slot. |
2858 CreateAllocationSiteStub create_stub(masm->isolate()); | 2867 CreateAllocationSiteStub create_stub(masm->isolate()); |
2859 CallStubInRecordCallTarget(masm, &create_stub, argc, function, | 2868 CallStubInRecordCallTarget(masm, &create_stub, argc, function, |
2860 feedback_vector, index, orig_construct); | 2869 feedback_vector, index, orig_construct, |
2870 is_super); | |
2861 __ B(&done); | 2871 __ B(&done); |
2862 | 2872 |
2863 __ Bind(¬_array_function); | 2873 __ Bind(¬_array_function); |
2864 } | 2874 } |
2865 | 2875 |
2866 CreateWeakCellStub create_stub(masm->isolate()); | 2876 CreateWeakCellStub create_stub(masm->isolate()); |
2867 CallStubInRecordCallTarget(masm, &create_stub, argc, function, | 2877 CallStubInRecordCallTarget(masm, &create_stub, argc, function, |
2868 feedback_vector, index, orig_construct); | 2878 feedback_vector, index, orig_construct, is_super); |
2869 __ Bind(&done); | 2879 __ Bind(&done); |
2870 } | 2880 } |
2871 | 2881 |
2872 | 2882 |
2873 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2883 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
2874 // Do not transform the receiver for strict mode functions. | 2884 // Do not transform the receiver for strict mode functions. |
2875 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); | 2885 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
2876 __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset)); | 2886 __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset)); |
2877 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont); | 2887 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont); |
2878 | 2888 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2998 Label slow, non_function_call; | 3008 Label slow, non_function_call; |
2999 | 3009 |
3000 // Check that the function is not a smi. | 3010 // Check that the function is not a smi. |
3001 __ JumpIfSmi(function, &non_function_call); | 3011 __ JumpIfSmi(function, &non_function_call); |
3002 // Check that the function is a JSFunction. | 3012 // Check that the function is a JSFunction. |
3003 Register object_type = x10; | 3013 Register object_type = x10; |
3004 __ JumpIfNotObjectType(function, object_type, object_type, JS_FUNCTION_TYPE, | 3014 __ JumpIfNotObjectType(function, object_type, object_type, JS_FUNCTION_TYPE, |
3005 &slow); | 3015 &slow); |
3006 | 3016 |
3007 if (RecordCallTarget()) { | 3017 if (RecordCallTarget()) { |
3008 GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11, x12); | 3018 GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11, x12, |
3019 IsSuperConstructorCall()); | |
3009 | 3020 |
3010 __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); | 3021 __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); |
3011 if (FLAG_pretenuring_call_new) { | 3022 if (FLAG_pretenuring_call_new) { |
3012 // Put the AllocationSite from the feedback vector into x2. | 3023 // Put the AllocationSite from the feedback vector into x2. |
3013 // By adding kPointerSize we encode that we know the AllocationSite | 3024 // By adding kPointerSize we encode that we know the AllocationSite |
3014 // entry is at the feedback vector slot given by x3 + 1. | 3025 // entry is at the feedback vector slot given by x3 + 1. |
3015 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize + kPointerSize)); | 3026 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize + kPointerSize)); |
3016 } else { | 3027 } else { |
3017 Label feedback_register_initialized; | 3028 Label feedback_register_initialized; |
3018 // Put the AllocationSite from the feedback vector into x2, or undefined. | 3029 // Put the AllocationSite from the feedback vector into x2, or undefined. |
(...skipping 2814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5833 MemOperand(fp, 6 * kPointerSize), NULL); | 5844 MemOperand(fp, 6 * kPointerSize), NULL); |
5834 } | 5845 } |
5835 | 5846 |
5836 | 5847 |
5837 #undef __ | 5848 #undef __ |
5838 | 5849 |
5839 } // namespace internal | 5850 } // namespace internal |
5840 } // namespace v8 | 5851 } // namespace v8 |
5841 | 5852 |
5842 #endif // V8_TARGET_ARCH_ARM64 | 5853 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |