| OLD | NEW | 
|---|
| 1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" | 
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) | 
| 7 | 7 | 
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" | 
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" | 
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 41     // Not adding Object::null() to the index table. It is at index 0 in the | 41     // Not adding Object::null() to the index table. It is at index 0 in the | 
| 42     // object pool, but the HashMap uses 0 to indicate not found. | 42     // object pool, but the HashMap uses 0 to indicate not found. | 
| 43 | 43 | 
| 44     object_pool_.Add(Bool::True(), Heap::kOld); | 44     object_pool_.Add(Bool::True(), Heap::kOld); | 
| 45     patchable_pool_entries_.Add(kNotPatchable); | 45     patchable_pool_entries_.Add(kNotPatchable); | 
| 46     object_pool_index_table_.Insert(ObjIndexPair(Bool::True().raw(), 1)); | 46     object_pool_index_table_.Insert(ObjIndexPair(Bool::True().raw(), 1)); | 
| 47 | 47 | 
| 48     object_pool_.Add(Bool::False(), Heap::kOld); | 48     object_pool_.Add(Bool::False(), Heap::kOld); | 
| 49     patchable_pool_entries_.Add(kNotPatchable); | 49     patchable_pool_entries_.Add(kNotPatchable); | 
| 50     object_pool_index_table_.Insert(ObjIndexPair(Bool::False().raw(), 2)); | 50     object_pool_index_table_.Insert(ObjIndexPair(Bool::False().raw(), 2)); | 
|  | 51 | 
|  | 52     if (StubCode::UpdateStoreBuffer_entry() != NULL) { | 
|  | 53       FindExternalLabel(&StubCode::UpdateStoreBufferLabel(), kNotPatchable); | 
|  | 54     } else { | 
|  | 55       object_pool_.Add(Object::null_object(), Heap::kOld); | 
|  | 56       patchable_pool_entries_.Add(kNotPatchable); | 
|  | 57     } | 
|  | 58 | 
|  | 59     if (StubCode::CallToRuntime_entry() != NULL) { | 
|  | 60       FindExternalLabel(&StubCode::CallToRuntimeLabel(), kNotPatchable); | 
|  | 61     } else { | 
|  | 62       object_pool_.Add(Object::null_object(), Heap::kOld); | 
|  | 63       patchable_pool_entries_.Add(kNotPatchable); | 
|  | 64     } | 
|  | 65 | 
|  | 66     // Create fixed object pool entry for debugger stub. | 
|  | 67     if (StubCode::BreakpointRuntime_entry() != NULL) { | 
|  | 68       intptr_t index = | 
|  | 69           FindExternalLabel(&StubCode::BreakpointRuntimeLabel(), kNotPatchable); | 
|  | 70       ASSERT(index == kBreakpointRuntimeCPIndex); | 
|  | 71     } else { | 
|  | 72       object_pool_.Add(Object::null_object(), Heap::kOld); | 
|  | 73       patchable_pool_entries_.Add(kNotPatchable); | 
|  | 74     } | 
| 51   } | 75   } | 
| 52 } | 76 } | 
| 53 | 77 | 
| 54 | 78 | 
| 55 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 79 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 
| 56   ASSERT(Utils::IsAligned(data, 4)); | 80   ASSERT(Utils::IsAligned(data, 4)); | 
| 57   ASSERT(Utils::IsAligned(length, 4)); | 81   ASSERT(Utils::IsAligned(length, 4)); | 
| 58   const uword end = data + length; | 82   const uword end = data + length; | 
| 59   while (data < end) { | 83   while (data < end) { | 
| 60     *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction; | 84     *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction; | 
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 669                                          const Address& dest, | 693                                          const Address& dest, | 
| 670                                          const Object& value) { | 694                                          const Object& value) { | 
| 671   ASSERT(value.IsSmi() || value.InVMHeap() || | 695   ASSERT(value.IsSmi() || value.InVMHeap() || | 
| 672          (value.IsOld() && value.IsNotTemporaryScopedHandle())); | 696          (value.IsOld() && value.IsNotTemporaryScopedHandle())); | 
| 673   // No store buffer update. | 697   // No store buffer update. | 
| 674   LoadObject(TMP, value, PP); | 698   LoadObject(TMP, value, PP); | 
| 675   str(TMP, dest); | 699   str(TMP, dest); | 
| 676 } | 700 } | 
| 677 | 701 | 
| 678 | 702 | 
|  | 703 void Assembler::LoadClassId(Register result, Register object) { | 
|  | 704   ASSERT(RawObject::kClassIdTagBit == 16); | 
|  | 705   ASSERT(RawObject::kClassIdTagSize == 16); | 
|  | 706   const intptr_t class_id_offset = Object::tags_offset() + | 
|  | 707       RawObject::kClassIdTagBit / kBitsPerByte; | 
|  | 708   LoadFromOffset(result, object, class_id_offset - kHeapObjectTag, | 
|  | 709                  kUnsignedHalfword); | 
|  | 710 } | 
|  | 711 | 
|  | 712 | 
|  | 713 void Assembler::LoadClassById(Register result, Register class_id) { | 
|  | 714   ASSERT(result != class_id); | 
|  | 715   LoadFieldFromOffset(result, CTX, Context::isolate_offset()); | 
|  | 716   const intptr_t table_offset_in_isolate = | 
|  | 717       Isolate::class_table_offset() + ClassTable::table_offset(); | 
|  | 718   LoadFromOffset(result, result, table_offset_in_isolate); | 
|  | 719   ldr(result, Address(result, class_id, UXTX, Address::Scaled)); | 
|  | 720 } | 
|  | 721 | 
|  | 722 | 
|  | 723 void Assembler::LoadClass(Register result, Register object) { | 
|  | 724   ASSERT(object != TMP); | 
|  | 725   LoadClassId(TMP, object); | 
|  | 726   LoadClassById(result, TMP); | 
|  | 727 } | 
|  | 728 | 
|  | 729 | 
|  | 730 void Assembler::CompareClassId(Register object, | 
|  | 731                                intptr_t class_id) { | 
|  | 732   LoadClassId(TMP, object); | 
|  | 733   CompareImmediate(TMP, class_id, PP); | 
|  | 734 } | 
|  | 735 | 
|  | 736 | 
| 679 // Frame entry and exit. | 737 // Frame entry and exit. | 
| 680 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 738 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 
| 681   // Reserve space for arguments and align frame before entering | 739   // Reserve space for arguments and align frame before entering | 
| 682   // the C++ world. | 740   // the C++ world. | 
| 683   AddImmediate(SP, SP, -frame_space, kNoRegister); | 741   AddImmediate(SP, SP, -frame_space, kNoRegister); | 
| 684   if (OS::ActivationFrameAlignment() > 1) { | 742   if (OS::ActivationFrameAlignment() > 1) { | 
| 685     mov(TMP, SP);  // SP can't be register operand of andi. | 743     mov(TMP, SP);  // SP can't be register operand of andi. | 
| 686     andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1)); | 744     andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1)); | 
| 687     mov(SP, TMP); | 745     mov(SP, TMP); | 
| 688   } | 746   } | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 702 | 760 | 
| 703 void Assembler::LeaveFrame() { | 761 void Assembler::LeaveFrame() { | 
| 704   mov(SP, FP); | 762   mov(SP, FP); | 
| 705   Pop(FP); | 763   Pop(FP); | 
| 706   Pop(LR); | 764   Pop(LR); | 
| 707 } | 765 } | 
| 708 | 766 | 
| 709 | 767 | 
| 710 void Assembler::EnterDartFrame(intptr_t frame_size) { | 768 void Assembler::EnterDartFrame(intptr_t frame_size) { | 
| 711   // Setup the frame. | 769   // Setup the frame. | 
| 712   adr(TMP, 0);  // TMP gets PC of this instruction. | 770   adr(TMP, -CodeSize());  // TMP gets PC marker. | 
| 713   EnterFrame(0); | 771   EnterFrame(0); | 
| 714   Push(TMP);  // Save PC Marker. | 772   Push(TMP);  // Save PC Marker. | 
| 715   TagAndPushPP();  // Save PP. | 773   TagAndPushPP();  // Save PP. | 
| 716 | 774 | 
| 717   // Load the pool pointer. | 775   // Load the pool pointer. | 
| 718   LoadPoolPointer(PP); | 776   LoadPoolPointer(PP); | 
| 719 | 777 | 
| 720   // Reserve space. | 778   // Reserve space. | 
| 721   if (frame_size > 0) { | 779   if (frame_size > 0) { | 
| 722     sub(SP, SP, Operand(frame_size)); | 780     AddImmediate(SP, SP, -frame_size, PP); | 
| 723   } | 781   } | 
| 724 } | 782 } | 
| 725 | 783 | 
| 726 | 784 | 
| 727 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp) { | 785 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp) { | 
| 728   // Setup the frame. | 786   // Setup the frame. | 
| 729   adr(TMP, 0);  // TMP gets PC of this instruction. | 787   adr(TMP, -CodeSize());  // TMP gets PC marker. | 
| 730   EnterFrame(0); | 788   EnterFrame(0); | 
| 731   Push(TMP);  // Save PC Marker. | 789   Push(TMP);  // Save PC Marker. | 
| 732   TagAndPushPP();  // Save PP. | 790   TagAndPushPP();  // Save PP. | 
| 733 | 791 | 
| 734   // Load the pool pointer. | 792   // Load the pool pointer. | 
| 735   if (new_pp == kNoRegister) { | 793   if (new_pp == kNoRegister) { | 
| 736     LoadPoolPointer(PP); | 794     LoadPoolPointer(PP); | 
| 737   } else { | 795   } else { | 
| 738     mov(PP, new_pp); | 796     mov(PP, new_pp); | 
| 739   } | 797   } | 
| 740 | 798 | 
| 741   // Reserve space. | 799   // Reserve space. | 
| 742   if (frame_size > 0) { | 800   if (frame_size > 0) { | 
| 743     sub(SP, SP, Operand(frame_size)); | 801     AddImmediate(SP, SP, -frame_size, PP); | 
| 744   } | 802   } | 
| 745 } | 803 } | 
| 746 | 804 | 
| 747 | 805 | 
| 748 // On entry to a function compiled for OSR, the caller's frame pointer, the | 806 // On entry to a function compiled for OSR, the caller's frame pointer, the | 
| 749 // stack locals, and any copied parameters are already in place.  The frame | 807 // stack locals, and any copied parameters are already in place.  The frame | 
| 750 // pointer is already set up.  The PC marker is not correct for the | 808 // pointer is already set up.  The PC marker is not correct for the | 
| 751 // optimized function and there may be extra space for spill slots to | 809 // optimized function and there may be extra space for spill slots to | 
| 752 // allocate. We must also set up the pool pointer for the function. | 810 // allocate. We must also set up the pool pointer for the function. | 
| 753 void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) { | 811 void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) { | 
| 754   const intptr_t offset = CodeSize(); | 812   const intptr_t offset = CodeSize(); | 
| 755 | 813 | 
| 756   Comment("EnterOsrFrame"); | 814   Comment("EnterOsrFrame"); | 
| 757   adr(TMP, 0); | 815   adr(TMP, -CodeSize()); | 
| 758 | 816 | 
| 759   AddImmediate(TMP, TMP, -offset, kNoRegister); | 817   AddImmediate(TMP, TMP, -offset, kNoRegister); | 
| 760   StoreToOffset(TMP, FP, kPcMarkerSlotFromFp * kWordSize); | 818   StoreToOffset(TMP, FP, kPcMarkerSlotFromFp * kWordSize); | 
| 761 | 819 | 
| 762   // Setup pool pointer for this dart function. | 820   // Setup pool pointer for this dart function. | 
| 763   if (new_pp == kNoRegister) { | 821   if (new_pp == kNoRegister) { | 
| 764     LoadPoolPointer(PP); | 822     LoadPoolPointer(PP); | 
| 765   } else { | 823   } else { | 
| 766     mov(PP, new_pp); | 824     mov(PP, new_pp); | 
| 767   } | 825   } | 
| 768 | 826 | 
| 769   if (extra_size > 0) { | 827   if (extra_size > 0) { | 
| 770     sub(SP, SP, Operand(extra_size)); | 828     AddImmediate(SP, SP, -extra_size, PP); | 
| 771   } | 829   } | 
| 772 } | 830 } | 
| 773 | 831 | 
| 774 | 832 | 
| 775 void Assembler::LeaveDartFrame() { | 833 void Assembler::LeaveDartFrame() { | 
| 776   // Restore and untag PP. | 834   // Restore and untag PP. | 
| 777   LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); | 835   LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); | 
| 778   sub(PP, PP, Operand(kHeapObjectTag)); | 836   sub(PP, PP, Operand(kHeapObjectTag)); | 
| 779   LeaveFrame(); | 837   LeaveFrame(); | 
| 780 } | 838 } | 
| 781 | 839 | 
| 782 | 840 | 
| 783 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) { | 841 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) { | 
| 784   EnterFrame(0); | 842   EnterFrame(0); | 
| 785 | 843 | 
| 786   // TODO(zra): also save volatile FPU registers. | 844   // TODO(zra): also save volatile FPU registers. | 
| 787 | 845 | 
| 788   for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) { | 846   for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) { | 
| 789     const Register reg = static_cast<Register>(i); | 847     const Register reg = static_cast<Register>(i); | 
| 790     Push(reg); | 848     if ((reg != R16) && (reg != R17)) { | 
|  | 849       Push(reg); | 
|  | 850     } | 
| 791   } | 851   } | 
| 792 | 852 | 
| 793   ReserveAlignedFrameSpace(frame_size); | 853   ReserveAlignedFrameSpace(frame_size); | 
| 794 } | 854 } | 
| 795 | 855 | 
| 796 | 856 | 
| 797 void Assembler::LeaveCallRuntimeFrame() { | 857 void Assembler::LeaveCallRuntimeFrame() { | 
| 798   // SP might have been modified to reserve space for arguments | 858   // SP might have been modified to reserve space for arguments | 
| 799   // and ensure proper alignment of the stack frame. | 859   // and ensure proper alignment of the stack frame. | 
| 800   // We need to restore it before restoring registers. | 860   // We need to restore it before restoring registers. | 
| 801   // TODO(zra): Also include FPU regs in this count once they are added. | 861   // TODO(zra): Also include FPU regs in this count once they are added. | 
| 802   const intptr_t kPushedRegistersSize = | 862   const intptr_t kPushedRegistersSize = | 
| 803       kDartVolatileCpuRegCount * kWordSize; | 863       kDartVolatileCpuRegCount * kWordSize; | 
| 804   AddImmediate(SP, FP, -kPushedRegistersSize, PP); | 864   AddImmediate(SP, FP, -kPushedRegistersSize, PP); | 
| 805   for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) { | 865   for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) { | 
| 806     const Register reg = static_cast<Register>(i); | 866     const Register reg = static_cast<Register>(i); | 
| 807     Pop(reg); | 867     if ((reg != R16) && (reg != R17)) { | 
|  | 868       Pop(reg); | 
|  | 869     } | 
| 808   } | 870   } | 
| 809 | 871 | 
| 810   Pop(FP); | 872   Pop(FP); | 
| 811   Pop(LR); | 873   Pop(LR); | 
| 812 } | 874 } | 
| 813 | 875 | 
| 814 | 876 | 
| 815 void Assembler::CallRuntime(const RuntimeEntry& entry, | 877 void Assembler::CallRuntime(const RuntimeEntry& entry, | 
| 816                             intptr_t argument_count) { | 878                             intptr_t argument_count) { | 
| 817   entry.Call(this, argument_count); | 879   entry.Call(this, argument_count); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 831 void Assembler::LeaveStubFrame() { | 893 void Assembler::LeaveStubFrame() { | 
| 832   // Restore and untag PP. | 894   // Restore and untag PP. | 
| 833   LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); | 895   LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); | 
| 834   sub(PP, PP, Operand(kHeapObjectTag)); | 896   sub(PP, PP, Operand(kHeapObjectTag)); | 
| 835   LeaveFrame(); | 897   LeaveFrame(); | 
| 836 } | 898 } | 
| 837 | 899 | 
| 838 }  // namespace dart | 900 }  // namespace dart | 
| 839 | 901 | 
| 840 #endif  // defined TARGET_ARCH_ARM64 | 902 #endif  // defined TARGET_ARCH_ARM64 | 
| OLD | NEW | 
|---|