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/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 2693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2704 result, | 2704 result, |
2705 HeapNumber::kValueOffset - kHeapObjectTag, | 2705 HeapNumber::kValueOffset - kHeapObjectTag, |
2706 true, // is_truncating | 2706 true, // is_truncating |
2707 true); // skip_fastpath | 2707 true); // skip_fastpath |
2708 CallStub(&stub); // DoubleToIStub preserves any registers it needs to clobber | 2708 CallStub(&stub); // DoubleToIStub preserves any registers it needs to clobber |
2709 Pop(lr); | 2709 Pop(lr); |
2710 | 2710 |
2711 Bind(&done); | 2711 Bind(&done); |
2712 } | 2712 } |
2713 | 2713 |
2714 | 2714 void MacroAssembler::StubPrologue(StackFrame::Type type, int frame_slots) { |
2715 void MacroAssembler::StubPrologue() { | |
2716 UseScratchRegisterScope temps(this); | 2715 UseScratchRegisterScope temps(this); |
| 2716 frame_slots -= TypedFrameConstants::kFixedSlotCountAboveFp; |
2717 Register temp = temps.AcquireX(); | 2717 Register temp = temps.AcquireX(); |
2718 __ Mov(temp, Smi::FromInt(StackFrame::STUB)); | 2718 Mov(temp, Smi::FromInt(type)); |
2719 // Compiled stubs don't age, and so they don't need the predictable code | 2719 Push(lr, fp); |
2720 // ageing sequence. | 2720 Mov(fp, StackPointer()); |
2721 __ Push(lr, fp, cp, temp); | 2721 Claim(frame_slots); |
2722 __ Add(fp, StackPointer(), StandardFrameConstants::kFixedFrameSizeFromFp); | 2722 str(temp, MemOperand(fp, TypedFrameConstants::kFrameTypeOffset)); |
2723 } | 2723 } |
2724 | 2724 |
2725 | |
2726 void MacroAssembler::Prologue(bool code_pre_aging) { | 2725 void MacroAssembler::Prologue(bool code_pre_aging) { |
2727 if (code_pre_aging) { | 2726 if (code_pre_aging) { |
2728 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); | 2727 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); |
2729 __ EmitCodeAgeSequence(stub); | 2728 __ EmitCodeAgeSequence(stub); |
2730 } else { | 2729 } else { |
2731 __ EmitFrameSetupForCodeAgePatching(); | 2730 __ EmitFrameSetupForCodeAgePatching(); |
2732 } | 2731 } |
2733 } | 2732 } |
2734 | 2733 |
2735 | 2734 |
(...skipping 11 matching lines...) Expand all Loading... |
2747 UNREACHABLE(); | 2746 UNREACHABLE(); |
2748 } | 2747 } |
2749 | 2748 |
2750 | 2749 |
2751 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 2750 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
2752 DCHECK(jssp.Is(StackPointer())); | 2751 DCHECK(jssp.Is(StackPointer())); |
2753 UseScratchRegisterScope temps(this); | 2752 UseScratchRegisterScope temps(this); |
2754 Register type_reg = temps.AcquireX(); | 2753 Register type_reg = temps.AcquireX(); |
2755 Register code_reg = temps.AcquireX(); | 2754 Register code_reg = temps.AcquireX(); |
2756 | 2755 |
2757 Push(lr, fp, cp); | 2756 if (type == StackFrame::INTERNAL) { |
2758 Mov(type_reg, Smi::FromInt(type)); | 2757 Mov(type_reg, Smi::FromInt(type)); |
2759 Mov(code_reg, Operand(CodeObject())); | 2758 Push(lr, fp); |
2760 Push(type_reg, code_reg); | 2759 Push(type_reg); |
2761 // jssp[4] : lr | 2760 Mov(code_reg, Operand(CodeObject())); |
2762 // jssp[3] : fp | 2761 Push(code_reg); |
2763 // jssp[2] : cp | 2762 Add(fp, jssp, InternalFrameConstants::kFixedFrameSizeFromFp); |
2764 // jssp[1] : type | 2763 // jssp[4] : lr |
2765 // jssp[0] : code object | 2764 // jssp[3] : fp |
2766 | 2765 // jssp[1] : type |
2767 // Adjust FP to point to saved FP. | 2766 // jssp[0] : [code object] |
2768 Add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize); | 2767 } else { |
| 2768 Mov(type_reg, Smi::FromInt(type)); |
| 2769 Push(lr, fp); |
| 2770 Push(type_reg); |
| 2771 Add(fp, jssp, TypedFrameConstants::kFixedFrameSizeFromFp); |
| 2772 // jssp[2] : lr |
| 2773 // jssp[1] : fp |
| 2774 // jssp[0] : type |
| 2775 } |
2769 } | 2776 } |
2770 | 2777 |
2771 | 2778 |
2772 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 2779 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
2773 DCHECK(jssp.Is(StackPointer())); | 2780 DCHECK(jssp.Is(StackPointer())); |
2774 // Drop the execution stack down to the frame pointer and restore | 2781 // Drop the execution stack down to the frame pointer and restore |
2775 // the caller frame pointer and return address. | 2782 // the caller frame pointer and return address. |
2776 Mov(jssp, fp); | 2783 Mov(jssp, fp); |
2777 AssertStackConsistency(); | 2784 AssertStackConsistency(); |
2778 Pop(fp, lr); | 2785 Pop(fp, lr); |
(...skipping 20 matching lines...) Expand all Loading... |
2799 } | 2806 } |
2800 } | 2807 } |
2801 | 2808 |
2802 | 2809 |
2803 void MacroAssembler::EnterExitFrame(bool save_doubles, | 2810 void MacroAssembler::EnterExitFrame(bool save_doubles, |
2804 const Register& scratch, | 2811 const Register& scratch, |
2805 int extra_space) { | 2812 int extra_space) { |
2806 DCHECK(jssp.Is(StackPointer())); | 2813 DCHECK(jssp.Is(StackPointer())); |
2807 | 2814 |
2808 // Set up the new stack frame. | 2815 // Set up the new stack frame. |
2809 Mov(scratch, Operand(CodeObject())); | |
2810 Push(lr, fp); | 2816 Push(lr, fp); |
2811 Mov(fp, StackPointer()); | 2817 Mov(fp, StackPointer()); |
2812 Push(xzr, scratch); | 2818 Mov(scratch, Smi::FromInt(StackFrame::EXIT)); |
| 2819 Push(scratch); |
| 2820 Push(xzr); |
| 2821 Mov(scratch, Operand(CodeObject())); |
| 2822 Push(scratch); |
2813 // fp[8]: CallerPC (lr) | 2823 // fp[8]: CallerPC (lr) |
2814 // fp -> fp[0]: CallerFP (old fp) | 2824 // fp -> fp[0]: CallerFP (old fp) |
2815 // fp[-8]: Space reserved for SPOffset. | 2825 // fp[-8]: STUB marker |
2816 // jssp -> fp[-16]: CodeObject() | 2826 // fp[-16]: Space reserved for SPOffset. |
2817 STATIC_ASSERT((2 * kPointerSize) == | 2827 // jssp -> fp[-24]: CodeObject() |
2818 ExitFrameConstants::kCallerSPDisplacement); | 2828 STATIC_ASSERT((2 * kPointerSize) == ExitFrameConstants::kCallerSPOffset); |
2819 STATIC_ASSERT((1 * kPointerSize) == ExitFrameConstants::kCallerPCOffset); | 2829 STATIC_ASSERT((1 * kPointerSize) == ExitFrameConstants::kCallerPCOffset); |
2820 STATIC_ASSERT((0 * kPointerSize) == ExitFrameConstants::kCallerFPOffset); | 2830 STATIC_ASSERT((0 * kPointerSize) == ExitFrameConstants::kCallerFPOffset); |
2821 STATIC_ASSERT((-1 * kPointerSize) == ExitFrameConstants::kSPOffset); | 2831 STATIC_ASSERT((-2 * kPointerSize) == ExitFrameConstants::kSPOffset); |
2822 STATIC_ASSERT((-2 * kPointerSize) == ExitFrameConstants::kCodeOffset); | 2832 STATIC_ASSERT((-3 * kPointerSize) == ExitFrameConstants::kCodeOffset); |
2823 | 2833 |
2824 // Save the frame pointer and context pointer in the top frame. | 2834 // Save the frame pointer and context pointer in the top frame. |
2825 Mov(scratch, Operand(ExternalReference(Isolate::kCEntryFPAddress, | 2835 Mov(scratch, Operand(ExternalReference(Isolate::kCEntryFPAddress, |
2826 isolate()))); | 2836 isolate()))); |
2827 Str(fp, MemOperand(scratch)); | 2837 Str(fp, MemOperand(scratch)); |
2828 Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, | 2838 Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, |
2829 isolate()))); | 2839 isolate()))); |
2830 Str(cp, MemOperand(scratch)); | 2840 Str(cp, MemOperand(scratch)); |
2831 | 2841 |
2832 STATIC_ASSERT((-2 * kPointerSize) == | 2842 STATIC_ASSERT((-3 * kPointerSize) == ExitFrameConstants::kLastExitFrameField); |
2833 ExitFrameConstants::kLastExitFrameField); | |
2834 if (save_doubles) { | 2843 if (save_doubles) { |
2835 ExitFramePreserveFPRegs(); | 2844 ExitFramePreserveFPRegs(); |
2836 } | 2845 } |
2837 | 2846 |
2838 // Reserve space for the return address and for user requested memory. | 2847 // Reserve space for the return address and for user requested memory. |
2839 // We do this before aligning to make sure that we end up correctly | 2848 // We do this before aligning to make sure that we end up correctly |
2840 // aligned with the minimum of wasted space. | 2849 // aligned with the minimum of wasted space. |
2841 Claim(extra_space + 1, kXRegSize); | 2850 Claim(extra_space + 1, kXRegSize); |
2842 // fp[8]: CallerPC (lr) | 2851 // fp[8]: CallerPC (lr) |
2843 // fp -> fp[0]: CallerFP (old fp) | 2852 // fp -> fp[0]: CallerFP (old fp) |
2844 // fp[-8]: Space reserved for SPOffset. | 2853 // fp[-8]: STUB marker |
2845 // fp[-16]: CodeObject() | 2854 // fp[-16]: Space reserved for SPOffset. |
2846 // fp[-16 - fp_size]: Saved doubles (if save_doubles is true). | 2855 // fp[-24]: CodeObject() |
| 2856 // fp[-24 - fp_size]: Saved doubles (if save_doubles is true). |
2847 // jssp[8]: Extra space reserved for caller (if extra_space != 0). | 2857 // jssp[8]: Extra space reserved for caller (if extra_space != 0). |
2848 // jssp -> jssp[0]: Space reserved for the return address. | 2858 // jssp -> jssp[0]: Space reserved for the return address. |
2849 | 2859 |
2850 // Align and synchronize the system stack pointer with jssp. | 2860 // Align and synchronize the system stack pointer with jssp. |
2851 AlignAndSetCSPForFrame(); | 2861 AlignAndSetCSPForFrame(); |
2852 DCHECK(csp.Is(StackPointer())); | 2862 DCHECK(csp.Is(StackPointer())); |
2853 | 2863 |
2854 // fp[8]: CallerPC (lr) | 2864 // fp[8]: CallerPC (lr) |
2855 // fp -> fp[0]: CallerFP (old fp) | 2865 // fp -> fp[0]: CallerFP (old fp) |
2856 // fp[-8]: Space reserved for SPOffset. | 2866 // fp[-8]: STUB marker |
2857 // fp[-16]: CodeObject() | 2867 // fp[-16]: Space reserved for SPOffset. |
2858 // fp[-16 - fp_size]: Saved doubles (if save_doubles is true). | 2868 // fp[-24]: CodeObject() |
| 2869 // fp[-24 - fp_size]: Saved doubles (if save_doubles is true). |
2859 // csp[8]: Memory reserved for the caller if extra_space != 0. | 2870 // csp[8]: Memory reserved for the caller if extra_space != 0. |
2860 // Alignment padding, if necessary. | 2871 // Alignment padding, if necessary. |
2861 // csp -> csp[0]: Space reserved for the return address. | 2872 // csp -> csp[0]: Space reserved for the return address. |
2862 | 2873 |
2863 // ExitFrame::GetStateForFramePointer expects to find the return address at | 2874 // ExitFrame::GetStateForFramePointer expects to find the return address at |
2864 // the memory address immediately below the pointer stored in SPOffset. | 2875 // the memory address immediately below the pointer stored in SPOffset. |
2865 // It is not safe to derive much else from SPOffset, because the size of the | 2876 // It is not safe to derive much else from SPOffset, because the size of the |
2866 // padding can vary. | 2877 // padding can vary. |
2867 Add(scratch, csp, kXRegSize); | 2878 Add(scratch, csp, kXRegSize); |
2868 Str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 2879 Str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3731 } | 3742 } |
3732 | 3743 |
3733 | 3744 |
3734 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 3745 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
3735 Register scratch1, | 3746 Register scratch1, |
3736 Register scratch2, | 3747 Register scratch2, |
3737 Label* miss) { | 3748 Label* miss) { |
3738 DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); | 3749 DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); |
3739 Label same_contexts; | 3750 Label same_contexts; |
3740 | 3751 |
3741 // Load current lexical context from the stack frame. | 3752 // Load current lexical context from the active StandardFrame, which |
3742 Ldr(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3753 // may require crawling past STUB frames. |
| 3754 Label load_context; |
| 3755 Label has_context; |
| 3756 Mov(scratch2, fp); |
| 3757 bind(&load_context); |
| 3758 Ldr(scratch1, |
| 3759 MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset)); |
| 3760 JumpIfNotSmi(scratch1, &has_context); |
| 3761 Ldr(scratch2, MemOperand(scratch2, CommonFrameConstants::kCallerFPOffset)); |
| 3762 B(&load_context); |
| 3763 bind(&has_context); |
| 3764 |
3743 // In debug mode, make sure the lexical context is set. | 3765 // In debug mode, make sure the lexical context is set. |
3744 #ifdef DEBUG | 3766 #ifdef DEBUG |
3745 Cmp(scratch1, 0); | 3767 Cmp(scratch1, 0); |
3746 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); | 3768 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); |
3747 #endif | 3769 #endif |
3748 | 3770 |
3749 // Load the native context of the current context. | 3771 // Load the native context of the current context. |
3750 Ldr(scratch1, ContextMemOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); | 3772 Ldr(scratch1, ContextMemOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); |
3751 | 3773 |
3752 // Check the context is a native context. | 3774 // Check the context is a native context. |
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5037 } | 5059 } |
5038 | 5060 |
5039 | 5061 |
5040 #undef __ | 5062 #undef __ |
5041 | 5063 |
5042 | 5064 |
5043 } // namespace internal | 5065 } // namespace internal |
5044 } // namespace v8 | 5066 } // namespace v8 |
5045 | 5067 |
5046 #endif // V8_TARGET_ARCH_ARM64 | 5068 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |