Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1143)

Side by Side Diff: runtime/vm/assembler_arm.cc

Issue 1343373003: Revert "VM: New calling convention for generated code." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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" // NOLINT 5 #include "vm/globals.h" // NOLINT
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 1527
1528 1528
1529 intptr_t Assembler::FindImmediate(int32_t imm) { 1529 intptr_t Assembler::FindImmediate(int32_t imm) {
1530 return object_pool_wrapper_.FindImmediate(imm); 1530 return object_pool_wrapper_.FindImmediate(imm);
1531 } 1531 }
1532 1532
1533 1533
1534 // Uses a code sequence that can easily be decoded. 1534 // Uses a code sequence that can easily be decoded.
1535 void Assembler::LoadWordFromPoolOffset(Register rd, 1535 void Assembler::LoadWordFromPoolOffset(Register rd,
1536 int32_t offset, 1536 int32_t offset,
1537 Register pp,
1538 Condition cond) { 1537 Condition cond) {
1539 ASSERT((pp != PP) || constant_pool_allowed()); 1538 ASSERT(constant_pool_allowed());
1540 ASSERT(rd != pp); 1539 ASSERT(rd != PP);
1541 int32_t offset_mask = 0; 1540 int32_t offset_mask = 0;
1542 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { 1541 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) {
1543 ldr(rd, Address(pp, offset), cond); 1542 ldr(rd, Address(PP, offset), cond);
1544 } else { 1543 } else {
1545 int32_t offset_hi = offset & ~offset_mask; // signed 1544 int32_t offset_hi = offset & ~offset_mask; // signed
1546 uint32_t offset_lo = offset & offset_mask; // unsigned 1545 uint32_t offset_lo = offset & offset_mask; // unsigned
1547 // Inline a simplified version of AddImmediate(rd, pp, offset_hi). 1546 // Inline a simplified version of AddImmediate(rd, PP, offset_hi).
1548 Operand o; 1547 Operand o;
1549 if (Operand::CanHold(offset_hi, &o)) { 1548 if (Operand::CanHold(offset_hi, &o)) {
1550 add(rd, pp, o, cond); 1549 add(rd, PP, o, cond);
1551 } else { 1550 } else {
1552 LoadImmediate(rd, offset_hi, cond); 1551 LoadImmediate(rd, offset_hi, cond);
1553 add(rd, pp, Operand(rd), cond); 1552 add(rd, PP, Operand(rd), cond);
1554 } 1553 }
1555 ldr(rd, Address(rd, offset_lo), cond); 1554 ldr(rd, Address(rd, offset_lo), cond);
1556 } 1555 }
1557 } 1556 }
1558 1557
1559 void Assembler::CheckCodePointer() {
1560 #ifdef DEBUG
1561 Label cid_ok, instructions_ok;
1562 Push(R0);
1563 Push(IP);
1564 CompareClassId(CODE_REG, kCodeCid, R0);
1565 b(&cid_ok, EQ);
1566 bkpt(0);
1567 Bind(&cid_ok);
1568 1558
1569 const intptr_t offset = CodeSize() + Instr::kPCReadOffset + 1559 void Assembler::LoadPoolPointer() {
1570 Instructions::HeaderSize() - kHeapObjectTag; 1560 const intptr_t object_pool_pc_dist =
1571 mov(R0, Operand(PC)); 1561 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1572 AddImmediate(R0, R0, -offset); 1562 CodeSize() + Instr::kPCReadOffset;
1573 ldr(IP, FieldAddress(CODE_REG, Code::saved_instructions_offset())); 1563 LoadFromOffset(kWord, PP, PC, -object_pool_pc_dist);
1574 cmp(R0, Operand(IP)); 1564 set_constant_pool_allowed(true);
1575 b(&instructions_ok, EQ);
1576 bkpt(1);
1577 Bind(&instructions_ok);
1578 Pop(IP);
1579 Pop(R0);
1580 #endif
1581 } 1565 }
1582 1566
1583 1567
1584 void Assembler::RestoreCodePointer() {
1585 ldr(CODE_REG, Address(FP, kPcMarkerSlotFromFp * kWordSize));
1586 CheckCodePointer();
1587 }
1588
1589
1590 void Assembler::LoadPoolPointer(Register reg) {
1591 // Load new pool pointer.
1592 CheckCodePointer();
1593 ldr(reg, FieldAddress(CODE_REG, Code::object_pool_offset()));
1594 set_constant_pool_allowed(reg == PP);
1595 }
1596
1597
1598 void Assembler::LoadIsolate(Register rd) { 1568 void Assembler::LoadIsolate(Register rd) {
1599 ldr(rd, Address(THR, Thread::isolate_offset())); 1569 ldr(rd, Address(THR, Thread::isolate_offset()));
1600 } 1570 }
1601 1571
1602 1572
1603 void Assembler::LoadObjectHelper(Register rd, 1573 void Assembler::LoadObjectHelper(Register rd,
1604 const Object& object, 1574 const Object& object,
1605 Condition cond, 1575 Condition cond,
1606 bool is_unique, 1576 bool is_unique) {
1607 Register pp) {
1608 // Load common VM constants from the thread. This works also in places where 1577 // Load common VM constants from the thread. This works also in places where
1609 // no constant pool is set up (e.g. intrinsic code). 1578 // no constant pool is set up (e.g. intrinsic code).
1610 if (Thread::CanLoadFromThread(object)) { 1579 if (Thread::CanLoadFromThread(object)) {
1611 ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond); 1580 ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond);
1612 return; 1581 return;
1613 } 1582 }
1614 // Smis and VM heap objects are never relocated; do not use object pool. 1583 // Smis and VM heap objects are never relocated; do not use object pool.
1615 if (object.IsSmi()) { 1584 if (object.IsSmi()) {
1616 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); 1585 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond);
1617 } else if (object.InVMHeap() || !constant_pool_allowed()) { 1586 } else if (object.InVMHeap() || !constant_pool_allowed()) {
1618 ASSERT(FLAG_allow_absolute_addresses); 1587 ASSERT(FLAG_allow_absolute_addresses);
1619 // Make sure that class CallPattern is able to decode this load immediate. 1588 // Make sure that class CallPattern is able to decode this load immediate.
1620 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); 1589 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw());
1621 LoadImmediate(rd, object_raw, cond); 1590 LoadImmediate(rd, object_raw, cond);
1622 } else { 1591 } else {
1623 // Make sure that class CallPattern is able to decode this load from the 1592 // Make sure that class CallPattern is able to decode this load from the
1624 // object pool. 1593 // object pool.
1625 const int32_t offset = ObjectPool::element_offset( 1594 const int32_t offset = ObjectPool::element_offset(
1626 is_unique ? object_pool_wrapper_.AddObject(object) 1595 is_unique ? object_pool_wrapper_.AddObject(object)
1627 : object_pool_wrapper_.FindObject(object)); 1596 : object_pool_wrapper_.FindObject(object));
1628 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond); 1597 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
1629 } 1598 }
1630 } 1599 }
1631 1600
1632 1601
1633 void Assembler::LoadObject(Register rd, const Object& object, Condition cond) { 1602 void Assembler::LoadObject(Register rd, const Object& object, Condition cond) {
1634 LoadObjectHelper(rd, object, cond, /* is_unique = */ false, PP); 1603 LoadObjectHelper(rd, object, cond, false);
1635 } 1604 }
1636 1605
1637 1606
1638 void Assembler::LoadUniqueObject(Register rd, 1607 void Assembler::LoadUniqueObject(Register rd,
1639 const Object& object, 1608 const Object& object,
1640 Condition cond) { 1609 Condition cond) {
1641 LoadObjectHelper(rd, object, cond, /* is_unique = */ true, PP); 1610 LoadObjectHelper(rd, object, cond, true);
1642 } 1611 }
1643 1612
1644 1613
1645 void Assembler::LoadExternalLabel(Register rd, 1614 void Assembler::LoadExternalLabel(Register rd,
1646 const ExternalLabel* label, 1615 const ExternalLabel* label,
1647 Patchability patchable, 1616 Patchability patchable,
1648 Condition cond) { 1617 Condition cond) {
1649 const int32_t offset = ObjectPool::element_offset( 1618 const int32_t offset = ObjectPool::element_offset(
1650 object_pool_wrapper_.FindExternalLabel(label, patchable)); 1619 object_pool_wrapper_.FindExternalLabel(label, patchable));
1651 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond); 1620 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
1652 } 1621 }
1653 1622
1654 1623
1655 void Assembler::LoadFunctionFromCalleePool(Register dst,
1656 const Function& function,
1657 Register new_pp) {
1658 const int32_t offset =
1659 ObjectPool::element_offset(object_pool_wrapper_.FindObject(function));
1660 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag, new_pp, AL);
1661 }
1662
1663
1664 void Assembler::LoadNativeEntry(Register rd, 1624 void Assembler::LoadNativeEntry(Register rd,
1665 const ExternalLabel* label, 1625 const ExternalLabel* label,
1666 Patchability patchable, 1626 Patchability patchable,
1667 Condition cond) { 1627 Condition cond) {
1668 const int32_t offset = ObjectPool::element_offset( 1628 const int32_t offset = ObjectPool::element_offset(
1669 object_pool_wrapper_.FindNativeEntry(label, patchable)); 1629 object_pool_wrapper_.FindNativeEntry(label, patchable));
1670 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond); 1630 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
1671 } 1631 }
1672 1632
1673 1633
1674 void Assembler::PushObject(const Object& object) { 1634 void Assembler::PushObject(const Object& object) {
1675 LoadObject(IP, object); 1635 LoadObject(IP, object);
1676 Push(IP); 1636 Push(IP);
1677 } 1637 }
1678 1638
1679 1639
1680 void Assembler::CompareObject(Register rn, const Object& object) { 1640 void Assembler::CompareObject(Register rn, const Object& object) {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1857 bool can_value_be_smi) { 1817 bool can_value_be_smi) {
1858 ASSERT(object != value); 1818 ASSERT(object != value);
1859 VerifiedWrite(dest, value, kHeapObjectOrSmi); 1819 VerifiedWrite(dest, value, kHeapObjectOrSmi);
1860 Label done; 1820 Label done;
1861 if (can_value_be_smi) { 1821 if (can_value_be_smi) {
1862 StoreIntoObjectFilter(object, value, &done); 1822 StoreIntoObjectFilter(object, value, &done);
1863 } else { 1823 } else {
1864 StoreIntoObjectFilterNoSmi(object, value, &done); 1824 StoreIntoObjectFilterNoSmi(object, value, &done);
1865 } 1825 }
1866 // A store buffer update is required. 1826 // A store buffer update is required.
1867 RegList regs = (1 << CODE_REG) | (1 << LR); 1827 RegList regs = (1 << LR);
1868 if (value != R0) { 1828 if (value != R0) {
1869 regs |= (1 << R0); // Preserve R0. 1829 regs |= (1 << R0); // Preserve R0.
1870 } 1830 }
1871 PushList(regs); 1831 PushList(regs);
1872 if (object != R0) { 1832 if (object != R0) {
1873 mov(R0, Operand(object)); 1833 mov(R0, Operand(object));
1874 } 1834 }
1875 ldr(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
1876 ldr(LR, Address(THR, Thread::update_store_buffer_entry_point_offset())); 1835 ldr(LR, Address(THR, Thread::update_store_buffer_entry_point_offset()));
1877 blx(LR); 1836 blx(LR);
1878 PopList(regs); 1837 PopList(regs);
1879 Bind(&done); 1838 Bind(&done);
1880 } 1839 }
1881 1840
1882 1841
1883 void Assembler::StoreIntoObjectOffset(Register object, 1842 void Assembler::StoreIntoObjectOffset(Register object,
1884 int32_t offset, 1843 int32_t offset,
1885 Register value, 1844 Register value,
(...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after
2721 void Assembler::Vdivqs(QRegister qd, QRegister qn, QRegister qm) { 2680 void Assembler::Vdivqs(QRegister qd, QRegister qn, QRegister qm) {
2722 ASSERT(qd != QTMP); 2681 ASSERT(qd != QTMP);
2723 ASSERT(qn != QTMP); 2682 ASSERT(qn != QTMP);
2724 ASSERT(qm != QTMP); 2683 ASSERT(qm != QTMP);
2725 2684
2726 Vreciprocalqs(qd, qm); 2685 Vreciprocalqs(qd, qm);
2727 vmulqs(qd, qn, qd); 2686 vmulqs(qd, qn, qd);
2728 } 2687 }
2729 2688
2730 2689
2731 void Assembler::Branch(const StubEntry& stub_entry, 2690 void Assembler::Branch(const StubEntry& stub_entry, Condition cond) {
2732 Patchability patchable, 2691 // Address is never patched.
2733 Register pp, 2692 LoadImmediate(IP, stub_entry.label().address(), cond);
2734 Condition cond) {
2735 const Code& target_code = Code::Handle(stub_entry.code());
2736 const int32_t offset = ObjectPool::element_offset(
2737 object_pool_wrapper_.FindObject(target_code, patchable));
2738 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp, cond);
2739 ldr(IP, FieldAddress(CODE_REG, Code::entry_point_offset()), cond);
2740 bx(IP, cond); 2693 bx(IP, cond);
2741 } 2694 }
2742 2695
2743 2696
2744 void Assembler::BranchLink(const Code& target, Patchability patchable) { 2697 void Assembler::BranchPatchable(const StubEntry& stub_entry) {
2745 // Make sure that class CallPattern is able to patch the label referred 2698 // Use a fixed size code sequence, since a function prologue may be patched
2746 // to by this code sequence. 2699 // with this branch sequence.
2747 // For added code robustness, use 'blx lr' in a patchable sequence and 2700 // Contrarily to BranchLinkPatchable, BranchPatchable requires an instruction
2748 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). 2701 // cache flush upon patching.
2749 const int32_t offset = ObjectPool::element_offset( 2702 LoadPatchableImmediate(IP, stub_entry.label().address());
2750 object_pool_wrapper_.FindObject(target, patchable)); 2703 bx(IP);
2751 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, PP, AL);
2752 ldr(LR, FieldAddress(CODE_REG, Code::entry_point_offset()));
2753 blx(LR); // Use blx instruction so that the return branch prediction works.
2754 }
2755
2756
2757 void Assembler::BranchLink(const StubEntry& stub_entry,
2758 Patchability patchable) {
2759 const Code& code = Code::Handle(stub_entry.code());
2760 BranchLink(code, patchable);
2761 }
2762
2763
2764 void Assembler::BranchLinkPatchable(const Code& target) {
2765 BranchLink(target, kPatchable);
2766 } 2704 }
2767 2705
2768 2706
2769 void Assembler::BranchLink(const ExternalLabel* label) { 2707 void Assembler::BranchLink(const ExternalLabel* label) {
2770 LoadImmediate(LR, label->address()); // Target address is never patched. 2708 LoadImmediate(LR, label->address()); // Target address is never patched.
2771 blx(LR); // Use blx instruction so that the return branch prediction works. 2709 blx(LR); // Use blx instruction so that the return branch prediction works.
2772 } 2710 }
2773 2711
2774 2712
2775 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) { 2713 void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) {
2776 BranchLinkPatchable(Code::Handle(stub_entry.code())); 2714 // Make sure that class CallPattern is able to patch the label referred
2715 // to by this code sequence.
2716 // For added code robustness, use 'blx lr' in a patchable sequence and
2717 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
2718 const int32_t offset = ObjectPool::element_offset(
2719 object_pool_wrapper_.FindExternalLabel(label, patchable));
2720 LoadWordFromPoolOffset(LR, offset - kHeapObjectTag, AL);
2721 blx(LR); // Use blx instruction so that the return branch prediction works.
2777 } 2722 }
2778 2723
2779 2724
2725 void Assembler::BranchLink(const StubEntry& stub_entry,
2726 Patchability patchable) {
2727 BranchLink(&stub_entry.label(), patchable);
2728 }
2729
2730
2731 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
2732 BranchLink(&stub_entry.label(), kPatchable);
2733 }
2734
2735
2780 void Assembler::BranchLinkOffset(Register base, int32_t offset) { 2736 void Assembler::BranchLinkOffset(Register base, int32_t offset) {
2781 ASSERT(base != PC); 2737 ASSERT(base != PC);
2782 ASSERT(base != IP); 2738 ASSERT(base != IP);
2783 LoadFromOffset(kWord, IP, base, offset); 2739 LoadFromOffset(kWord, IP, base, offset);
2784 blx(IP); // Use blx instruction so that the return branch prediction works. 2740 blx(IP); // Use blx instruction so that the return branch prediction works.
2785 } 2741 }
2786 2742
2787 2743
2788 void Assembler::LoadPatchableImmediate( 2744 void Assembler::LoadPatchableImmediate(
2789 Register rd, int32_t value, Condition cond) { 2745 Register rd, int32_t value, Condition cond) {
(...skipping 17 matching lines...) Expand all
2807 } 2763 }
2808 } 2764 }
2809 2765
2810 2766
2811 void Assembler::LoadDecodableImmediate( 2767 void Assembler::LoadDecodableImmediate(
2812 Register rd, int32_t value, Condition cond) { 2768 Register rd, int32_t value, Condition cond) {
2813 const ARMVersion version = TargetCPUFeatures::arm_version(); 2769 const ARMVersion version = TargetCPUFeatures::arm_version();
2814 if ((version == ARMv5TE) || (version == ARMv6)) { 2770 if ((version == ARMv5TE) || (version == ARMv6)) {
2815 if (constant_pool_allowed()) { 2771 if (constant_pool_allowed()) {
2816 const int32_t offset = Array::element_offset(FindImmediate(value)); 2772 const int32_t offset = Array::element_offset(FindImmediate(value));
2817 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond); 2773 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
2818 } else { 2774 } else {
2819 LoadPatchableImmediate(rd, value, cond); 2775 LoadPatchableImmediate(rd, value, cond);
2820 } 2776 }
2821 } else { 2777 } else {
2822 ASSERT(version == ARMv7); 2778 ASSERT(version == ARMv7);
2823 movw(rd, Utils::Low16Bits(value), cond); 2779 movw(rd, Utils::Low16Bits(value), cond);
2824 const uint16_t value_high = Utils::High16Bits(value); 2780 const uint16_t value_high = Utils::High16Bits(value);
2825 if (value_high != 0) { 2781 if (value_high != 0) {
2826 movt(rd, value_high, cond); 2782 movt(rd, value_high, cond);
2827 } 2783 }
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
3342 } 3298 }
3343 3299
3344 3300
3345 void Assembler::CallRuntime(const RuntimeEntry& entry, 3301 void Assembler::CallRuntime(const RuntimeEntry& entry,
3346 intptr_t argument_count) { 3302 intptr_t argument_count) {
3347 entry.Call(this, argument_count); 3303 entry.Call(this, argument_count);
3348 } 3304 }
3349 3305
3350 3306
3351 void Assembler::EnterDartFrame(intptr_t frame_size) { 3307 void Assembler::EnterDartFrame(intptr_t frame_size) {
3352 CheckCodePointer();
3353 ASSERT(!constant_pool_allowed()); 3308 ASSERT(!constant_pool_allowed());
3309 const intptr_t offset = CodeSize();
3354 3310
3355 // Registers are pushed in descending order: R9 | R10 | R11 | R14. 3311 // Save PC in frame for fast identification of corresponding code.
3356 EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << LR), 0); 3312 // Note that callee-saved registers can be added to the register list.
3313 EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0);
3314
3315 if (offset != 0) {
3316 // Adjust saved PC for any intrinsic code that could have been generated
3317 // before a frame is created. Use PP as temp register.
3318 ldr(PP, Address(FP, 2 * kWordSize));
3319 AddImmediate(PP, PP, -offset);
3320 str(PP, Address(FP, 2 * kWordSize));
3321 }
3357 3322
3358 // Setup pool pointer for this dart function. 3323 // Setup pool pointer for this dart function.
3359 LoadPoolPointer(); 3324 LoadPoolPointer();
3360 3325
3361 // Reserve space for locals. 3326 // Reserve space for locals.
3362 AddImmediate(SP, -frame_size); 3327 AddImmediate(SP, -frame_size);
3363 } 3328 }
3364 3329
3365 3330
3366 // On entry to a function compiled for OSR, the caller's frame pointer, the 3331 // On entry to a function compiled for OSR, the caller's frame pointer, the
3367 // stack locals, and any copied parameters are already in place. The frame 3332 // stack locals, and any copied parameters are already in place. The frame
3368 // pointer is already set up. The PC marker is not correct for the 3333 // pointer is already set up. The PC marker is not correct for the
3369 // optimized function and there may be extra space for spill slots to 3334 // optimized function and there may be extra space for spill slots to
3370 // allocate. We must also set up the pool pointer for the function. 3335 // allocate. We must also set up the pool pointer for the function.
3371 void Assembler::EnterOsrFrame(intptr_t extra_size) { 3336 void Assembler::EnterOsrFrame(intptr_t extra_size) {
3372 ASSERT(!constant_pool_allowed()); 3337 ASSERT(!constant_pool_allowed());
3338 // mov(IP, Operand(PC)) loads PC + Instr::kPCReadOffset (8). This may be
3339 // different from EntryPointToPcMarkerOffset().
3340 const intptr_t offset =
3341 CodeSize() + Instr::kPCReadOffset - EntryPointToPcMarkerOffset();
3342
3373 Comment("EnterOsrFrame"); 3343 Comment("EnterOsrFrame");
3374 RestoreCodePointer(); 3344 mov(IP, Operand(PC));
3345
3346 AddImmediate(IP, -offset);
3347 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize));
3348
3349 // Setup pool pointer for this dart function.
3375 LoadPoolPointer(); 3350 LoadPoolPointer();
3376 3351
3377 AddImmediate(SP, -extra_size); 3352 AddImmediate(SP, -extra_size);
3378 } 3353 }
3379 3354
3380 3355
3381 void Assembler::LeaveDartFrame(RestorePP restore_pp) { 3356 void Assembler::LeaveDartFrame() {
3382 if (restore_pp == kRestoreCallerPP) { 3357 set_constant_pool_allowed(false);
3383 ldr(PP, Address(FP, kSavedCallerPpSlotFromFp * kWordSize)); 3358 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR));
3384 set_constant_pool_allowed(false); 3359 // Adjust SP for PC pushed in EnterDartFrame.
3385 } 3360 AddImmediate(SP, kWordSize);
3386 Drop(2); // Drop saved PP, PC marker.
3387 LeaveFrame((1 << FP) | (1 << LR));
3388 } 3361 }
3389 3362
3390 3363
3391 void Assembler::EnterStubFrame() { 3364 void Assembler::EnterStubFrame() {
3392 EnterDartFrame(0); 3365 set_constant_pool_allowed(false);
3366 // Push 0 as saved PC for stub frames.
3367 mov(IP, Operand(LR));
3368 mov(LR, Operand(0));
3369 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR);
3370 EnterFrame(regs, 0);
3371 // Setup pool pointer for this stub.
3372 LoadPoolPointer();
3393 } 3373 }
3394 3374
3395 3375
3396 void Assembler::LeaveStubFrame() { 3376 void Assembler::LeaveStubFrame() {
3397 LeaveDartFrame(); 3377 LeaveDartFrame();
3398 } 3378 }
3399 3379
3400 3380
3401 void Assembler::LoadAllocationStatsAddress(Register dest, 3381 void Assembler::LoadAllocationStatsAddress(Register dest,
3402 intptr_t cid, 3382 intptr_t cid,
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
3683 3663
3684 3664
3685 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3665 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3686 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3666 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3687 return fpu_reg_names[reg]; 3667 return fpu_reg_names[reg];
3688 } 3668 }
3689 3669
3690 } // namespace dart 3670 } // namespace dart
3691 3671
3692 #endif // defined TARGET_ARCH_ARM 3672 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698