| OLD | NEW |
| 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" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1667 | 1667 |
| 1668 __ lw(CMPRES1, | 1668 __ lw(CMPRES1, |
| 1669 FieldAddress(value_reg, | 1669 FieldAddress(value_reg, |
| 1670 field().guarded_list_length_in_object_offset())); | 1670 field().guarded_list_length_in_object_offset())); |
| 1671 __ LoadImmediate(TMP, Smi::RawValue(field().guarded_list_length())); | 1671 __ LoadImmediate(TMP, Smi::RawValue(field().guarded_list_length())); |
| 1672 __ bne(CMPRES1, TMP, deopt); | 1672 __ bne(CMPRES1, TMP, deopt); |
| 1673 } | 1673 } |
| 1674 } | 1674 } |
| 1675 | 1675 |
| 1676 | 1676 |
| 1677 class StoreInstanceFieldSlowPath : public SlowPathCode { | 1677 class BoxAllocationSlowPath : public SlowPathCode { |
| 1678 public: | 1678 public: |
| 1679 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, | 1679 BoxAllocationSlowPath(Instruction* instruction, |
| 1680 const Class& cls) | 1680 const Class& cls, |
| 1681 : instruction_(instruction), cls_(cls) { } | 1681 Register result) |
| 1682 : instruction_(instruction), |
| 1683 cls_(cls), |
| 1684 result_(result) { } |
| 1682 | 1685 |
| 1683 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1686 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1684 Isolate* isolate = compiler->isolate(); | 1687 Isolate* isolate = compiler->isolate(); |
| 1685 StubCode* stub_code = isolate->stub_code(); | 1688 StubCode* stub_code = isolate->stub_code(); |
| 1686 | 1689 |
| 1687 __ Comment("StoreInstanceFieldSlowPath"); | 1690 if (Assembler::EmittingComments()) { |
| 1691 __ Comment("%s slow path allocation of %s", |
| 1692 instruction_->DebugName(), |
| 1693 String::Handle(cls_.PrettyName()).ToCString()); |
| 1694 } |
| 1688 __ Bind(entry_label()); | 1695 __ Bind(entry_label()); |
| 1689 const Code& stub = | 1696 const Code& stub = |
| 1690 Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); | 1697 Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); |
| 1691 const ExternalLabel label(stub.EntryPoint()); | 1698 const ExternalLabel label(stub.EntryPoint()); |
| 1692 | 1699 |
| 1693 LocationSummary* locs = instruction_->locs(); | 1700 LocationSummary* locs = instruction_->locs(); |
| 1694 locs->live_registers()->Remove(locs->temp(0)); | 1701 locs->live_registers()->Remove(Location::RegisterLocation(result_)); |
| 1695 | 1702 |
| 1696 compiler->SaveLiveRegisters(locs); | 1703 compiler->SaveLiveRegisters(locs); |
| 1697 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 1704 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| 1698 &label, | 1705 &label, |
| 1699 RawPcDescriptors::kOther, | 1706 RawPcDescriptors::kOther, |
| 1700 locs); | 1707 locs); |
| 1701 __ mov(locs->temp(0).reg(), V0); | 1708 if (result_ != V0) { |
| 1709 __ mov(result_, V0); |
| 1710 } |
| 1702 compiler->RestoreLiveRegisters(locs); | 1711 compiler->RestoreLiveRegisters(locs); |
| 1703 | 1712 |
| 1704 __ b(exit_label()); | 1713 __ b(exit_label()); |
| 1705 } | 1714 } |
| 1706 | 1715 |
| 1716 static void Allocate(FlowGraphCompiler* compiler, |
| 1717 Instruction* instruction, |
| 1718 const Class& cls, |
| 1719 Register result, |
| 1720 Register temp) { |
| 1721 BoxAllocationSlowPath* slow_path = |
| 1722 new BoxAllocationSlowPath(instruction, cls, result); |
| 1723 compiler->AddSlowPathCode(slow_path); |
| 1724 |
| 1725 __ TryAllocate(cls, |
| 1726 slow_path->entry_label(), |
| 1727 result, |
| 1728 temp); |
| 1729 __ Bind(slow_path->exit_label()); |
| 1730 } |
| 1731 |
| 1707 private: | 1732 private: |
| 1708 StoreInstanceFieldInstr* instruction_; | 1733 Instruction* instruction_; |
| 1709 const Class& cls_; | 1734 const Class& cls_; |
| 1735 Register result_; |
| 1710 }; | 1736 }; |
| 1711 | 1737 |
| 1712 | 1738 |
| 1713 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, | 1739 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, |
| 1714 bool opt) const { | 1740 bool opt) const { |
| 1715 const intptr_t kNumInputs = 2; | 1741 const intptr_t kNumInputs = 2; |
| 1716 const intptr_t kNumTemps = | 1742 const intptr_t kNumTemps = |
| 1717 (IsUnboxedStore() && opt) ? 2 : | 1743 (IsUnboxedStore() && opt) ? 2 : |
| 1718 ((IsPotentialUnboxedStore()) ? 3 : 0); | 1744 ((IsPotentialUnboxedStore()) ? 3 : 0); |
| 1719 LocationSummary* summary = new(isolate) LocationSummary( | 1745 LocationSummary* summary = new(isolate) LocationSummary( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1738 : Location::FpuRegisterLocation(D1)); | 1764 : Location::FpuRegisterLocation(D1)); |
| 1739 } else { | 1765 } else { |
| 1740 summary->set_in(1, ShouldEmitStoreBarrier() | 1766 summary->set_in(1, ShouldEmitStoreBarrier() |
| 1741 ? Location::WritableRegister() | 1767 ? Location::WritableRegister() |
| 1742 : Location::RegisterOrConstant(value())); | 1768 : Location::RegisterOrConstant(value())); |
| 1743 } | 1769 } |
| 1744 return summary; | 1770 return summary; |
| 1745 } | 1771 } |
| 1746 | 1772 |
| 1747 | 1773 |
| 1774 static void EnsureMutableBox(FlowGraphCompiler* compiler, |
| 1775 StoreInstanceFieldInstr* instruction, |
| 1776 Register box_reg, |
| 1777 const Class& cls, |
| 1778 Register instance_reg, |
| 1779 intptr_t offset, |
| 1780 Register temp) { |
| 1781 Label done; |
| 1782 __ lw(box_reg, FieldAddress(instance_reg, offset)); |
| 1783 __ BranchNotEqual(box_reg, reinterpret_cast<int32_t>(Object::null()), |
| 1784 &done); |
| 1785 BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp); |
| 1786 __ mov(temp, box_reg); |
| 1787 __ StoreIntoObjectOffset(instance_reg, offset, temp); |
| 1788 __ Bind(&done); |
| 1789 } |
| 1790 |
| 1791 |
| 1748 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1792 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1749 Label skip_store; | 1793 Label skip_store; |
| 1750 | 1794 |
| 1751 Register instance_reg = locs()->in(0).reg(); | 1795 Register instance_reg = locs()->in(0).reg(); |
| 1752 | 1796 |
| 1753 if (IsUnboxedStore() && compiler->is_optimizing()) { | 1797 if (IsUnboxedStore() && compiler->is_optimizing()) { |
| 1754 DRegister value = locs()->in(1).fpu_reg(); | 1798 DRegister value = locs()->in(1).fpu_reg(); |
| 1755 Register temp = locs()->temp(0).reg(); | 1799 Register temp = locs()->temp(0).reg(); |
| 1756 Register temp2 = locs()->temp(1).reg(); | 1800 Register temp2 = locs()->temp(1).reg(); |
| 1757 const intptr_t cid = field().UnboxedFieldCid(); | 1801 const intptr_t cid = field().UnboxedFieldCid(); |
| 1758 | 1802 |
| 1759 if (is_initialization_) { | 1803 if (is_initialization_) { |
| 1760 const Class* cls = NULL; | 1804 const Class* cls = NULL; |
| 1761 switch (cid) { | 1805 switch (cid) { |
| 1762 case kDoubleCid: | 1806 case kDoubleCid: |
| 1763 cls = &compiler->double_class(); | 1807 cls = &compiler->double_class(); |
| 1764 break; | 1808 break; |
| 1765 default: | 1809 default: |
| 1766 UNREACHABLE(); | 1810 UNREACHABLE(); |
| 1767 } | 1811 } |
| 1768 | 1812 |
| 1769 StoreInstanceFieldSlowPath* slow_path = | 1813 BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2); |
| 1770 new StoreInstanceFieldSlowPath(this, *cls); | |
| 1771 compiler->AddSlowPathCode(slow_path); | |
| 1772 | |
| 1773 __ TryAllocate(*cls, | |
| 1774 slow_path->entry_label(), | |
| 1775 temp, | |
| 1776 temp2); | |
| 1777 __ Bind(slow_path->exit_label()); | |
| 1778 __ mov(temp2, temp); | 1814 __ mov(temp2, temp); |
| 1779 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); | 1815 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); |
| 1780 } else { | 1816 } else { |
| 1781 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1817 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
| 1782 } | 1818 } |
| 1783 switch (cid) { | 1819 switch (cid) { |
| 1784 case kDoubleCid: | 1820 case kDoubleCid: |
| 1785 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); | 1821 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1786 break; | 1822 break; |
| 1787 default: | 1823 default: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1814 // Fall through. | 1850 // Fall through. |
| 1815 __ b(&store_pointer); | 1851 __ b(&store_pointer); |
| 1816 | 1852 |
| 1817 if (!compiler->is_optimizing()) { | 1853 if (!compiler->is_optimizing()) { |
| 1818 locs()->live_registers()->Add(locs()->in(0)); | 1854 locs()->live_registers()->Add(locs()->in(0)); |
| 1819 locs()->live_registers()->Add(locs()->in(1)); | 1855 locs()->live_registers()->Add(locs()->in(1)); |
| 1820 } | 1856 } |
| 1821 | 1857 |
| 1822 { | 1858 { |
| 1823 __ Bind(&store_double); | 1859 __ Bind(&store_double); |
| 1824 Label copy_double; | 1860 EnsureMutableBox(compiler, |
| 1825 | 1861 this, |
| 1826 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1862 temp, |
| 1827 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()), | 1863 compiler->double_class(), |
| 1828 ©_double); | 1864 instance_reg, |
| 1829 | 1865 offset_in_bytes_, |
| 1830 StoreInstanceFieldSlowPath* slow_path = | 1866 temp2); |
| 1831 new StoreInstanceFieldSlowPath(this, compiler->double_class()); | |
| 1832 compiler->AddSlowPathCode(slow_path); | |
| 1833 | |
| 1834 __ TryAllocate(compiler->double_class(), | |
| 1835 slow_path->entry_label(), | |
| 1836 temp, | |
| 1837 temp2); | |
| 1838 __ Bind(slow_path->exit_label()); | |
| 1839 __ mov(temp2, temp); | |
| 1840 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); | |
| 1841 | |
| 1842 __ Bind(©_double); | |
| 1843 __ LoadDFromOffset(fpu_temp, | 1867 __ LoadDFromOffset(fpu_temp, |
| 1844 value_reg, | 1868 value_reg, |
| 1845 Double::value_offset() - kHeapObjectTag); | 1869 Double::value_offset() - kHeapObjectTag); |
| 1846 __ StoreDToOffset(fpu_temp, temp, | 1870 __ StoreDToOffset(fpu_temp, temp, |
| 1847 Double::value_offset() - kHeapObjectTag); | 1871 Double::value_offset() - kHeapObjectTag); |
| 1848 __ b(&skip_store); | 1872 __ b(&skip_store); |
| 1849 } | 1873 } |
| 1850 | 1874 |
| 1851 __ Bind(&store_pointer); | 1875 __ Bind(&store_pointer); |
| 1852 } | 1876 } |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2076 StubCode* stub_code = compiler->isolate()->stub_code(); | 2100 StubCode* stub_code = compiler->isolate()->stub_code(); |
| 2077 compiler->GenerateCall(token_pos(), | 2101 compiler->GenerateCall(token_pos(), |
| 2078 &stub_code->AllocateArrayLabel(), | 2102 &stub_code->AllocateArrayLabel(), |
| 2079 RawPcDescriptors::kOther, | 2103 RawPcDescriptors::kOther, |
| 2080 locs()); | 2104 locs()); |
| 2081 __ Bind(&done); | 2105 __ Bind(&done); |
| 2082 ASSERT(locs()->out(0).reg() == kResultReg); | 2106 ASSERT(locs()->out(0).reg() == kResultReg); |
| 2083 } | 2107 } |
| 2084 | 2108 |
| 2085 | 2109 |
| 2086 class BoxDoubleSlowPath : public SlowPathCode { | |
| 2087 public: | |
| 2088 explicit BoxDoubleSlowPath(Instruction* instruction) | |
| 2089 : instruction_(instruction) { } | |
| 2090 | |
| 2091 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2092 __ Comment("BoxDoubleSlowPath"); | |
| 2093 __ Bind(entry_label()); | |
| 2094 Isolate* isolate = compiler->isolate(); | |
| 2095 StubCode* stub_code = isolate->stub_code(); | |
| 2096 const Class& double_class = compiler->double_class(); | |
| 2097 const Code& stub = | |
| 2098 Code::Handle(isolate, | |
| 2099 stub_code->GetAllocationStubForClass(double_class)); | |
| 2100 const ExternalLabel label(stub.EntryPoint()); | |
| 2101 | |
| 2102 LocationSummary* locs = instruction_->locs(); | |
| 2103 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
| 2104 | |
| 2105 compiler->SaveLiveRegisters(locs); | |
| 2106 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
| 2107 &label, | |
| 2108 RawPcDescriptors::kOther, | |
| 2109 locs); | |
| 2110 if (locs->out(0).reg() != V0) { | |
| 2111 __ mov(locs->out(0).reg(), V0); | |
| 2112 } | |
| 2113 compiler->RestoreLiveRegisters(locs); | |
| 2114 | |
| 2115 __ b(exit_label()); | |
| 2116 } | |
| 2117 | |
| 2118 private: | |
| 2119 Instruction* instruction_; | |
| 2120 }; | |
| 2121 | |
| 2122 | |
| 2123 LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, | 2110 LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, |
| 2124 bool opt) const { | 2111 bool opt) const { |
| 2125 const intptr_t kNumInputs = 1; | 2112 const intptr_t kNumInputs = 1; |
| 2126 const intptr_t kNumTemps = | 2113 const intptr_t kNumTemps = |
| 2127 (IsUnboxedLoad() && opt) ? 1 : | 2114 (IsUnboxedLoad() && opt) ? 1 : |
| 2128 ((IsPotentialUnboxedLoad()) ? 2 : 0); | 2115 ((IsPotentialUnboxedLoad()) ? 2 : 0); |
| 2129 LocationSummary* locs = new(isolate) LocationSummary( | 2116 LocationSummary* locs = new(isolate) LocationSummary( |
| 2130 isolate, kNumInputs, kNumTemps, | 2117 isolate, kNumInputs, kNumTemps, |
| 2131 (opt && !IsPotentialUnboxedLoad()) | 2118 (opt && !IsPotentialUnboxedLoad()) |
| 2132 ? LocationSummary::kNoCall | 2119 ? LocationSummary::kNoCall |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2187 | 2174 |
| 2188 // Fall through. | 2175 // Fall through. |
| 2189 __ b(&load_pointer); | 2176 __ b(&load_pointer); |
| 2190 | 2177 |
| 2191 if (!compiler->is_optimizing()) { | 2178 if (!compiler->is_optimizing()) { |
| 2192 locs()->live_registers()->Add(locs()->in(0)); | 2179 locs()->live_registers()->Add(locs()->in(0)); |
| 2193 } | 2180 } |
| 2194 | 2181 |
| 2195 { | 2182 { |
| 2196 __ Bind(&load_double); | 2183 __ Bind(&load_double); |
| 2197 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2184 BoxAllocationSlowPath::Allocate( |
| 2198 compiler->AddSlowPathCode(slow_path); | 2185 compiler, this, compiler->double_class(), result_reg, temp); |
| 2199 | |
| 2200 __ TryAllocate(compiler->double_class(), | |
| 2201 slow_path->entry_label(), | |
| 2202 result_reg, | |
| 2203 temp); | |
| 2204 __ Bind(slow_path->exit_label()); | |
| 2205 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2186 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2206 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); | 2187 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 2207 __ StoreDToOffset(value, | 2188 __ StoreDToOffset(value, |
| 2208 result_reg, | 2189 result_reg, |
| 2209 Double::value_offset() - kHeapObjectTag); | 2190 Double::value_offset() - kHeapObjectTag); |
| 2210 __ b(&done); | 2191 __ b(&done); |
| 2211 } | 2192 } |
| 2212 | 2193 |
| 2213 __ Bind(&load_pointer); | 2194 __ Bind(&load_pointer); |
| 2214 } | 2195 } |
| (...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3039 kNumTemps, | 3020 kNumTemps, |
| 3040 LocationSummary::kCallOnSlowPath); | 3021 LocationSummary::kCallOnSlowPath); |
| 3041 summary->set_in(0, Location::RequiresFpuRegister()); | 3022 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3042 summary->set_temp(0, Location::RequiresRegister()); | 3023 summary->set_temp(0, Location::RequiresRegister()); |
| 3043 summary->set_out(0, Location::RequiresRegister()); | 3024 summary->set_out(0, Location::RequiresRegister()); |
| 3044 return summary; | 3025 return summary; |
| 3045 } | 3026 } |
| 3046 | 3027 |
| 3047 | 3028 |
| 3048 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3029 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3049 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | |
| 3050 compiler->AddSlowPathCode(slow_path); | |
| 3051 | |
| 3052 Register out_reg = locs()->out(0).reg(); | 3030 Register out_reg = locs()->out(0).reg(); |
| 3053 DRegister value = locs()->in(0).fpu_reg(); | 3031 DRegister value = locs()->in(0).fpu_reg(); |
| 3054 | 3032 |
| 3055 __ TryAllocate(compiler->double_class(), | 3033 BoxAllocationSlowPath::Allocate( |
| 3056 slow_path->entry_label(), | 3034 compiler, this, compiler->double_class(), out_reg, locs()->temp(0).reg()); |
| 3057 out_reg, | |
| 3058 locs()->temp(0).reg()); | |
| 3059 __ Bind(slow_path->exit_label()); | |
| 3060 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 3035 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); |
| 3061 } | 3036 } |
| 3062 | 3037 |
| 3063 | 3038 |
| 3064 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3039 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, |
| 3065 bool opt) const { | 3040 bool opt) const { |
| 3066 const intptr_t kNumInputs = 1; | 3041 const intptr_t kNumInputs = 1; |
| 3067 const intptr_t kNumTemps = 0; | 3042 const intptr_t kNumTemps = 0; |
| 3068 LocationSummary* summary = new(isolate) LocationSummary( | 3043 LocationSummary* summary = new(isolate) LocationSummary( |
| 3069 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3044 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| (...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4805 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 4780 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 4806 #if defined(DEBUG) | 4781 #if defined(DEBUG) |
| 4807 __ LoadImmediate(S4, kInvalidObjectPointer); | 4782 __ LoadImmediate(S4, kInvalidObjectPointer); |
| 4808 __ LoadImmediate(S5, kInvalidObjectPointer); | 4783 __ LoadImmediate(S5, kInvalidObjectPointer); |
| 4809 #endif | 4784 #endif |
| 4810 } | 4785 } |
| 4811 | 4786 |
| 4812 } // namespace dart | 4787 } // namespace dart |
| 4813 | 4788 |
| 4814 #endif // defined TARGET_ARCH_MIPS | 4789 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |