| 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 2633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2644 result, | 2644 result, |
| 2645 HeapNumber::kValueOffset - kHeapObjectTag, | 2645 HeapNumber::kValueOffset - kHeapObjectTag, |
| 2646 true, // is_truncating | 2646 true, // is_truncating |
| 2647 true); // skip_fastpath | 2647 true); // skip_fastpath |
| 2648 CallStub(&stub); // DoubleToIStub preserves any registers it needs to clobber | 2648 CallStub(&stub); // DoubleToIStub preserves any registers it needs to clobber |
| 2649 Pop(lr); | 2649 Pop(lr); |
| 2650 | 2650 |
| 2651 Bind(&done); | 2651 Bind(&done); |
| 2652 } | 2652 } |
| 2653 | 2653 |
| 2654 | 2654 void MacroAssembler::StubPrologue(StackFrame::Type type, int frame_slots) { |
| 2655 void MacroAssembler::StubPrologue() { | |
| 2656 UseScratchRegisterScope temps(this); | 2655 UseScratchRegisterScope temps(this); |
| 2656 frame_slots -= TypedFrameConstants::kFixedSlotCountAboveFp; |
| 2657 Register temp = temps.AcquireX(); | 2657 Register temp = temps.AcquireX(); |
| 2658 __ Mov(temp, Smi::FromInt(StackFrame::STUB)); | 2658 Mov(temp, Smi::FromInt(type)); |
| 2659 // Compiled stubs don't age, and so they don't need the predictable code | 2659 Push(lr, fp); |
| 2660 // ageing sequence. | 2660 Mov(fp, StackPointer()); |
| 2661 __ Push(lr, fp, cp, temp); | 2661 Claim(frame_slots); |
| 2662 __ Add(fp, StackPointer(), StandardFrameConstants::kFixedFrameSizeFromFp); | 2662 str(temp, MemOperand(fp, TypedFrameConstants::kFrameTypeOffset)); |
| 2663 } | 2663 } |
| 2664 | 2664 |
| 2665 | |
| 2666 void MacroAssembler::Prologue(bool code_pre_aging) { | 2665 void MacroAssembler::Prologue(bool code_pre_aging) { |
| 2667 if (code_pre_aging) { | 2666 if (code_pre_aging) { |
| 2668 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); | 2667 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); |
| 2669 __ EmitCodeAgeSequence(stub); | 2668 __ EmitCodeAgeSequence(stub); |
| 2670 } else { | 2669 } else { |
| 2671 __ EmitFrameSetupForCodeAgePatching(); | 2670 __ EmitFrameSetupForCodeAgePatching(); |
| 2672 } | 2671 } |
| 2673 } | 2672 } |
| 2674 | 2673 |
| 2675 | 2674 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2687 UNREACHABLE(); | 2686 UNREACHABLE(); |
| 2688 } | 2687 } |
| 2689 | 2688 |
| 2690 | 2689 |
| 2691 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 2690 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
| 2692 DCHECK(jssp.Is(StackPointer())); | 2691 DCHECK(jssp.Is(StackPointer())); |
| 2693 UseScratchRegisterScope temps(this); | 2692 UseScratchRegisterScope temps(this); |
| 2694 Register type_reg = temps.AcquireX(); | 2693 Register type_reg = temps.AcquireX(); |
| 2695 Register code_reg = temps.AcquireX(); | 2694 Register code_reg = temps.AcquireX(); |
| 2696 | 2695 |
| 2697 Push(lr, fp, cp); | 2696 if (type == StackFrame::INTERNAL) { |
| 2698 Mov(type_reg, Smi::FromInt(type)); | 2697 Mov(type_reg, Smi::FromInt(type)); |
| 2699 Mov(code_reg, Operand(CodeObject())); | 2698 Push(lr, fp); |
| 2700 Push(type_reg, code_reg); | 2699 Push(type_reg); |
| 2701 // jssp[4] : lr | 2700 Mov(code_reg, Operand(CodeObject())); |
| 2702 // jssp[3] : fp | 2701 Push(code_reg); |
| 2703 // jssp[2] : cp | 2702 Add(fp, jssp, InternalFrameConstants::kFixedFrameSizeFromFp); |
| 2704 // jssp[1] : type | 2703 // jssp[4] : lr |
| 2705 // jssp[0] : code object | 2704 // jssp[3] : fp |
| 2706 | 2705 // jssp[1] : type |
| 2707 // Adjust FP to point to saved FP. | 2706 // jssp[0] : [code object] |
| 2708 Add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize); | 2707 } else { |
| 2708 Mov(type_reg, Smi::FromInt(type)); |
| 2709 Push(lr, fp); |
| 2710 Push(type_reg); |
| 2711 Add(fp, jssp, TypedFrameConstants::kFixedFrameSizeFromFp); |
| 2712 // jssp[2] : lr |
| 2713 // jssp[1] : fp |
| 2714 // jssp[0] : type |
| 2715 } |
| 2709 } | 2716 } |
| 2710 | 2717 |
| 2711 | 2718 |
| 2712 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 2719 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
| 2713 DCHECK(jssp.Is(StackPointer())); | 2720 DCHECK(jssp.Is(StackPointer())); |
| 2714 // Drop the execution stack down to the frame pointer and restore | 2721 // Drop the execution stack down to the frame pointer and restore |
| 2715 // the caller frame pointer and return address. | 2722 // the caller frame pointer and return address. |
| 2716 Mov(jssp, fp); | 2723 Mov(jssp, fp); |
| 2717 AssertStackConsistency(); | 2724 AssertStackConsistency(); |
| 2718 Pop(fp, lr); | 2725 Pop(fp, lr); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2739 } | 2746 } |
| 2740 } | 2747 } |
| 2741 | 2748 |
| 2742 | 2749 |
| 2743 void MacroAssembler::EnterExitFrame(bool save_doubles, | 2750 void MacroAssembler::EnterExitFrame(bool save_doubles, |
| 2744 const Register& scratch, | 2751 const Register& scratch, |
| 2745 int extra_space) { | 2752 int extra_space) { |
| 2746 DCHECK(jssp.Is(StackPointer())); | 2753 DCHECK(jssp.Is(StackPointer())); |
| 2747 | 2754 |
| 2748 // Set up the new stack frame. | 2755 // Set up the new stack frame. |
| 2749 Mov(scratch, Operand(CodeObject())); | |
| 2750 Push(lr, fp); | 2756 Push(lr, fp); |
| 2751 Mov(fp, StackPointer()); | 2757 Mov(fp, StackPointer()); |
| 2752 Push(xzr, scratch); | 2758 Mov(scratch, Smi::FromInt(StackFrame::EXIT)); |
| 2759 Push(scratch); |
| 2760 Push(xzr); |
| 2761 Mov(scratch, Operand(CodeObject())); |
| 2762 Push(scratch); |
| 2753 // fp[8]: CallerPC (lr) | 2763 // fp[8]: CallerPC (lr) |
| 2754 // fp -> fp[0]: CallerFP (old fp) | 2764 // fp -> fp[0]: CallerFP (old fp) |
| 2755 // fp[-8]: Space reserved for SPOffset. | 2765 // fp[-8]: STUB marker |
| 2756 // jssp -> fp[-16]: CodeObject() | 2766 // fp[-16]: Space reserved for SPOffset. |
| 2757 STATIC_ASSERT((2 * kPointerSize) == | 2767 // jssp -> fp[-24]: CodeObject() |
| 2758 ExitFrameConstants::kCallerSPDisplacement); | 2768 STATIC_ASSERT((2 * kPointerSize) == ExitFrameConstants::kCallerSPOffset); |
| 2759 STATIC_ASSERT((1 * kPointerSize) == ExitFrameConstants::kCallerPCOffset); | 2769 STATIC_ASSERT((1 * kPointerSize) == ExitFrameConstants::kCallerPCOffset); |
| 2760 STATIC_ASSERT((0 * kPointerSize) == ExitFrameConstants::kCallerFPOffset); | 2770 STATIC_ASSERT((0 * kPointerSize) == ExitFrameConstants::kCallerFPOffset); |
| 2761 STATIC_ASSERT((-1 * kPointerSize) == ExitFrameConstants::kSPOffset); | 2771 STATIC_ASSERT((-2 * kPointerSize) == ExitFrameConstants::kSPOffset); |
| 2762 STATIC_ASSERT((-2 * kPointerSize) == ExitFrameConstants::kCodeOffset); | 2772 STATIC_ASSERT((-3 * kPointerSize) == ExitFrameConstants::kCodeOffset); |
| 2763 | 2773 |
| 2764 // Save the frame pointer and context pointer in the top frame. | 2774 // Save the frame pointer and context pointer in the top frame. |
| 2765 Mov(scratch, Operand(ExternalReference(Isolate::kCEntryFPAddress, | 2775 Mov(scratch, Operand(ExternalReference(Isolate::kCEntryFPAddress, |
| 2766 isolate()))); | 2776 isolate()))); |
| 2767 Str(fp, MemOperand(scratch)); | 2777 Str(fp, MemOperand(scratch)); |
| 2768 Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, | 2778 Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, |
| 2769 isolate()))); | 2779 isolate()))); |
| 2770 Str(cp, MemOperand(scratch)); | 2780 Str(cp, MemOperand(scratch)); |
| 2771 | 2781 |
| 2772 STATIC_ASSERT((-2 * kPointerSize) == | 2782 STATIC_ASSERT((-3 * kPointerSize) == ExitFrameConstants::kLastExitFrameField); |
| 2773 ExitFrameConstants::kLastExitFrameField); | |
| 2774 if (save_doubles) { | 2783 if (save_doubles) { |
| 2775 ExitFramePreserveFPRegs(); | 2784 ExitFramePreserveFPRegs(); |
| 2776 } | 2785 } |
| 2777 | 2786 |
| 2778 // Reserve space for the return address and for user requested memory. | 2787 // Reserve space for the return address and for user requested memory. |
| 2779 // We do this before aligning to make sure that we end up correctly | 2788 // We do this before aligning to make sure that we end up correctly |
| 2780 // aligned with the minimum of wasted space. | 2789 // aligned with the minimum of wasted space. |
| 2781 Claim(extra_space + 1, kXRegSize); | 2790 Claim(extra_space + 1, kXRegSize); |
| 2782 // fp[8]: CallerPC (lr) | 2791 // fp[8]: CallerPC (lr) |
| 2783 // fp -> fp[0]: CallerFP (old fp) | 2792 // fp -> fp[0]: CallerFP (old fp) |
| 2784 // fp[-8]: Space reserved for SPOffset. | 2793 // fp[-8]: STUB marker |
| 2785 // fp[-16]: CodeObject() | 2794 // fp[-16]: Space reserved for SPOffset. |
| 2786 // fp[-16 - fp_size]: Saved doubles (if save_doubles is true). | 2795 // fp[-24]: CodeObject() |
| 2796 // fp[-24 - fp_size]: Saved doubles (if save_doubles is true). |
| 2787 // jssp[8]: Extra space reserved for caller (if extra_space != 0). | 2797 // jssp[8]: Extra space reserved for caller (if extra_space != 0). |
| 2788 // jssp -> jssp[0]: Space reserved for the return address. | 2798 // jssp -> jssp[0]: Space reserved for the return address. |
| 2789 | 2799 |
| 2790 // Align and synchronize the system stack pointer with jssp. | 2800 // Align and synchronize the system stack pointer with jssp. |
| 2791 AlignAndSetCSPForFrame(); | 2801 AlignAndSetCSPForFrame(); |
| 2792 DCHECK(csp.Is(StackPointer())); | 2802 DCHECK(csp.Is(StackPointer())); |
| 2793 | 2803 |
| 2794 // fp[8]: CallerPC (lr) | 2804 // fp[8]: CallerPC (lr) |
| 2795 // fp -> fp[0]: CallerFP (old fp) | 2805 // fp -> fp[0]: CallerFP (old fp) |
| 2796 // fp[-8]: Space reserved for SPOffset. | 2806 // fp[-8]: STUB marker |
| 2797 // fp[-16]: CodeObject() | 2807 // fp[-16]: Space reserved for SPOffset. |
| 2798 // fp[-16 - fp_size]: Saved doubles (if save_doubles is true). | 2808 // fp[-24]: CodeObject() |
| 2809 // fp[-24 - fp_size]: Saved doubles (if save_doubles is true). |
| 2799 // csp[8]: Memory reserved for the caller if extra_space != 0. | 2810 // csp[8]: Memory reserved for the caller if extra_space != 0. |
| 2800 // Alignment padding, if necessary. | 2811 // Alignment padding, if necessary. |
| 2801 // csp -> csp[0]: Space reserved for the return address. | 2812 // csp -> csp[0]: Space reserved for the return address. |
| 2802 | 2813 |
| 2803 // ExitFrame::GetStateForFramePointer expects to find the return address at | 2814 // ExitFrame::GetStateForFramePointer expects to find the return address at |
| 2804 // the memory address immediately below the pointer stored in SPOffset. | 2815 // the memory address immediately below the pointer stored in SPOffset. |
| 2805 // It is not safe to derive much else from SPOffset, because the size of the | 2816 // It is not safe to derive much else from SPOffset, because the size of the |
| 2806 // padding can vary. | 2817 // padding can vary. |
| 2807 Add(scratch, csp, kXRegSize); | 2818 Add(scratch, csp, kXRegSize); |
| 2808 Str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 2819 Str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3671 } | 3682 } |
| 3672 | 3683 |
| 3673 | 3684 |
| 3674 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 3685 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
| 3675 Register scratch1, | 3686 Register scratch1, |
| 3676 Register scratch2, | 3687 Register scratch2, |
| 3677 Label* miss) { | 3688 Label* miss) { |
| 3678 DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); | 3689 DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); |
| 3679 Label same_contexts; | 3690 Label same_contexts; |
| 3680 | 3691 |
| 3681 // Load current lexical context from the stack frame. | 3692 // Load current lexical context from the active StandardFrame, which |
| 3682 Ldr(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3693 // my require crawling past STUB frames. |
| 3694 Label load_context; |
| 3695 Label has_context; |
| 3696 Mov(scratch2, fp); |
| 3697 bind(&load_context); |
| 3698 Ldr(scratch1, |
| 3699 MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset)); |
| 3700 JumpIfNotSmi(scratch1, &has_context); |
| 3701 Ldr(scratch2, MemOperand(scratch2, CommonFrameConstants::kCallerFPOffset)); |
| 3702 B(&load_context); |
| 3703 bind(&has_context); |
| 3704 |
| 3683 // In debug mode, make sure the lexical context is set. | 3705 // In debug mode, make sure the lexical context is set. |
| 3684 #ifdef DEBUG | 3706 #ifdef DEBUG |
| 3685 Cmp(scratch1, 0); | 3707 Cmp(scratch1, 0); |
| 3686 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); | 3708 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); |
| 3687 #endif | 3709 #endif |
| 3688 | 3710 |
| 3689 // Load the native context of the current context. | 3711 // Load the native context of the current context. |
| 3690 Ldr(scratch1, ContextMemOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); | 3712 Ldr(scratch1, ContextMemOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); |
| 3691 | 3713 |
| 3692 // Check the context is a native context. | 3714 // Check the context is a native context. |
| (...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4977 } | 4999 } |
| 4978 | 5000 |
| 4979 | 5001 |
| 4980 #undef __ | 5002 #undef __ |
| 4981 | 5003 |
| 4982 | 5004 |
| 4983 } // namespace internal | 5005 } // namespace internal |
| 4984 } // namespace v8 | 5006 } // namespace v8 |
| 4985 | 5007 |
| 4986 #endif // V8_TARGET_ARCH_ARM64 | 5008 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |