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 |