| 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 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 // object pool. | 394 // object pool. |
| 395 // TODO(zra): Evaluate putting all VM heap objects into the pool. | 395 // TODO(zra): Evaluate putting all VM heap objects into the pool. |
| 396 (!object.InVMHeap() || (object.raw() == Object::null()) || | 396 (!object.InVMHeap() || (object.raw() == Object::null()) || |
| 397 (object.raw() == Bool::True().raw()) || | 397 (object.raw() == Bool::True().raw()) || |
| 398 (object.raw() == Bool::False().raw())); | 398 (object.raw() == Bool::False().raw())); |
| 399 } | 399 } |
| 400 | 400 |
| 401 | 401 |
| 402 bool Assembler::CanLoadImmediateFromPool(int64_t imm, Register pp) { | 402 bool Assembler::CanLoadImmediateFromPool(int64_t imm, Register pp) { |
| 403 return !Utils::IsInt(32, imm) && | 403 return !Utils::IsInt(32, imm) && |
| 404 (pp != kNoRegister) && | 404 (pp != kNoPP) && |
| 405 (Isolate::Current() != Dart::vm_isolate()); | 405 (Isolate::Current() != Dart::vm_isolate()); |
| 406 } | 406 } |
| 407 | 407 |
| 408 | 408 |
| 409 void Assembler::LoadExternalLabel(Register dst, | 409 void Assembler::LoadExternalLabel(Register dst, |
| 410 const ExternalLabel* label, | 410 const ExternalLabel* label, |
| 411 Patchability patchable, | 411 Patchability patchable, |
| 412 Register pp) { | 412 Register pp) { |
| 413 const int32_t offset = | 413 const int32_t offset = |
| 414 Array::element_offset(FindExternalLabel(label, patchable)); | 414 Array::element_offset(FindExternalLabel(label, patchable)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 434 if (CanLoadObjectFromPool(object)) { | 434 if (CanLoadObjectFromPool(object)) { |
| 435 LoadObject(TMP, object, pp); | 435 LoadObject(TMP, object, pp); |
| 436 CompareRegisters(reg, TMP); | 436 CompareRegisters(reg, TMP); |
| 437 } else { | 437 } else { |
| 438 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp); | 438 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp); |
| 439 } | 439 } |
| 440 } | 440 } |
| 441 | 441 |
| 442 | 442 |
| 443 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) { | 443 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) { |
| 444 if ((pp != kNoRegister) && (Isolate::Current() != Dart::vm_isolate())) { | 444 if ((pp != kNoPP) && (Isolate::Current() != Dart::vm_isolate())) { |
| 445 int64_t val_smi_tag = imm & kSmiTagMask; | 445 int64_t val_smi_tag = imm & kSmiTagMask; |
| 446 imm &= ~kSmiTagMask; // Mask off the tag bits. | 446 imm &= ~kSmiTagMask; // Mask off the tag bits. |
| 447 const int32_t offset = Array::element_offset(FindImmediate(imm)); | 447 const int32_t offset = Array::element_offset(FindImmediate(imm)); |
| 448 LoadWordFromPoolOffset(reg, pp, offset); | 448 LoadWordFromPoolOffset(reg, pp, offset); |
| 449 if (val_smi_tag != 0) { | 449 if (val_smi_tag != 0) { |
| 450 // Add back the tag bits. | 450 // Add back the tag bits. |
| 451 orri(reg, reg, val_smi_tag); | 451 orri(reg, reg, val_smi_tag); |
| 452 } | 452 } |
| 453 } else { | 453 } else { |
| 454 // TODO(zra): Since this sequence only needs to be decodable, it can be | 454 // TODO(zra): Since this sequence only needs to be decodable, it can be |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 } else { | 604 } else { |
| 605 LoadImmediate(TMP2, imm, pp); | 605 LoadImmediate(TMP2, imm, pp); |
| 606 cmp(rn, Operand(TMP2)); | 606 cmp(rn, Operand(TMP2)); |
| 607 } | 607 } |
| 608 } | 608 } |
| 609 | 609 |
| 610 | 610 |
| 611 void Assembler::LoadFromOffset( | 611 void Assembler::LoadFromOffset( |
| 612 Register dest, Register base, int32_t offset, OperandSize sz) { | 612 Register dest, Register base, int32_t offset, OperandSize sz) { |
| 613 ASSERT(base != TMP2); | 613 ASSERT(base != TMP2); |
| 614 if (Address::CanHoldOffset(offset)) { | 614 if (Address::CanHoldOffset(offset, Address::Offset, sz)) { |
| 615 ldr(dest, Address(base, offset), sz); | 615 ldr(dest, Address(base, offset, Address::Offset, sz), sz); |
| 616 } else { | 616 } else { |
| 617 // Since offset is 32-bits, it won't be loaded from the pool. | 617 // Since offset is 32-bits, it won't be loaded from the pool. |
| 618 AddImmediate(TMP2, base, offset, kNoRegister); | 618 AddImmediate(TMP2, base, offset, kNoPP); |
| 619 ldr(dest, Address(TMP2), sz); | 619 ldr(dest, Address(TMP2), sz); |
| 620 } | 620 } |
| 621 } | 621 } |
| 622 | 622 |
| 623 | 623 |
| 624 void Assembler::StoreToOffset( | 624 void Assembler::StoreToOffset( |
| 625 Register src, Register base, int32_t offset, OperandSize sz) { | 625 Register src, Register base, int32_t offset, OperandSize sz) { |
| 626 ASSERT(src != TMP2); | 626 ASSERT(src != TMP2); |
| 627 ASSERT(base != TMP2); | 627 ASSERT(base != TMP2); |
| 628 if (Address::CanHoldOffset(offset)) { | 628 if (Address::CanHoldOffset(offset, Address::Offset, sz)) { |
| 629 str(src, Address(base, offset), sz); | 629 str(src, Address(base, offset, Address::Offset, sz), sz); |
| 630 } else { | 630 } else { |
| 631 // Since offset is 32-bits, it won't be loaded from the pool. | 631 // Since offset is 32-bits, it won't be loaded from the pool. |
| 632 AddImmediate(TMP2, base, offset, kNoRegister); | 632 AddImmediate(TMP2, base, offset, kNoPP); |
| 633 str(src, Address(TMP2), sz); | 633 str(src, Address(TMP2), sz); |
| 634 } | 634 } |
| 635 } | 635 } |
| 636 | 636 |
| 637 | 637 |
| 638 // Store into object. | 638 // Store into object. |
| 639 // Preserves object and value registers. | 639 // Preserves object and value registers. |
| 640 void Assembler::StoreIntoObjectFilterNoSmi(Register object, | 640 void Assembler::StoreIntoObjectFilterNoSmi(Register object, |
| 641 Register value, | 641 Register value, |
| 642 Label* no_update) { | 642 Label* no_update) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 intptr_t class_id) { | 754 intptr_t class_id) { |
| 755 LoadClassId(TMP, object); | 755 LoadClassId(TMP, object); |
| 756 CompareImmediate(TMP, class_id, PP); | 756 CompareImmediate(TMP, class_id, PP); |
| 757 } | 757 } |
| 758 | 758 |
| 759 | 759 |
| 760 // Frame entry and exit. | 760 // Frame entry and exit. |
| 761 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 761 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { |
| 762 // Reserve space for arguments and align frame before entering | 762 // Reserve space for arguments and align frame before entering |
| 763 // the C++ world. | 763 // the C++ world. |
| 764 AddImmediate(SP, SP, -frame_space, kNoRegister); | 764 AddImmediate(SP, SP, -frame_space, kNoPP); |
| 765 if (OS::ActivationFrameAlignment() > 1) { | 765 if (OS::ActivationFrameAlignment() > 1) { |
| 766 mov(TMP, SP); // SP can't be register operand of andi. | 766 mov(TMP, SP); // SP can't be register operand of andi. |
| 767 andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1)); | 767 andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1)); |
| 768 mov(SP, TMP); | 768 mov(SP, TMP); |
| 769 } | 769 } |
| 770 } | 770 } |
| 771 | 771 |
| 772 | 772 |
| 773 void Assembler::EnterFrame(intptr_t frame_size) { | 773 void Assembler::EnterFrame(intptr_t frame_size) { |
| 774 Push(LR); | 774 Push(LR); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 | 806 |
| 807 | 807 |
| 808 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp) { | 808 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp) { |
| 809 // Setup the frame. | 809 // Setup the frame. |
| 810 adr(TMP, -CodeSize()); // TMP gets PC marker. | 810 adr(TMP, -CodeSize()); // TMP gets PC marker. |
| 811 EnterFrame(0); | 811 EnterFrame(0); |
| 812 Push(TMP); // Save PC Marker. | 812 Push(TMP); // Save PC Marker. |
| 813 TagAndPushPP(); // Save PP. | 813 TagAndPushPP(); // Save PP. |
| 814 | 814 |
| 815 // Load the pool pointer. | 815 // Load the pool pointer. |
| 816 if (new_pp == kNoRegister) { | 816 if (new_pp == kNoPP) { |
| 817 LoadPoolPointer(PP); | 817 LoadPoolPointer(PP); |
| 818 } else { | 818 } else { |
| 819 mov(PP, new_pp); | 819 mov(PP, new_pp); |
| 820 } | 820 } |
| 821 | 821 |
| 822 // Reserve space. | 822 // Reserve space. |
| 823 if (frame_size > 0) { | 823 if (frame_size > 0) { |
| 824 AddImmediate(SP, SP, -frame_size, PP); | 824 AddImmediate(SP, SP, -frame_size, PP); |
| 825 } | 825 } |
| 826 } | 826 } |
| 827 | 827 |
| 828 | 828 |
| 829 // On entry to a function compiled for OSR, the caller's frame pointer, the | 829 // On entry to a function compiled for OSR, the caller's frame pointer, the |
| 830 // stack locals, and any copied parameters are already in place. The frame | 830 // stack locals, and any copied parameters are already in place. The frame |
| 831 // pointer is already set up. The PC marker is not correct for the | 831 // pointer is already set up. The PC marker is not correct for the |
| 832 // optimized function and there may be extra space for spill slots to | 832 // optimized function and there may be extra space for spill slots to |
| 833 // allocate. We must also set up the pool pointer for the function. | 833 // allocate. We must also set up the pool pointer for the function. |
| 834 void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) { | 834 void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) { |
| 835 const intptr_t offset = CodeSize(); | 835 const intptr_t offset = CodeSize(); |
| 836 | 836 |
| 837 Comment("EnterOsrFrame"); | 837 Comment("EnterOsrFrame"); |
| 838 adr(TMP, -CodeSize()); | 838 adr(TMP, -CodeSize()); |
| 839 | 839 |
| 840 AddImmediate(TMP, TMP, -offset, kNoRegister); | 840 AddImmediate(TMP, TMP, -offset, kNoPP); |
| 841 StoreToOffset(TMP, FP, kPcMarkerSlotFromFp * kWordSize); | 841 StoreToOffset(TMP, FP, kPcMarkerSlotFromFp * kWordSize); |
| 842 | 842 |
| 843 // Setup pool pointer for this dart function. | 843 // Setup pool pointer for this dart function. |
| 844 if (new_pp == kNoRegister) { | 844 if (new_pp == kNoPP) { |
| 845 LoadPoolPointer(PP); | 845 LoadPoolPointer(PP); |
| 846 } else { | 846 } else { |
| 847 mov(PP, new_pp); | 847 mov(PP, new_pp); |
| 848 } | 848 } |
| 849 | 849 |
| 850 if (extra_size > 0) { | 850 if (extra_size > 0) { |
| 851 AddImmediate(SP, SP, -extra_size, PP); | 851 AddImmediate(SP, SP, -extra_size, PP); |
| 852 } | 852 } |
| 853 } | 853 } |
| 854 | 854 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 void Assembler::LeaveStubFrame() { | 916 void Assembler::LeaveStubFrame() { |
| 917 // Restore and untag PP. | 917 // Restore and untag PP. |
| 918 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); | 918 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); |
| 919 sub(PP, PP, Operand(kHeapObjectTag)); | 919 sub(PP, PP, Operand(kHeapObjectTag)); |
| 920 LeaveFrame(); | 920 LeaveFrame(); |
| 921 } | 921 } |
| 922 | 922 |
| 923 | 923 |
| 924 void Assembler::UpdateAllocationStats(intptr_t cid, | 924 void Assembler::UpdateAllocationStats(intptr_t cid, |
| 925 Register temp_reg, | 925 Register temp_reg, |
| 926 Register pp, |
| 926 Heap::Space space) { | 927 Heap::Space space) { |
| 927 ASSERT(temp_reg != kNoRegister); | 928 ASSERT(temp_reg != kNoRegister); |
| 928 ASSERT(temp_reg != TMP); | 929 ASSERT(temp_reg != TMP); |
| 929 ASSERT(cid > 0); | 930 ASSERT(cid > 0); |
| 930 Isolate* isolate = Isolate::Current(); | 931 Isolate* isolate = Isolate::Current(); |
| 931 ClassTable* class_table = isolate->class_table(); | 932 ClassTable* class_table = isolate->class_table(); |
| 932 if (cid < kNumPredefinedCids) { | 933 if (cid < kNumPredefinedCids) { |
| 933 const uword class_heap_stats_table_address = | 934 const uword class_heap_stats_table_address = |
| 934 class_table->PredefinedClassHeapStatsTableAddress(); | 935 class_table->PredefinedClassHeapStatsTableAddress(); |
| 935 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 936 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 936 const uword count_field_offset = (space == Heap::kNew) ? | 937 const uword count_field_offset = (space == Heap::kNew) ? |
| 937 ClassHeapStats::allocated_since_gc_new_space_offset() : | 938 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 938 ClassHeapStats::allocated_since_gc_old_space_offset(); | 939 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 939 LoadImmediate(temp_reg, class_heap_stats_table_address + class_offset, PP); | 940 LoadImmediate(temp_reg, class_heap_stats_table_address + class_offset, pp); |
| 940 const Address& count_address = Address(temp_reg, count_field_offset); | 941 const Address& count_address = Address(temp_reg, count_field_offset); |
| 941 ldr(TMP, count_address); | 942 ldr(TMP, count_address); |
| 942 AddImmediate(TMP, TMP, 1, PP); | 943 AddImmediate(TMP, TMP, 1, pp); |
| 943 str(TMP, count_address); | 944 str(TMP, count_address); |
| 944 } else { | 945 } else { |
| 945 ASSERT(temp_reg != kNoRegister); | 946 ASSERT(temp_reg != kNoRegister); |
| 946 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 947 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 947 const uword count_field_offset = (space == Heap::kNew) ? | 948 const uword count_field_offset = (space == Heap::kNew) ? |
| 948 ClassHeapStats::allocated_since_gc_new_space_offset() : | 949 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 949 ClassHeapStats::allocated_since_gc_old_space_offset(); | 950 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 950 LoadImmediate(temp_reg, class_table->ClassStatsTableAddress(), PP); | 951 LoadImmediate(temp_reg, class_table->ClassStatsTableAddress(), pp); |
| 951 ldr(temp_reg, Address(temp_reg)); | 952 ldr(temp_reg, Address(temp_reg)); |
| 952 AddImmediate(temp_reg, temp_reg, class_offset, PP); | 953 AddImmediate(temp_reg, temp_reg, class_offset, pp); |
| 953 ldr(TMP, Address(temp_reg, count_field_offset)); | 954 ldr(TMP, Address(temp_reg, count_field_offset)); |
| 954 AddImmediate(TMP, TMP, 1, PP); | 955 AddImmediate(TMP, TMP, 1, pp); |
| 955 str(TMP, Address(temp_reg, count_field_offset)); | 956 str(TMP, Address(temp_reg, count_field_offset)); |
| 956 } | 957 } |
| 957 } | 958 } |
| 958 | 959 |
| 959 } // namespace dart | 960 } // namespace dart |
| 960 | 961 |
| 961 #endif // defined TARGET_ARCH_ARM64 | 962 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |