| 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 |